Skip to content

Instantly share code, notes, and snippets.

@01Vladimir10
Created May 10, 2023 22:31
Show Gist options
  • Save 01Vladimir10/70c679937d4c77792cd814894caf06a0 to your computer and use it in GitHub Desktop.
Save 01Vladimir10/70c679937d4c77792cd814894caf06a0 to your computer and use it in GitHub Desktop.
An implementation of JsonNamingPolicy for snake case, this is completly compatible with Json.NET
namespace ZuperApi.ZohoIntegration.Utils;
public class JsonSnakeCaseNamingPolicy : System.Text.Json.JsonNamingPolicy
{
public override string ConvertName(string name) => ToSeparatedCase(name, '_');
private enum SeparatedCaseState
{
Start,
Lower,
Upper,
NewWord
}
private static string ToSeparatedCase(string s, char separator)
{
if (string.IsNullOrEmpty(s))
{
return s;
}
var sb = new System.Text.StringBuilder();
var state = SeparatedCaseState.Start;
for (var i = 0; i < s.Length; i++)
{
if (s[i] == ' ')
{
if (state != SeparatedCaseState.Start)
{
state = SeparatedCaseState.NewWord;
}
}
else if (char.IsUpper(s[i]))
{
switch (state)
{
case SeparatedCaseState.Upper:
var hasNext = i + 1 < s.Length;
if (i > 0 && hasNext)
{
var nextChar = s[i + 1];
if (!char.IsUpper(nextChar) && nextChar != separator)
{
sb.Append(separator);
}
}
break;
case SeparatedCaseState.Lower:
case SeparatedCaseState.NewWord:
sb.Append(separator);
break;
case SeparatedCaseState.Start:
break;
default:
throw new InvalidOperationException();
}
var c = char.ToLowerInvariant(s[i]);
sb.Append(c);
state = SeparatedCaseState.Upper;
}
else if (s[i] == separator)
{
sb.Append(separator);
state = SeparatedCaseState.Start;
}
else
{
if (state == SeparatedCaseState.NewWord)
{
sb.Append(separator);
}
sb.Append(s[i]);
state = SeparatedCaseState.Lower;
}
}
return sb.ToString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment