Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add default scalar style #827

Merged
merged 14 commits into from
Aug 14, 2023
Merged

Conversation

tymokvo
Copy link
Contributor

@tymokvo tymokvo commented Jul 17, 2023

Summary

Re: #714 , it is sometimes desirable to force a quotation style on all strings in a YAML document. For example, when some strings contain valid numeric literals.

This implements the suggested change from that issue by exposing the "default scalar style" as a constructor argument. Previously, this value was hard-coded to ScalarStyle.Any as the local value suggestedStyle.

Changes

  • YamlDotNet/Serialization
    • Add defaultScalarStyle = ScalarStyle.Any to TypeAssigningEventEmitter
    • Add SerializerBuilder.WithDefaultScalarStyle
      • I wasn't sure of the best way to create the TypeAssigningEventEmitter, so I copied the instantiation from the constructor and used loc.InsteadOf<_> to replace it.
      • I'm not sure how necessary it is, but here it would have been a bit more ergonomic to have an instance member on the SerializerBuilder to construct its TypeAssigningEventEmitter
  • YamlDotNet.Test
    • Add SerializationRespectsDefaultScalarStyle
      • This is only testing SingleQuote. I can add others if necessary.
    • Add MixedFormatScalarStyleExample to helpers

To Do

  • Add StaticSerializerBuilder.WithDefaultScalarStyle
  • Use literal strings in test case
  • Increase newline consistency quotient
  • Add new constructors instead of changing signatures

Fix #714

@tymokvo
Copy link
Contributor Author

tymokvo commented Jul 17, 2023

Hm, I don't know enough about CI here to fix the failure. Seems like an upload failed?

Error uploading artifact to the storage: Remote server returned 500: Internal Server Error

@EdwardCooke
Copy link
Collaborator

The issue with the failed build is most likely appveyor.

Can you add the same with method to the staticserializerbuilder as well? Also, in your tests can you use literal strings instead of putting \r\n in them like the other tests.

I’ll take a closer look later today but this looks like a good solution so far.

: this(nextEmitter, requireTagWhenStaticAndActualTypesAreDifferent, tagMappings)
private readonly ScalarStyle defaultScalarStyle;

public TypeAssigningEventEmitter(IEventEmitter nextEmitter, bool requireTagWhenStaticAndActualTypesAreDifferent, IDictionary<Type, TagName> tagMappings, bool quoteNecessaryStrings, bool quoteYaml1_1Strings, ScalarStyle defaultScalarStyle = ScalarStyle.Any)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing a constructor signature is considered a breaking change. Can you create this as a new constructor with this parameter?

The breaking change with this would be if, for whatever reason, someone was using reflection to get the constructor. You would just need to add an additional one, and not change any of the others.

public class MixedFormatScalarStyleExample
{
public string[] Data { get; }
public MixedFormatScalarStyleExample(string[] data)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it's nit picky, especially in a test class, but can you add an empty line between the property and the method? That's the general standard throughout this library.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added!

Comment on lines +70 to +81
public TypeAssigningEventEmitter(IEventEmitter nextEmitter, bool requireTagWhenStaticAndActualTypesAreDifferent, IDictionary<Type, TagName> tagMappings, bool quoteNecessaryStrings, bool quoteYaml1_1Strings, ScalarStyle defaultScalarStyle)
: this(nextEmitter, requireTagWhenStaticAndActualTypesAreDifferent, tagMappings, quoteNecessaryStrings, quoteYaml1_1Strings)
{
this.defaultScalarStyle = defaultScalarStyle;
}

public TypeAssigningEventEmitter(IEventEmitter nextEmitter, bool requireTagWhenStaticAndActualTypesAreDifferent, IDictionary<Type, TagName> tagMappings, bool quoteNecessaryStrings, ScalarStyle defaultScalarStyle)
: this(nextEmitter, requireTagWhenStaticAndActualTypesAreDifferent, tagMappings, quoteNecessaryStrings)
{
this.defaultScalarStyle = defaultScalarStyle;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ended up adding 2 constructors since SerializerBuilder and StaticSerializerBuilder rely on 2 different existing constructors. Is that the right approach here?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good enough :)

@tymokvo tymokvo requested a review from EdwardCooke August 11, 2023 18:48
Copy link
Collaborator

@EdwardCooke EdwardCooke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

@EdwardCooke EdwardCooke merged commit 20f17c7 into aaubry:master Aug 14, 2023
@aaubry
Copy link
Owner

aaubry commented Aug 14, 2023

This feature has been released in version 13.2.0.

@daniol
Copy link

daniol commented Mar 1, 2024

This quotes everything, also keys, not only values. Hence this is not what was requested in #714 or #315.

@EdwardCooke
Copy link
Collaborator

Are you looking for something different? There's 2 methods you can call on the serializer builder that will help control whether a value/key (both are just scalars in yaml) should be quoted or not.

  • One is the default scalar style, where you can always quote every string regardless of the value.
  • The quote necessary strings will put quotes around strings that are numbers and booleans and a few other values that would generally be misinterpreted by other deserializers, Kubernetes being the big one with true/false and numbers. That seems to be the biggest use case from what I've seen, which if I recall, even in their .net client (which uses yamldotnet) they do call with quote necessary strings when they build the serializer.
    Those 2 methods satisfy those 2 issues that you mentioned. This PR was in regards to 714, not 315, which was handled in the quotenecessarystrings Option to quote YAML 1.1 strings #767.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Wrap all string values in quotes when serializing, if possible
4 participants