Skip to content

Instantly share code, notes, and snippets.

@amilos
Created October 9, 2017 16:56
Show Gist options
  • Save amilos/9ec30c60bc50b40bf0cfabb8fdec4966 to your computer and use it in GitHub Desktop.
Save amilos/9ec30c60bc50b40bf0cfabb8fdec4966 to your computer and use it in GitHub Desktop.
Kebab case naming strategy extension for Newtonsoft.JSON library
using System.Text;
using Newtonsoft.Json.Serialization;
namespace Asseco.JsonUtils
{
// Adapted from SnakeCaseNamingStrategy from Newtonsoft.Json library
public class KebabCaseNamingStrategy : NamingStrategy
{
const char HYPHEN = '-';
const char UNDERSCORE = '_';
public KebabCaseNamingStrategy(bool processDictionaryKeys, bool overrideSpecifiedNames)
{
ProcessDictionaryKeys = processDictionaryKeys;
OverrideSpecifiedNames = overrideSpecifiedNames;
}
public KebabCaseNamingStrategy(bool processDictionaryKeys, bool overrideSpecifiedNames, bool processExtensionDataNames)
: this(processDictionaryKeys, overrideSpecifiedNames)
{
ProcessExtensionDataNames = processExtensionDataNames;
}
public KebabCaseNamingStrategy()
{
}
protected override string ResolvePropertyName(string name)
{
return ToKebabCase(name);
}
internal enum KebabCaseState
{
Start,
Lower,
Upper,
NewWord
}
internal string ToKebabCase(string s)
{
if (string.IsNullOrEmpty(s))
{
return s;
}
StringBuilder sb = new StringBuilder();
KebabCaseState state = KebabCaseState.Start;
for (int i = 0; i < s.Length; i++)
{
if (s[i] == ' ')
{
if (state != KebabCaseState.Start)
{
state = KebabCaseState.NewWord;
}
}
else if (char.IsUpper(s[i]))
{
switch (state)
{
case KebabCaseState.Upper:
bool hasNext = (i + 1 < s.Length);
if (i > 0 && hasNext)
{
char nextChar = s[i + 1];
if (!char.IsUpper(nextChar) && nextChar != UNDERSCORE && nextChar != HYPHEN)
{
sb.Append(HYPHEN);
}
}
break;
case KebabCaseState.Lower:
case KebabCaseState.NewWord:
sb.Append(HYPHEN);
break;
}
char c;
c = char.ToLowerInvariant(s[i]);
sb.Append(c);
state = KebabCaseState.Upper;
}
else if (s[i] == UNDERSCORE || s[i] == HYPHEN)
{
sb.Append(HYPHEN);
state = KebabCaseState.Start;
}
else
{
if (state == KebabCaseState.NewWord)
{
sb.Append(HYPHEN);
}
sb.Append(s[i]);
state = KebabCaseState.Lower;
}
}
return sb.ToString();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment