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

Consider consolidating logic of JSON Snake/Kebab naming with Camel #77262

Closed
krwq opened this issue Oct 20, 2022 · 9 comments
Closed

Consider consolidating logic of JSON Snake/Kebab naming with Camel #77262

krwq opened this issue Oct 20, 2022 · 9 comments

Comments

@krwq
Copy link
Member

krwq commented Oct 20, 2022

In #69613 we've added Snake/Kebab casing but it uses slightly different word splitting logic. We should decide which we prefer and consider consolidating the code.

cc: @YohDeadfall

@ghost
Copy link

ghost commented Oct 20, 2022

Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis
See info in area-owners.md if you want to be subscribed.

Issue Details

In #69613 we've added Snake/Kebab casing but it uses slightly different word splitting logic. We should decide which we prefer and consider consolidating the code.

Author: krwq
Assignees: -
Labels:

area-System.Text.Json

Milestone: -

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Oct 20, 2022
@YohDeadfall
Copy link
Contributor

If it gets approved, please assign it on me. I already know how to fix it policies which are merged initially were made taking an approach allowing customization of word transform and the separator.

@eiriktsarpalis
Copy link
Member

eiriktsarpalis commented Oct 20, 2022

camelCase conversion doesn't require splitting tokens -- it simply converts the first group of uppercase characters to lowercase on a fixed-length string:

private static void FixCasing(Span<char> chars)
{
for (int i = 0; i < chars.Length; i++)
{
if (i == 1 && !char.IsUpper(chars[i]))
{
break;
}
bool hasNext = (i + 1 < chars.Length);
// Stop when next char is already lowercase.
if (i > 0 && hasNext && !char.IsUpper(chars[i + 1]))
{
// If the next char is a space, lowercase current char before exiting.
if (chars[i + 1] == ' ')
{
chars[i] = char.ToLowerInvariant(chars[i]);
}
break;
}
chars[i] = char.ToLowerInvariant(chars[i]);
}
}

Consolidating the logic would introduce complexity where it shouldn't exist. Why would we want to do this?

@YohDeadfall
Copy link
Contributor

type ``Lemme break your code :trollface:``() =
    member _.M() = ()

@eiriktsarpalis
Copy link
Member

As of .NET 7, the CamelCase policy has the following behavior:

> JsonNamingPolicy.CamelCase.ConvertName <| nameof ``Lemme break your code :trollface:`` ;;
val it: string = "lemme break your code :trollface:"

and changing that would be a breaking change.

@YohDeadfall
Copy link
Contributor

Without jokes, in my previous attempt of making naming policies I analyzed implementation in other libraries and platforms. Anywhere else policies are implemented exactly as @krwq wrote, i.e., split an input into words, transform them using some logic and concatenate them. When I asked you about ITransform interface the idea was about expanding the taken approach to the camel case too. The only change the base class will get is a generic argument to which you pass a struct implementing the interface. A single method of it shall be called instead of ToLowerInvariant/ToUpperInvariant, and that method will do all the transformation logic and adding a separator if needed.

As I noticed you in the PR, most likely it won't pass "it's written in stone" rule, but let's think that it won't affect too many users and with each release there are breaking changes already (:

@eiriktsarpalis
Copy link
Member

eiriktsarpalis commented Oct 20, 2022

As I noticed you in the PR, most likely it won't pass "it's written in stone" rule, but let's think that it won't affect too many users and with each release there are breaking changes already (:

We don't do this out of spite :-) Unlike libraries shipped in NuGet which can be governed by things like SemVer, STJ is (also) part of the .NET shared framework; as such any regression/breaking change could have the potential to prevent entire teams from migrating to the next version of .NET. Accidental breaking changes will always be serviced, and the bar for introducing intentional breaking changes is very high (and pretty involved from a paperwork perspective).

I may or may not agree with the current implementation of JsonNamingPolicy.CamelCase, however the case for changing it doesn't seem particularly strong to me -- the underlying JsonNamingPolicy abstraction is available for users/library authors to implement as they please.

let's think that it won't affect too many users

This needs to be backed by evidence. For users that are affected the problem will manifest silently, as in the serializer would end up writing data using a different JSON schema.

@krwq
Copy link
Member Author

krwq commented Oct 20, 2022

@YohDeadfall I'd suggest compiling a list of differences in behavior (i.e. table with examples). If we were to make this change we'd possibly introduce compat switch. We'll likely need more upvotes on this issue to proceed though

@YohDeadfall
Copy link
Contributor

Hard to point to any exact place in the original PR since there was a discussion about rules, so you have to check at least a half of dotnet/corefx#41354. Some links are provided by a @ahsonkhan in dotnet/corefx#41354 (comment). For my package and merged changes, I also checked Rust libraries, especially heck.

To conclude, usually name transformers use the same method under the hood to parse an input string and then work on extracted words using rule specific to each policy like lower casing and an underscore as separator. I say usually because I have faced no library which does policies differently, but it might exist since I checked popular only.

@eiriktsarpalis eiriktsarpalis removed the untriaged New issue has not been triaged by the area owner label Oct 26, 2022
@eiriktsarpalis eiriktsarpalis added this to the Future milestone Oct 26, 2022
@eiriktsarpalis eiriktsarpalis closed this as not planned Won't fix, can't repro, duplicate, stale Nov 22, 2023
@github-actions github-actions bot locked and limited conversation to collaborators Dec 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants