From 63d4526e0db1290b795df44601c59eccd1f52136 Mon Sep 17 00:00:00 2001 From: Francis Pion Date: Wed, 16 Apr 2025 15:04:58 -0400 Subject: [PATCH 1/2] Added `StringExtensions.Humanize` method. --- CHANGELOG.md | 9 ++++- src/Logitar/Logitar.csproj | 6 +-- src/Logitar/StringExtensions.cs | 39 ++++++++++++++++++- .../StringExtensionsTests.cs | 11 ++++++ 4 files changed, 60 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7369064..f9d37b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Nothing yet. +## [1.20.4] - 2025-04-16 + +### Added + +- Method `StringExtensions.Humanize`. + ## [1.20.3] - 2025-04-16 ### Fixed @@ -281,7 +287,8 @@ Nothing yet. - Implemented StringExtensions. -[unreleased]: https://github.com/Logitar/Logitar.NET/compare/v1.20.3...HEAD +[unreleased]: https://github.com/Logitar/Logitar.NET/compare/v1.20.4...HEAD +[1.20.4]: https://github.com/Logitar/Logitar.NET/compare/v1.20.3...v1.20.4 [1.20.3]: https://github.com/Logitar/Logitar.NET/compare/v1.20.2...v1.20.3 [1.20.2]: https://github.com/Logitar/Logitar.NET/compare/v1.20.1...v1.20.2 [1.20.1]: https://github.com/Logitar/Logitar.NET/compare/v1.20.0...v1.20.1 diff --git a/src/Logitar/Logitar.csproj b/src/Logitar/Logitar.csproj index 202b522..053e3aa 100644 --- a/src/Logitar/Logitar.csproj +++ b/src/Logitar/Logitar.csproj @@ -15,14 +15,14 @@ README.md git https://github.com/Logitar/Logitar.NET - 7.0.0.0 + 7.1.0.0 $(AssemblyVersion) LICENSE True - 7.0.0 + 7.1.0 en-CA True - Removed `ExceptionDetail` and dependency from `System.Text.Json`. + Added `StringExtensions.Humanize` method. logitar net framework https://github.com/Logitar/Logitar.NET/tree/dev/src/Logitar diff --git a/src/Logitar/StringExtensions.cs b/src/Logitar/StringExtensions.cs index b836454..151b249 100644 --- a/src/Logitar/StringExtensions.cs +++ b/src/Logitar/StringExtensions.cs @@ -1,4 +1,6 @@ -namespace Logitar; +using System.Text; + +namespace Logitar; /// /// Provides extension methods for instances. @@ -33,6 +35,41 @@ public static string FromUriSafeBase64(this string s) /// The Uri-safe base6 version of the string. public static string ToUriSafeBase64(this string s) => s.Replace('+', '-').Replace('/', '_').TrimEnd('='); + /// + /// Humanizes the specified string by inserting spaces between words. Words are separated by case-change, such as in camelCase and PascalCase. + /// + /// The camelCase or PascalCase string. + /// The humanized string. + public static string Humanize(this string s) + { + List words = new(capacity: s.Length); + + StringBuilder word = new(); + for (int i = 0; i < s.Length; i++) + { + char? previous = (i > 0) ? s[i - 1] : null; + char current = s[i]; + char? next = (i < s.Length - 1) ? s[i + 1] : null; + + if (char.IsUpper(current) && ((previous.HasValue && char.IsLower(previous.Value)) || (next.HasValue && char.IsLower(next.Value)))) + { + if (word.Length > 0) + { + words.Add(word.ToString()); + word.Clear(); + } + } + + word.Append(current); + } + if (word.Length > 0) + { + words.Add(word.ToString()); + } + + return string.Join(' ', words); + } + /// /// Returns a new string where every character of the specified string has been replaced by the specified mask character (defaults to '*'). /// diff --git a/tests/Logitar.UnitTests/StringExtensionsTests.cs b/tests/Logitar.UnitTests/StringExtensionsTests.cs index f873149..f1d9a61 100644 --- a/tests/Logitar.UnitTests/StringExtensionsTests.cs +++ b/tests/Logitar.UnitTests/StringExtensionsTests.cs @@ -31,6 +31,17 @@ public void FromUriSafeBase64_uri_safe_base64_is_correctly_parsed(string base64) Assert.Equal(bytes, other); } + [Theory(DisplayName = "Humanize: it should return the correct humanized string.")] + [InlineData("", "")] + [InlineData(" ", " ")] + [InlineData("helloWorld", "hello World")] + [InlineData("HelloWorld1!", "Hello World1!")] + [InlineData("UserID", "User ID")] + public void Humanize_it_returns_the_correct_humanized_string(string input, string expected) + { + Assert.Equal(expected, input.Humanize()); + } + [Theory(DisplayName = "Mask: it returns the correct masked string.")] [InlineData(" ")] [InlineData("P@s$W0rD", '-')] From be510453f1c2bd64d25330bd98e16da243f49ae2 Mon Sep 17 00:00:00 2001 From: Francis Pion Date: Wed, 16 Apr 2025 15:06:05 -0400 Subject: [PATCH 2/2] using --- src/Logitar/Logitar.csproj | 1 + src/Logitar/StringExtensions.cs | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Logitar/Logitar.csproj b/src/Logitar/Logitar.csproj index 053e3aa..8426b0b 100644 --- a/src/Logitar/Logitar.csproj +++ b/src/Logitar/Logitar.csproj @@ -53,6 +53,7 @@ + diff --git a/src/Logitar/StringExtensions.cs b/src/Logitar/StringExtensions.cs index 151b249..654d1f1 100644 --- a/src/Logitar/StringExtensions.cs +++ b/src/Logitar/StringExtensions.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace Logitar; +namespace Logitar; /// /// Provides extension methods for instances.