From a7c1189617d301edf08827e5866e3b6243e33785 Mon Sep 17 00:00:00 2001 From: yu_xianglong <87717663@qq.com> Date: Tue, 18 Feb 2025 16:13:48 +0800 Subject: [PATCH] feat - Support 'Ignore Case' in TryParseFast --- .../EnumSourceGenerator.cs | 35 +++++++++++++ test/Console.Test.Benchmark/Program.cs | 26 ++++++++++ test/UnitTests/EnumGeneratorTest.cs | 52 +++++++++++++++++++ 3 files changed, 113 insertions(+) diff --git a/Supernova.Enum.Generators/EnumSourceGenerator.cs b/Supernova.Enum.Generators/EnumSourceGenerator.cs index 7ab0f1a..7ae97be 100644 --- a/Supernova.Enum.Generators/EnumSourceGenerator.cs +++ b/Supernova.Enum.Generators/EnumSourceGenerator.cs @@ -438,5 +438,40 @@ private static void TryParseFast(StringBuilder sourceBuilder, EnumDeclarationSyn } """ ); + + + + sourceBuilder.Append($@" + /// + /// Try parse a string to value. + /// + /// The string representing a value. + /// The enum parse result. + /// See StringComparison for meaning of different comparisonType + /// True if the string is parsed successfully; otherwise, false. + public static bool {SourceGeneratorHelper.ExtensionMethodNameTryParse}(string states, out {symbol.FullName()} result,StringComparison comparisonType) + {{ + result =default; +"); + foreach (var member in e.Members.Select(x => x.Identifier.ValueText)) + sourceBuilder.AppendLine( + $$""" + + if (string.Compare(states, "{{member}}", comparisonType ) == 0) + { + result = {{symbol.FullName()}}.{{member}}; + return true; + } + """); + sourceBuilder.Append( + """ + + + return false; + + + } + """ + ); } } diff --git a/test/Console.Test.Benchmark/Program.cs b/test/Console.Test.Benchmark/Program.cs index da49a6f..c0c5720 100644 --- a/test/Console.Test.Benchmark/Program.cs +++ b/test/Console.Test.Benchmark/Program.cs @@ -8,6 +8,7 @@ using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Order; using BenchmarkDotNet.Running; +using CommandLine; using EnumFastToStringGenerated; using Perfolizer.Horology; using System; @@ -154,6 +155,31 @@ public bool FastTryParse() { return UserTypeEnumExtensions.TryParseFast("Men",out _); } + + [Benchmark] + public void Parse_CaseSensitive_Ordinal() + { + UserTypeEnumExtensions.TryParseFast("Men", out _, StringComparison.Ordinal); + } + + [Benchmark] + public void Parse_CaseInsensitive_Ordinal() + { + UserTypeEnumExtensions.TryParseFast("men", out _, StringComparison.Ordinal); + } + + [Benchmark] + public void Parse_CaseSensitive_OrdinalIgnoreCase() + { + UserTypeEnumExtensions.TryParseFast("Men", out _, StringComparison.OrdinalIgnoreCase); + } + + [Benchmark] + public void Parse_CaseInsensitive_OrdinalIgnoreCase() + { + UserTypeEnumExtensions.TryParseFast("men", out _, StringComparison.OrdinalIgnoreCase); + } + } public static class Ext diff --git a/test/UnitTests/EnumGeneratorTest.cs b/test/UnitTests/EnumGeneratorTest.cs index 8b2dc84..164a5f5 100644 --- a/test/UnitTests/EnumGeneratorTest.cs +++ b/test/UnitTests/EnumGeneratorTest.cs @@ -188,5 +188,57 @@ public void TestEnumTryParse() } + + [DataTestMethod] + [DataRow("Men", StringComparison.OrdinalIgnoreCase, UserTypeTest.Men)] + [DataRow("men", StringComparison.OrdinalIgnoreCase, UserTypeTest.Men)] + [DataRow("MEN", StringComparison.OrdinalIgnoreCase, UserTypeTest.Men)] + [DataRow("Women", StringComparison.OrdinalIgnoreCase, UserTypeTest.Women)] + [DataRow("women", StringComparison.OrdinalIgnoreCase, UserTypeTest.Women)] + [DataRow("WOMEN", StringComparison.OrdinalIgnoreCase, UserTypeTest.Women)] + [DataRow("None", StringComparison.OrdinalIgnoreCase, UserTypeTest.None)] + [DataRow("none", StringComparison.OrdinalIgnoreCase, UserTypeTest.None)] + [DataRow("NONE", StringComparison.OrdinalIgnoreCase, UserTypeTest.None)] + public void TryParseFast_IgnoreCase_ReturnsCorrectResult(string input, StringComparison comparisonType, UserTypeTest expected) + { + // Act + bool success = UserTypeTestEnumExtensions.TryParseFast(input, out UserTypeTest result, comparisonType); + + // Assert + Assert.IsTrue(success); + Assert.AreEqual(expected, result); + } + + [DataTestMethod] + [DataRow("Men", StringComparison.Ordinal, UserTypeTest.Men)] + [DataRow("Women", StringComparison.Ordinal, UserTypeTest.Women)] + [DataRow("None", StringComparison.Ordinal, UserTypeTest.None)] + public void TryParseFast_Ordinal_ReturnsCorrectResult(string input, StringComparison comparisonType, UserTypeTest expected) + { + // Act + bool success = UserTypeTestEnumExtensions.TryParseFast(input, out UserTypeTest result, comparisonType); + + // Assert + Assert.IsTrue(success); + Assert.AreEqual(expected, result); + } + + [DataTestMethod] + [DataRow("men", StringComparison.Ordinal)] + [DataRow("MEN", StringComparison.Ordinal)] + [DataRow("women", StringComparison.Ordinal)] + [DataRow("WOMEN", StringComparison.Ordinal)] + [DataRow("none", StringComparison.Ordinal)] + [DataRow("NONE", StringComparison.Ordinal)] + public void TryParseFast_Ordinal_CaseSensitive_Fails(string input, StringComparison comparisonType) + { + // Act + bool success = UserTypeTestEnumExtensions.TryParseFast(input, out UserTypeTest result, comparisonType); + + // Assert + Assert.IsFalse(success); + Assert.AreEqual(default(UserTypeTest), result); + } + private UserTypeTest GetUndefinedEnumValue() => (UserTypeTest)(-1); }