Kursach_StealthAction/Assets/Tremble/Utils/NamingConventionUtil.cs
2026-10-11 19:16:11 +03:00

157 lines
3.9 KiB
C#

//
// This file is part of the Tremble package by Tiny Goose.
// Copyright (c) 2024-2026 TinyGoose Ltd., All Rights Reserved.
//
using System;
using System.Text;
namespace TinyGoose.Tremble
{
public static class NamingConventionUtil
{
public static string ToNamingConvention(this string input, NamingConvention convention)
{
switch (convention)
{
case NamingConvention.SnakeCase:
return input.ToSnakeCase();
case NamingConvention.UpperCamelCase:
return CapitaliseFirstLetter(input, true);
case NamingConvention.LowerCamelCase:
return CapitaliseFirstLetter(input, false);
case NamingConvention.HumanFriendly:
return ToHuman(input);
case NamingConvention.PreserveExact:
return input;
}
return input;
}
private static readonly StringBuilder s_SnakeBuilder = new(128);
private static string ToSnakeCase(this string inString)
{
s_SnakeBuilder.Clear();
for (int i = 0; i < inString.Length; i++)
{
if (inString[i] == ' ')
{
s_SnakeBuilder.Append('_');
continue;
}
if (Char.IsUpper(inString[i]) && i > 0)
{
// Not if we just output an underscore!
if (s_SnakeBuilder[^1] != '_')
{
// If the previous character wasn't uppercase
if (!Char.IsUpper(inString[i - 1]))
{
s_SnakeBuilder.Append('_');
}
// Or the next character isn't uppercase
else if (i < inString.Length - 1 && Char.IsLower(inString[i + 1]))
{
s_SnakeBuilder.Append('_');
}
}
}
s_SnakeBuilder.Append(Char.ToLowerInvariant(inString[i]));
}
return s_SnakeBuilder.ToString();
}
private static string ToHuman(this string inString)
{
s_SnakeBuilder.Clear();
int firstIndex = inString.IndexOf('_') + 1;
for (int i = firstIndex; i < inString.Length; i++)
{
// Straight up convert underscores to spaces
if (inString[i] == '_')
{
s_SnakeBuilder.Append(' ');
continue;
}
if (Char.IsUpper(inString[i]) && i > firstIndex)
{
// Not if we just output a space!
if (s_SnakeBuilder[^1] != ' ' && s_SnakeBuilder[^1] != '_')
{
// If the previous character wasn't uppercase
if (!Char.IsUpper(inString[i - 1]))
{
s_SnakeBuilder.Append(' ');
}
// Or the next character isn't uppercase
else if (i < inString.Length - 1 && Char.IsLower(inString[i + 1]))
{
s_SnakeBuilder.Append(' ');
}
}
}
if (i == firstIndex || s_SnakeBuilder[^1] == ' ')
{
s_SnakeBuilder.Append(Char.ToUpperInvariant(inString[i]));
}
else
{
s_SnakeBuilder.Append(Char.ToLowerInvariant(inString[i]));
}
}
return s_SnakeBuilder.ToString();
}
public static string FromHuman(ReadOnlySpan<char> inString)
{
s_SnakeBuilder.Clear();
int inBrackets = 0;
for (int i = 0; i < inString.Length; i++)
{
if (inString[i] == '(') { inBrackets++; continue; }
if (inString[i] == ')') { inBrackets--; continue; }
if (!Char.IsLetter(inString[i]) && !Char.IsNumber(inString[i]) && inString[i] != '_')
continue;
if (inBrackets > 0)
continue;
if (i == 0 || inString[i - 1] == ' ')
{
s_SnakeBuilder.Append(Char.ToUpperInvariant(inString[i]));
}
else
{
s_SnakeBuilder.Append(inString[i]);
}
}
return s_SnakeBuilder.ToString().Trim();
}
public static string FromHuman(string inString) => FromHuman(inString.AsSpan());
private static string CapitaliseFirstLetter(string input, bool capitalise)
{
if (input.IsNullOrEmpty())
return "";
if (input.Length == 1)
return capitalise ? input.ToUpperInvariant() : input.ToLowerInvariant();
return (capitalise ? Char.ToUpperInvariant(input[0]) : Char.ToLowerInvariant(input[0]))
+ input.Substring(1);
}
}
}