-
-
Notifications
You must be signed in to change notification settings - Fork 486
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
Buffered deserialisation #774
Conversation
Love this; let me know if you want some help to finish it off. I'd say that the resolver you didn't implement is equally useful and is probably worth adding. I found it more common that yaml files did not include a discriminator key. Or if you don't agree, I think it would be better to provide a configuration option method to add a custom ITypeDiscriminator so others can extend as they like. |
This is great! I've seen a few questions/issues related to this. It'll be nice to have it built in. A few things I see right off the top that would be great to have addressed
For the tests, add them to the tests project. It runs them against net47, net 3.1 (for netstandard2.0), net6.0 and net7.0. |
Thanks both, good to know there is appetite for this! 😊 I'll work on the things mentioned and let you know when its ready for a closer look (: |
Okay, I think I have addressed what I consider "design" changes at this point. Still have comments & tests to do though (:
|
Actually the BaseType = object scenario is more complex than I previously thought - won't get to it today but will keep thinking (: |
Okay, I have reworked things such that BaseType = object is now supported (see tests). In order to accomplish this, I have made the |
I can't think of a better solution without changing the signature for public interface INodeDeserializer
{
bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object?> nestedObjectDeserializer, out object? value);
} The only output of each This is why the BufferedNodeDeserializer needs to wrap all other INodeDeserializers. However all the others also need to exist outside of the BufferedNodeDeserializer for cases when buffering isn't needed/desired. I don't like the duplication of all of the INodeDeserializers but I think it is a trade off between that and more significantly impacting the existing codebase/functionality/user expectations. Does anyone have any ideas for a more elegant solution? 😂 |
701c014
to
f3cfec5
Compare
Hey @EdwardCooke, just a ping that this is ready for review (: |
Great! I’ll look at it in greater detail when I get some time. Most likely this weekend. |
YamlDotNet/Serialization/BufferedDeserialization/ParserBuffer.cs
Outdated
Show resolved
Hide resolved
YamlDotNet/Serialization/BufferedDeserialization/TypeDiscriminators/IValueTypeDiscriminator.cs
Show resolved
Hide resolved
...DotNet/Serialization/BufferedDeserialization/TypeDiscriminators/KeyValueTypeDiscriminator.cs
Outdated
Show resolved
Hide resolved
...DotNet/Serialization/BufferedDeserialization/TypeDiscriminators/KeyValueTypeDiscriminator.cs
Show resolved
Hide resolved
...DotNet/Serialization/BufferedDeserialization/TypeDiscriminators/KeyValueTypeDiscriminator.cs
Outdated
Show resolved
Hide resolved
...DotNet/Serialization/BufferedDeserialization/TypeDiscriminators/KeyValueTypeDiscriminator.cs
Outdated
Show resolved
Hide resolved
...otNet/Serialization/BufferedDeserialization/TypeDiscriminators/UniqueKeyTypeDiscriminator.cs
Outdated
Show resolved
Hide resolved
...DotNet/Serialization/BufferedDeserialization/TypeDiscriminators/KeyValueTypeDiscriminator.cs
Outdated
Show resolved
Hide resolved
Thanks for the review @EdwardCooke! Will aim to get back to this over the coming week 😊 |
I think I've addressed everything @EdwardCooke! 😊 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fantastic!
A few notes:
- Your tests don't cover a fall through case (i.e. two registrations of
AddKeyValueTypeDiscriminator
orAddUniqueKeyTypeDiscriminator
) but the code seems to support it. I.e. would this work:
var bufferedDeserializer = new DeserializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.WithBufferedNodeDeserializer(options => {
options.AddKeyValueTypeDiscriminator<KubernetesResource>(
"kind",
new Dictionary<string, Type>()
{
{ "Namespace", typeof(KubernetesNamespace) },
})
.AddKeyValueTypeDiscriminator<KubernetesResource>(
"kind",
new Dictionary<string, Type>()
{
{ "Service", typeof(KubernetesService) }
});
},
maxDepth: 3,
maxLength: 40)
.Build();
- The name
BufferedNodeDeserializer
is probably one I would change (I know I chose the name originally, my bad) since it doesn't describe what it's doing but rather how - and how is unimportant. Suggestion:TypeDiscriminatingNodeDeserializer
.
I'm so hyped you did the work for this. There's no way I would have had the capacity, so thank you!
YamlDotNet/Serialization/BufferedDeserialization/BufferedNodeDeserializer.cs
Outdated
Show resolved
Hide resolved
Thanks @atruskie! Have made those changes (: |
YamlDotNet/Serialization/BufferedDeserialization/TypeDiscriminatingNodeDeserializer.cs
Show resolved
Hide resolved
...otNet/Serialization/BufferedDeserialization/TypeDiscriminators/UniqueKeyTypeDiscriminator.cs
Show resolved
Hide resolved
YamlDotNet.Test/Serialization/BufferedDeserialization/KeyValueTypeDiscriminatorTests.cs
Show resolved
Hide resolved
...DotNet.Test/Serialization/BufferedDeserialization/TypeDiscriminatingNodeDeserializerTests.cs
Show resolved
Hide resolved
YamlDotNet.Test/Serialization/BufferedDeserialization/UniqueKeyTypeDiscriminatorTests.cs
Show resolved
Hide resolved
YamlDotNet/Serialization/BufferedDeserialization/ITypeDiscriminatingNodeDeserializerOptions.cs
Show resolved
Hide resolved
YamlDotNet/Serialization/BufferedDeserialization/TypeDiscriminatingNodeDeserializerOptions.cs
Show resolved
Hide resolved
YamlDotNet/Serialization/BufferedDeserialization/TypeDiscriminators/IValueTypeDiscriminator.cs
Show resolved
Hide resolved
...DotNet/Serialization/BufferedDeserialization/TypeDiscriminators/KeyValueTypeDiscriminator.cs
Show resolved
Hide resolved
YamlDotNet/Serialization/BufferedDeserialization/TypeDiscriminatingNodeDeserializer.cs
Outdated
Show resolved
Hide resolved
YamlDotNet/Serialization/BufferedDeserialization/TypeDiscriminatingNodeDeserializer.cs
Outdated
Show resolved
Hide resolved
Once the latest comments are fixed we should be good to merge this in. |
All done @EdwardCooke! (: |
I’ll merge this in when I get time, should be this week. |
Hi! When it will be available as nuget package? |
This feature has been released in version 13.1.0. |
I have just pulled down the 13.1.0 release and tried using this, but the lack of documentation is killing me.
Don't get me wrong, I'm not here just to complain. Just pointing out something that I think will make it difficult for users to adopt this new feature. I'm sure if I swim into the unit tests I'll eventually figure it out, but hours are pretty valuable these days... In any case, I appreciate the months you folks spent on getting this ready. |
Thanks for the feedback, I'll work on building out some documentation in the wiki, I know this particular feature was a bit complex in nature. I'll also work on getting those missing XML comments on the interface. |
Here's a little wiki page documenting how to use this new feature https://github.com/aaubry/YamlDotNet/wiki/Deserialization---Type-Discrimators |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- [ ]
For future visitors, this is the correct link: https://github.com/aaubry/YamlDotNet/wiki/Deserialization---Type-Discriminators Thanks again for the examples! |
Hello!
This is a draft PR to add support for deserialising yaml into different types, depending on values found during deserialisation. Specifically, it addresses scenarios mentioned in: #36 #343, #605, #731.
The foundational code included in this PR was written by @atruskie in a gist available here. I am opening this PR with their permission.
Notably, this PR only includes a subset of the functionality, specifically the ability to discern type by looking for a key that has the desired type encoded in its value. This PR does not include the functionality to discern type by looking at the presence of unique keys. It does lay the foundation to bring in this additional functionality in the future if desired.
My use case is very similar to the kubernetes use case (where there is a "kind" key), and this PR should satisfy the kubernetes use case.
In addition to less functionality, I have also:
Here is an example of usage:
I wanted to put this up and gauge interest before working on this more, but the remaining things I know I need to do before merging:
Some other things that could be done in this or future PRs:
It is also worth mentioning @EdwardCooke that this also works with the AOT branch we've been testing, it just needs a similar helper method on the
StaticDeserializerBuilder
as that file is not in the codebase yet.Let me know if this is desired and I'll keep working on it, and thanks for maintaining this library (: