Files
EFCore.NamingConventions/EFCore.NamingConventions/NamingConventions/Internal/SnakeCaseNameRewriter.cs
2020-09-14 17:29:47 +03:00

76 lines
2.5 KiB
C#

using System;
using System.Globalization;
using System.Text;
namespace EFCore.NamingConventions.Internal
{
public class SnakeCaseNameRewriter : INameRewriter
{
private readonly CultureInfo _culture;
public SnakeCaseNameRewriter(CultureInfo culture) => _culture = culture;
public virtual string RewriteName(string name)
{
if (string.IsNullOrEmpty(name))
{
return name;
}
var builder = new StringBuilder(name.Length + Math.Min(2, name.Length / 5));
var previousCategory = default(UnicodeCategory?);
for (var currentIndex = 0; currentIndex < name.Length; currentIndex++)
{
var currentChar = name[currentIndex];
if (currentChar == '_')
{
builder.Append('_');
previousCategory = null;
continue;
}
var currentCategory = char.GetUnicodeCategory(currentChar);
switch (currentCategory)
{
case UnicodeCategory.UppercaseLetter:
case UnicodeCategory.TitlecaseLetter:
if (previousCategory == UnicodeCategory.SpaceSeparator ||
previousCategory == UnicodeCategory.LowercaseLetter ||
previousCategory != UnicodeCategory.DecimalDigitNumber &&
previousCategory != null &&
currentIndex > 0 &&
currentIndex + 1 < name.Length &&
char.IsLower(name[currentIndex + 1]))
{
builder.Append('_');
}
currentChar = char.ToLower(currentChar, _culture);
break;
case UnicodeCategory.LowercaseLetter:
case UnicodeCategory.DecimalDigitNumber:
if (previousCategory == UnicodeCategory.SpaceSeparator)
{
builder.Append('_');
}
break;
default:
if (previousCategory != null)
{
previousCategory = UnicodeCategory.SpaceSeparator;
}
continue;
}
builder.Append(currentChar);
previousCategory = currentCategory;
}
return builder.ToString();
}
}
}