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

Allow applying naming policy to properties #44

Open
AArnott opened this issue Nov 7, 2024 · 6 comments
Open

Allow applying naming policy to properties #44

AArnott opened this issue Nov 7, 2024 · 6 comments
Milestone

Comments

@AArnott
Copy link
Contributor

AArnott commented Nov 7, 2024

From this conversation @eiriktsarpalis said:

I'm thinking that the concept of applying a naming policy is something that transfers to shapes in general, so perhaps it makes sense to lift that to being a feature in the core library.

I was thinking the same thing.

@AArnott
Copy link
Contributor Author

AArnott commented Nov 9, 2024

Once you have naming policy support, it would be great PolyType could offer a map of properties and constructor parameters, or (even simpler) the properties themselves should have something more than HasSetter that would indicate whether the constructor allows indirectly setting the property.

The reason for this is that I don't want a serializer to include serialization of a property that has only a getter and no constructor parameter either.

@eiriktsarpalis
Copy link
Owner

eiriktsarpalis commented Nov 10, 2024

it would be great PolyType could offer a map of properties and constructor parameters, or (even simpler) the properties themselves should have something more than HasSetter that would indicate whether the constructor allows indirectly setting the property.

The parameters of constructor shapes already includes settable members modulo those matching constructor parameters.

Beyond that though, the library doesn't try to explicitly pair properties to parameters or fail if no match is found. System.Text.Json does do this fairly aggressively and we've received feedback from users that this is undesirable in scenaria where you only care about serialization or deserialization but not about being able to roundtrip values. This feels like a policy that can be enforced by individual consumers.

@AArnott
Copy link
Contributor Author

AArnott commented Nov 10, 2024

Beyond that though, the library doesn't try to explicitly pair properties to parameters or fail if no match is found.

Let's put the "fail if not match is found" or skipping serialization on no match aside for a moment.

I still have to (at present) write the code to match a serialized property name to a constructor parameter. This is a pain, and requires that I decide the policy for how user's constructor parameter names must match the property name. Consider this case:

class Foo
{
   public Foo(int a);

   public int A { get; }
}

By default, this might serialize to JSON like this:

{ "A": 5 }

Now, upon _de_serialization, how should the deserializer decide what to do with the JSON A property? It doesn't match the a constructor parameter. So should it drop it, or should it decide based on a camelCase/PascalCase match, or should it be totally case-insensitive?

From a PolyType perspective, we have an opportunity perhaps to unify how serializers work including potentially some of their policies. Personally, for a fresh MessagePack library such as the one I'm building, I'd rather not have to decide this policy and rely on a common framework like PolyType to define it, so that users can define their types once with PolyType conformance, and then switch from serializing to JSON to MsgPack to Cbor -- and have it all Just Work instead of one of those formats failing because they don't know that property A should be matched with ctor parameter a.

@eiriktsarpalis
Copy link
Owner

eiriktsarpalis commented Nov 10, 2024

Now, upon _de_serialization, how should the deserializer decide what to do with the JSON A property? It doesn't match the a constructor parameter. So should it drop it, or should it decide based on a camelCase/PascalCase match, or should it be totally case-insensitive?

These are all valid options. I don't believe this association should be the purview of shapes but a matter of policy in individual serializers. We can of course choose to expose helpers that implement either of these policies in a streamlined fashion.

@eiriktsarpalis
Copy link
Owner

I'd rather not have to decide this policy and rely on a common framework like PolyType to define it, so that users can define their types once with PolyType conformance, and then switch from serializing to JSON to MsgPack to Cbor

I agree that this would be a desirable goal. At some point we could consider implementing something like Serde.NET on top of PolyType using a common set of conventions. Adding support for a new format would be as simple as implementing a pair of reader/writer classes.

@AArnott
Copy link
Contributor Author

AArnott commented Nov 16, 2024

Another use case for consistent mapping from constructor parameters to properties: AArnott/Nerdbank.MessagePack#89 needs to decide which property is impacted by the default value as specified as a default parameter value in a primary constructor so that we can decide whether to serialize that property.

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

No branches or pull requests

2 participants