Skip to content

Commit

Permalink
feat: add to kebab case string ext
Browse files Browse the repository at this point in the history
  • Loading branch information
elringus committed Oct 6, 2024
1 parent 2694903 commit 9195ba9
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
28 changes: 28 additions & 0 deletions backend/Naninovel.Common.Modern/Utilities/TextUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,32 @@ public static string ToPascalCase (this string str)
bool Upper () => length == 1 || !char.IsLetterOrDigit(prev);
bool Lower () => char.IsUpper(curr) && char.IsUpper(prev);
}

/// <summary>
/// Converts specified string to kebab-case.
/// </summary>
public static string ToKebabCase (this string str)
{
int idx, length = 0;
char curr, next = default;
Span<char> buffer = stackalloc char[str.Length * 2];

for (idx = 0; idx < str.Length; idx++)
{
curr = str[idx];
next = idx + 1 < str.Length ? str[idx + 1] : default;
if (!Skip()) buffer[length++] = Lower() ? char.ToLower(curr) : curr;
if (Kebab()) buffer[length++] = '-';
}

return buffer[..length].ToString();

bool Skip () => !char.IsLetterOrDigit(curr);
bool Lower () => char.IsUpper(curr);
bool Kebab () => length > 0 && (
char.IsLower(curr) && char.IsUpper(next) ||
char.IsLetter(curr) && char.IsDigit(next) ||
char.IsDigit(curr) && char.IsLetter(next) ||
!char.IsLetterOrDigit(curr) && char.IsLetterOrDigit(next));
}
}
26 changes: 26 additions & 0 deletions backend/Naninovel.Common.Test/Utilities/TextUtilsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -258,4 +258,30 @@ public void ToPascalCaseWorksCorrectly (string input, string expected)
{
Assert.Equal(expected, input.ToPascalCase());
}

[Theory]
[InlineData("", "")]
[InlineData(" ", "")]
[InlineData("_-\\+^@", "")]
[InlineData("FooBar", "foo-bar")]
[InlineData("fooBar", "foo-bar")]
[InlineData("foo_bar", "foo-bar")]
[InlineData("FOO_BAR", "foo-bar")]
[InlineData("FOO BAR", "foo-bar")]
[InlineData("foo-bar", "foo-bar")]
[InlineData("Foo Bar", "foo-bar")]
[InlineData("Foo1", "foo-1")]
[InlineData("Foo 1", "foo-1")]
[InlineData("Foo123Bar321Nya", "foo-123-bar-321-nya")]
[InlineData("Foo 123Bar", "foo-123-bar")]
[InlineData(" Foo 123 Bar ", "foo-123-bar")]
[InlineData("Foo-123_Bar", "foo-123-bar")]
[InlineData("_foo_", "foo")]
[InlineData("__foo__", "foo")]
[InlineData("___foo___", "foo")]
[InlineData(" _ __ FOO1-2-3BAR __ _ ", "foo-1-2-3-bar")]
public void ToKebabCaseWorksCorrectly (string input, string expected)
{
Assert.Equal(expected, input.ToKebabCase());
}
}

0 comments on commit 9195ba9

Please sign in to comment.