From dbb311eae8904a927506d03fafb95910477b06d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabr=C3=ADcio=20Godoy?= Date: Sun, 6 Oct 2024 09:13:46 -0300 Subject: [PATCH] feat: Update version to 1.9 --- ...rationTests.Models.StatusCodeEnumInfo.g.cs | 402 ++--------------- ...tionTests.Models.StatusCodeExtensions.g.cs | 107 ++++- ...grationTests.Models.StatusCodeFactory.g.cs | 412 +++++++++++++++--- version.json | 2 +- 4 files changed, 474 insertions(+), 449 deletions(-) diff --git a/tests/EnumUtilities.Generators.IntegrationTests/Generated/Raiqub.Generators.EnumUtilities/Raiqub.Generators.EnumUtilities.EnumUtilitiesGenerator/Raiqub.Generators.EnumUtilities.IntegrationTests.Models.StatusCodeEnumInfo.g.cs b/tests/EnumUtilities.Generators.IntegrationTests/Generated/Raiqub.Generators.EnumUtilities/Raiqub.Generators.EnumUtilities.EnumUtilitiesGenerator/Raiqub.Generators.EnumUtilities.IntegrationTests.Models.StatusCodeEnumInfo.g.cs index a908337..dc3d29d 100644 --- a/tests/EnumUtilities.Generators.IntegrationTests/Generated/Raiqub.Generators.EnumUtilities/Raiqub.Generators.EnumUtilities.EnumUtilitiesGenerator/Raiqub.Generators.EnumUtilities.IntegrationTests.Models.StatusCodeEnumInfo.g.cs +++ b/tests/EnumUtilities.Generators.IntegrationTests/Generated/Raiqub.Generators.EnumUtilities/Raiqub.Generators.EnumUtilities.EnumUtilitiesGenerator/Raiqub.Generators.EnumUtilities.IntegrationTests.Models.StatusCodeEnumInfo.g.cs @@ -10,6 +10,7 @@ namespace Raiqub.Generators.EnumUtilities.IntegrationTests.Models { + /// Provides metadata for enumeration. [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Raiqub.Generators.EnumUtilities", "1.8.0.0")] public static partial class StatusCodeMetadata @@ -17,7 +18,7 @@ public static partial class StatusCodeMetadata /// Provides constant values for members names. public static partial class Name { - /// Represents the largest possible number of characters produced by converting an value to string, based on defined members. This field is constant. + /// Represents the largest possible number of characters produced by converting a value to string, based on defined members. public const int MaxCharsLength = 14; /// The string representation of name. @@ -57,7 +58,7 @@ public static partial class Name /// Provides static values for UTF-8 encoded members names. public static partial class Utf8Name { - /// Represents the largest possible number of bytes produced by converting an value to UTF-8 string, based on defined members. This field is constant. + /// Represents the largest possible number of bytes produced by converting a value to UTF-8 string, based on defined members. public const int MaxBytesLength = 14; /// The UTF-8 representation of name. @@ -97,428 +98,81 @@ public static partial class Utf8Name /// Provides constant values for serialized members values. public static partial class SerializedValue { - /// Represents the largest possible number of characters produced by converting an value to string, based on defined members. This field is constant. + /// Represents the largest possible number of characters produced by serializing a value to string, based on defined members. public const int MaxCharsLength = 14; - /// The string representation of serialized value. + /// The string representation of serialized value. public const string Unknown = "Unknown"; - /// The string representation of serialized value. + /// The string representation of serialized value. public const string Success = "Success"; - /// The string representation of serialized value. + /// The string representation of serialized value. public const string Error = "Error"; - /// The string representation of serialized value. + /// The string representation of serialized value. public const string NotFound = "Not Found"; - /// The string representation of serialized value. + /// The string representation of serialized value. public const string Timeout = "Timeout"; - /// The string representation of serialized value. + /// The string representation of serialized value. public const string Unauthorized = "Unauthorized"; - /// The string representation of serialized value. + /// The string representation of serialized value. public const string Forbidden = "Forbidden"; - /// The string representation of serialized value. + /// The string representation of serialized value. public const string Conflict = "Conflict"; - /// The string representation of serialized value. + /// The string representation of serialized value. public const string Gone = "Gone"; - /// The string representation of serialized value. + /// The string representation of serialized value. public const string InvalidRequest = "InvalidRequest"; - /// The string representation of serialized value. + /// The string representation of serialized value. public const string ServerError = "ServerError"; } - /// Provides static values for UTF-8 encoded members serialized values. + /// Provides static values for UTF-8 encoded serialized members values. public static partial class Utf8SerializedValue { - /// Represents the largest possible number of bytes produced by converting an value to UTF-8 string, based on defined members. This field is constant. + /// Represents the largest possible number of bytes produced by serializing a value to UTF-8 string, based on defined members. public const int MaxBytesLength = 14; - /// The UTF-8 representation of serialized value. + /// The UTF-8 representation of serialized value. public static ReadOnlySpan Unknown => new byte[7] { 85, 110, 107, 110, 111, 119, 110 }; - /// The UTF-8 representation of serialized value. + /// The UTF-8 representation of serialized value. public static ReadOnlySpan Success => new byte[7] { 83, 117, 99, 99, 101, 115, 115 }; - /// The UTF-8 representation of serialized value. + /// The UTF-8 representation of serialized value. public static ReadOnlySpan Error => new byte[5] { 69, 114, 114, 111, 114 }; - /// The UTF-8 representation of serialized value. + /// The UTF-8 representation of serialized value. public static ReadOnlySpan NotFound => new byte[9] { 78, 111, 116, 32, 70, 111, 117, 110, 100 }; - /// The UTF-8 representation of serialized value. + /// The UTF-8 representation of serialized value. public static ReadOnlySpan Timeout => new byte[7] { 84, 105, 109, 101, 111, 117, 116 }; - /// The UTF-8 representation of serialized value. + /// The UTF-8 representation of serialized value. public static ReadOnlySpan Unauthorized => new byte[12] { 85, 110, 97, 117, 116, 104, 111, 114, 105, 122, 101, 100 }; - /// The UTF-8 representation of serialized value. + /// The UTF-8 representation of serialized value. public static ReadOnlySpan Forbidden => new byte[9] { 70, 111, 114, 98, 105, 100, 100, 101, 110 }; - /// The UTF-8 representation of serialized value. + /// The UTF-8 representation of serialized value. public static ReadOnlySpan Conflict => new byte[8] { 67, 111, 110, 102, 108, 105, 99, 116 }; - /// The UTF-8 representation of serialized value. + /// The UTF-8 representation of serialized value. public static ReadOnlySpan Gone => new byte[4] { 71, 111, 110, 101 }; - /// The UTF-8 representation of serialized value. + /// The UTF-8 representation of serialized value. public static ReadOnlySpan InvalidRequest => new byte[14] { 73, 110, 118, 97, 108, 105, 100, 82, 101, 113, 117, 101, 115, 116 }; - /// The UTF-8 representation of serialized value. + /// The UTF-8 representation of serialized value. public static ReadOnlySpan ServerError => new byte[11] { 83, 101, 114, 118, 101, 114, 69, 114, 114, 111, 114 }; } - - /// Provides support for formatting values. - internal sealed partial class StringFormatter : IEnumFormatter - { - /// Gets the singleton instance of the class. - public static StringFormatter Instance = new StringFormatter(); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int GetStringLengthForNumber(int value) => EnumNumericFormatter.GetStringLength(value); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public string GetStringForNumber(int value) => value.ToString(); - - /// - public int? TryGetStringLengthForMember(int value) - { - return value switch - { - -1 => 7, - 0 => 7, - -2 => 5, - -3 => 8, - -4 => 7, - -5 => 12, - -6 => 9, - -7 => 8, - -8 => 4, - -9 => 14, - -10 => 11, - _ => null - }; - } - - /// - public string? TryGetStringForMember(int value) - { - return value switch - { - -1 => "Unknown", - 0 => "Success", - -2 => "Error", - -3 => "NotFound", - -4 => "Timeout", - -5 => "Unauthorized", - -6 => "Forbidden", - -7 => "Conflict", - -8 => "Gone", - -9 => "InvalidRequest", - -10 => "ServerError", - _ => null - }; - } - } - - /// Provides support for formatting serialized values. - internal sealed partial class SerializationStringFormatter : IEnumFormatter - { - /// Gets the singleton instance of the class. - public static SerializationStringFormatter Instance = new SerializationStringFormatter(); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int GetStringLengthForNumber(int value) => EnumNumericFormatter.GetStringLength(value); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public string GetStringForNumber(int value) => value.ToString(); - - /// - public int? TryGetStringLengthForMember(int value) - { - return value switch - { - -1 => 7, - 0 => 7, - -2 => 5, - -3 => 9, - -4 => 7, - -5 => 12, - -6 => 9, - -7 => 8, - -8 => 4, - -9 => 14, - -10 => 11, - _ => null - }; - } - - /// - public string? TryGetStringForMember(int value) - { - return value switch - { - -1 => "Unknown", - 0 => "Success", - -2 => "Error", - -3 => "Not Found", - -4 => "Timeout", - -5 => "Unauthorized", - -6 => "Forbidden", - -7 => "Conflict", - -8 => "Gone", - -9 => "InvalidRequest", - -10 => "ServerError", - _ => null - }; - } - } - - /// Provides support for parsing values. - internal sealed partial class StringParser - : IEnumParser - { - /// Gets the singleton instance of the class. - public static StringParser Instance = new StringParser(); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int BitwiseOr(int value1, int value2) => unchecked((int)(value1 | value2)); - - /// - public bool TryParseNumber(ReadOnlySpan value, out int result) => EnumNumericParser.TryParse(value, out result); - - /// - public bool TryParseSingleName(ReadOnlySpan value, StringComparison comparisonType, out int result) - { - if (value.IsEmpty) - { - result = 0; - return false; - } - - switch (value[0]) - { - case 'U': - case 'u': - switch (value) - { - case { } when value.Equals("Unknown", comparisonType): - result = -1; - return true; - case { } when value.Equals("Unauthorized", comparisonType): - result = -5; - return true; - } - goto default; - case 'S': - case 's': - switch (value) - { - case { } when value.Equals("Success", comparisonType): - result = 0; - return true; - case { } when value.Equals("ServerError", comparisonType): - result = -10; - return true; - } - goto default; - case 'E': - case 'e': - switch (value) - { - case { } when value.Equals("Error", comparisonType): - result = -2; - return true; - } - goto default; - case 'N': - case 'n': - switch (value) - { - case { } when value.Equals("NotFound", comparisonType): - result = -3; - return true; - } - goto default; - case 'T': - case 't': - switch (value) - { - case { } when value.Equals("Timeout", comparisonType): - result = -4; - return true; - } - goto default; - case 'F': - case 'f': - switch (value) - { - case { } when value.Equals("Forbidden", comparisonType): - result = -6; - return true; - } - goto default; - case 'C': - case 'c': - switch (value) - { - case { } when value.Equals("Conflict", comparisonType): - result = -7; - return true; - } - goto default; - case 'G': - case 'g': - switch (value) - { - case { } when value.Equals("Gone", comparisonType): - result = -8; - return true; - } - goto default; - case 'I': - case 'i': - switch (value) - { - case { } when value.Equals("InvalidRequest", comparisonType): - result = -9; - return true; - } - goto default; - default: - result = 0; - return false; - } - } - } - - /// Provides support for parsing serialized values. - internal sealed partial class SerializationStringParser : IEnumParser - { - /// Gets the singleton instance of the class. - public static SerializationStringParser Instance = new SerializationStringParser(); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int BitwiseOr(int value1, int value2) => unchecked((int)(value1 | value2)); - - /// - public bool TryParseNumber(ReadOnlySpan value, out int result) => EnumNumericParser.TryParse(value, out result); - - /// - public bool TryParseSingleName(ReadOnlySpan value, StringComparison comparisonType, out int result) - { - if (value.IsEmpty) - { - result = 0; - return false; - } - - switch (value[0]) - { - case 'U': - case 'u': - switch (value) - { - case { } when value.Equals("Unknown", comparisonType): - result = -1; - return true; - case { } when value.Equals("Unauthorized", comparisonType): - result = -5; - return true; - } - goto default; - case 'S': - case 's': - switch (value) - { - case { } when value.Equals("Success", comparisonType): - result = 0; - return true; - case { } when value.Equals("ServerError", comparisonType): - result = -10; - return true; - } - goto default; - case 'E': - case 'e': - switch (value) - { - case { } when value.Equals("Error", comparisonType): - result = -2; - return true; - } - goto default; - case 'N': - case 'n': - switch (value) - { - case { } when value.Equals("Not Found", comparisonType): - result = -3; - return true; - } - goto default; - case 'T': - case 't': - switch (value) - { - case { } when value.Equals("Timeout", comparisonType): - result = -4; - return true; - } - goto default; - case 'F': - case 'f': - switch (value) - { - case { } when value.Equals("Forbidden", comparisonType): - result = -6; - return true; - } - goto default; - case 'C': - case 'c': - switch (value) - { - case { } when value.Equals("Conflict", comparisonType): - result = -7; - return true; - } - goto default; - case 'G': - case 'g': - switch (value) - { - case { } when value.Equals("Gone", comparisonType): - result = -8; - return true; - } - goto default; - case 'I': - case 'i': - switch (value) - { - case { } when value.Equals("InvalidRequest", comparisonType): - result = -9; - return true; - } - goto default; - default: - result = 0; - return false; - } - } - } } } diff --git a/tests/EnumUtilities.Generators.IntegrationTests/Generated/Raiqub.Generators.EnumUtilities/Raiqub.Generators.EnumUtilities.EnumUtilitiesGenerator/Raiqub.Generators.EnumUtilities.IntegrationTests.Models.StatusCodeExtensions.g.cs b/tests/EnumUtilities.Generators.IntegrationTests/Generated/Raiqub.Generators.EnumUtilities/Raiqub.Generators.EnumUtilities.EnumUtilitiesGenerator/Raiqub.Generators.EnumUtilities.IntegrationTests.Models.StatusCodeExtensions.g.cs index bb2aa87..70aa6dc 100644 --- a/tests/EnumUtilities.Generators.IntegrationTests/Generated/Raiqub.Generators.EnumUtilities/Raiqub.Generators.EnumUtilities.EnumUtilitiesGenerator/Raiqub.Generators.EnumUtilities.IntegrationTests.Models.StatusCodeExtensions.g.cs +++ b/tests/EnumUtilities.Generators.IntegrationTests/Generated/Raiqub.Generators.EnumUtilities/Raiqub.Generators.EnumUtilities.EnumUtilitiesGenerator/Raiqub.Generators.EnumUtilities.IntegrationTests.Models.StatusCodeExtensions.g.cs @@ -14,14 +14,12 @@ namespace Raiqub.Generators.EnumUtilities.IntegrationTests.Models [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Raiqub.Generators.EnumUtilities", "1.8.0.0")] public static partial class StatusCodeExtensions { - private static readonly StatusCodeMetadata.StringFormatter s_stringFormatter = StatusCodeMetadata.StringFormatter.Instance; - private static readonly StatusCodeMetadata.SerializationStringFormatter s_serializationStringFormatter = StatusCodeMetadata.SerializationStringFormatter.Instance; - /// Converts the value of this instance to its equivalent string representation. /// The string representation of the value of this instance. public static string ToStringFast(this StatusCode value) { - return EnumStringFormatter.GetString((int)value, s_stringFormatter); + return GetNameInlined((int)value) + ?? ((int)value).ToString(); } /// Calculates the number of characters produced by converting the specified value to string. @@ -29,14 +27,67 @@ public static string ToStringFast(this StatusCode value) /// The number of characters produced by converting the specified value to string. public static int GetStringLength(this StatusCode value) { - return EnumStringFormatter.GetStringLength((int)value, s_stringFormatter); + return GetNameLengthInlined((int)value) + ?? EnumNumericFormatter.GetStringLength((int)value); } /// Returns a boolean telling whether the value of this instance exists in the enumeration. /// true if the value of this instance exists in the enumeration; false otherwise. public static bool IsDefined(this StatusCode value) { - return StatusCodeValidation.IsDefined(value); + return (int)value switch + { + -1 => true, + 0 => true, + -2 => true, + -3 => true, + -4 => true, + -5 => true, + -6 => true, + -7 => true, + -8 => true, + -9 => true, + -10 => true, + _ => false + }; + } + + private static int? GetNameLengthInlined(int value) + { + return value switch + { + -1 => 7, + 0 => 7, + -2 => 5, + -3 => 8, + -4 => 7, + -5 => 12, + -6 => 9, + -7 => 8, + -8 => 4, + -9 => 14, + -10 => 11, + _ => null + }; + } + + private static string? GetNameInlined(int value) + { + return value switch + { + -1 => "Unknown", + 0 => "Success", + -2 => "Error", + -3 => "NotFound", + -4 => "Timeout", + -5 => "Unauthorized", + -6 => "Forbidden", + -7 => "Conflict", + -8 => "Gone", + -9 => "InvalidRequest", + -10 => "ServerError", + _ => null + }; } /// Adds two enumerations and replaces the first integer with the sum, as an atomic operation. @@ -95,12 +146,52 @@ public static StatusCode InterlockedExchange(this ref StatusCode location, Statu public static string ToEnumMemberValue(this StatusCode value) { - return EnumStringFormatter.GetString((int)value, s_serializationStringFormatter); + return GetEnumMemberValueInlined((int)value) + ?? ((int)value).ToString(); } public static int GetEnumMemberValueStringLength(this StatusCode value) { - return EnumStringFormatter.GetStringLength((int)value, s_serializationStringFormatter); + return GetEnumMemberValueLengthInlined((int)value) + ?? EnumNumericFormatter.GetStringLength((int)value); + } + + private static int? GetEnumMemberValueLengthInlined(int value) + { + return value switch + { + -1 => 7, + 0 => 7, + -2 => 5, + -3 => 9, + -4 => 7, + -5 => 12, + -6 => 9, + -7 => 8, + -8 => 4, + -9 => 14, + -10 => 11, + _ => null + }; + } + + private static string? GetEnumMemberValueInlined(int value) + { + return value switch + { + -1 => "Unknown", + 0 => "Success", + -2 => "Error", + -3 => "Not Found", + -4 => "Timeout", + -5 => "Unauthorized", + -6 => "Forbidden", + -7 => "Conflict", + -8 => "Gone", + -9 => "InvalidRequest", + -10 => "ServerError", + _ => null + }; } public static string GetDisplayShortName(this StatusCode value) diff --git a/tests/EnumUtilities.Generators.IntegrationTests/Generated/Raiqub.Generators.EnumUtilities/Raiqub.Generators.EnumUtilities.EnumUtilitiesGenerator/Raiqub.Generators.EnumUtilities.IntegrationTests.Models.StatusCodeFactory.g.cs b/tests/EnumUtilities.Generators.IntegrationTests/Generated/Raiqub.Generators.EnumUtilities/Raiqub.Generators.EnumUtilities.EnumUtilitiesGenerator/Raiqub.Generators.EnumUtilities.IntegrationTests.Models.StatusCodeFactory.g.cs index c4d0a04..9e92f94 100644 --- a/tests/EnumUtilities.Generators.IntegrationTests/Generated/Raiqub.Generators.EnumUtilities/Raiqub.Generators.EnumUtilities.EnumUtilitiesGenerator/Raiqub.Generators.EnumUtilities.IntegrationTests.Models.StatusCodeFactory.g.cs +++ b/tests/EnumUtilities.Generators.IntegrationTests/Generated/Raiqub.Generators.EnumUtilities/Raiqub.Generators.EnumUtilities.EnumUtilitiesGenerator/Raiqub.Generators.EnumUtilities.IntegrationTests.Models.StatusCodeFactory.g.cs @@ -15,9 +15,6 @@ namespace Raiqub.Generators.EnumUtilities.IntegrationTests.Models [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Raiqub.Generators.EnumUtilities", "1.8.0.0")] public static partial class StatusCodeFactory { - private static readonly StatusCodeMetadata.StringParser s_stringParser = StatusCodeMetadata.StringParser.Instance; - private static readonly StatusCodeMetadata.SerializationStringParser s_serializationStringParser = StatusCodeMetadata.SerializationStringParser.Instance; - /// /// Converts the string representation of the name or numeric value of one or more enumerated constants to /// an equivalent enumerated object. @@ -29,9 +26,9 @@ public static partial class StatusCodeFactory /// is empty or does not represent a valid value. public static StatusCode Parse(string value, bool ignoreCase = false) { - if (value is null) ThrowArgumentNullException(nameof(value)); - TryParse(value.AsSpan(), ignoreCase, throwOnFailure: true, out var result); - return result; + if (value is null) ThrowHelper.ThrowArgumentNullException(nameof(value)); + TryParseName(value.AsSpan(), ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal, throwOnFailure: true, out var result); + return (StatusCode)result; } /// @@ -44,8 +41,8 @@ public static StatusCode Parse(string value, bool ignoreCase = false) /// is empty or does not represent a valid value. public static StatusCode Parse(ReadOnlySpan value, bool ignoreCase = false) { - TryParse(value, ignoreCase, throwOnFailure: true, out var result); - return result; + TryParseName(value, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal, throwOnFailure: true, out var result); + return (StatusCode)result; } /// @@ -60,8 +57,8 @@ public static StatusCode Parse(ReadOnlySpan value, bool ignoreCase = false public static StatusCode? ParseOrNull(string? value, bool ignoreCase = false) { if (value is null) return null; - TryParse(value.AsSpan(), ignoreCase, throwOnFailure: true, out var result); - return result; + TryParseName(value.AsSpan(), ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal, throwOnFailure: true, out var result); + return (StatusCode)result; } /// @@ -78,7 +75,8 @@ public static StatusCode Parse(ReadOnlySpan value, bool ignoreCase = false /// true if the value parameter was converted successfully; otherwise, false. public static bool TryParse([NotNullWhen(true)] string? value, bool ignoreCase, out StatusCode result) { - return TryParse(value.AsSpan(), ignoreCase, throwOnFailure: false, out result); + Unsafe.SkipInit(out result); + return TryParseName(value.AsSpan(), ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal, throwOnFailure: false, out Unsafe.As(ref result)); } /// @@ -94,7 +92,8 @@ public static bool TryParse([NotNullWhen(true)] string? value, bool ignoreCase, /// true if the value parameter was converted successfully; otherwise, false. public static bool TryParse([NotNullWhen(true)] string? value, out StatusCode result) { - return TryParse(value.AsSpan(), ignoreCase: false, throwOnFailure: false, out result); + Unsafe.SkipInit(out result); + return TryParseName(value.AsSpan(), StringComparison.Ordinal, throwOnFailure: false, out Unsafe.As(ref result)); } /// @@ -109,7 +108,7 @@ public static bool TryParse([NotNullWhen(true)] string? value, out StatusCode re /// public static StatusCode? TryParse(string? value, bool ignoreCase = false) { - return TryParse(value.AsSpan(), ignoreCase, throwOnFailure: false, out StatusCode result) ? result : null; + return TryParseName(value.AsSpan(), ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal, throwOnFailure: false, out var result) ? (StatusCode?)result : null; } /// @@ -126,7 +125,8 @@ public static bool TryParse([NotNullWhen(true)] string? value, out StatusCode re /// true if the value parameter was converted successfully; otherwise, false. public static bool TryParse(ReadOnlySpan value, bool ignoreCase, out StatusCode result) { - return TryParse(value, ignoreCase, throwOnFailure: false, out result); + Unsafe.SkipInit(out result); + return TryParseName(value, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal, throwOnFailure: false, out Unsafe.As(ref result)); } /// @@ -142,7 +142,8 @@ public static bool TryParse(ReadOnlySpan value, bool ignoreCase, out Statu /// true if the value parameter was converted successfully; otherwise, false. public static bool TryParse(ReadOnlySpan value, out StatusCode result) { - return TryParse(value, ignoreCase: false, throwOnFailure: false, out result); + Unsafe.SkipInit(out result); + return TryParseName(value, StringComparison.Ordinal, throwOnFailure: false, out Unsafe.As(ref result)); } /// @@ -157,21 +158,166 @@ public static bool TryParse(ReadOnlySpan value, out StatusCode result) /// public static StatusCode? TryParse(ReadOnlySpan value, bool ignoreCase = false) { - return TryParse(value, ignoreCase, throwOnFailure: false, out StatusCode result) ? result : null; + return TryParseName(value, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal, throwOnFailure: false, out var result) ? (StatusCode?)result : null; } - private static bool TryParse(ReadOnlySpan value, bool ignoreCase, bool throwOnFailure, out StatusCode result) + private static bool TryParseName(ReadOnlySpan value, StringComparison comparisonType, bool throwOnFailure, out int result) { - var comparisonType = ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; - bool success = EnumStringParser.TryParse(value, s_stringParser, comparisonType, throwOnFailure, out int number); - if (!success) + if (!value.IsEmpty) { - result = 0; - return false; + char c = value[0]; + if (char.IsWhiteSpace(c)) + { + value = value.TrimStart(); + if (value.IsEmpty) + { + goto ParseFailure; + } + + c = value[0]; + } + + if ((c < '0' || c > '9') && c != '-' && c != '+') + { + return TryParseNonNumericName(value, comparisonType, throwOnFailure, out result); + } + + bool success = EnumNumericParser.TryParse(value, out result); + if (success) + { + return true; + } + + return TryParseNonNumericName(value, comparisonType, throwOnFailure, out result); } - result = (StatusCode)number; - return true; + ParseFailure: + if (throwOnFailure) + { + ThrowHelper.ThrowInvalidEmptyParseArgument(nameof(value)); + } + + result = 0; + return false; + } + + private static bool TryParseNonNumericName(ReadOnlySpan value, StringComparison comparisonType, bool throwOnFailure, out int result) + { + bool success = TryParseSingleName(value, comparisonType, out result); + if (success) + { + return true; + } + + if (throwOnFailure) + { + ThrowHelper.ThrowValueNotFound(value, nameof(value)); + } + + return false; + } + + private static bool TryParseSingleName(ReadOnlySpan value, StringComparison comparisonType, out int result) + { + if (value.IsEmpty) + { + result = 0; + return false; + } + + switch (value[0]) + { + case 'C': + case 'c': + switch (value) + { + case { } when value.Equals("Conflict", comparisonType): + result = -7; + return true; + } + break; + case 'E': + case 'e': + switch (value) + { + case { } when value.Equals("Error", comparisonType): + result = -2; + return true; + } + break; + case 'F': + case 'f': + switch (value) + { + case { } when value.Equals("Forbidden", comparisonType): + result = -6; + return true; + } + break; + case 'G': + case 'g': + switch (value) + { + case { } when value.Equals("Gone", comparisonType): + result = -8; + return true; + } + break; + case 'I': + case 'i': + switch (value) + { + case { } when value.Equals("InvalidRequest", comparisonType): + result = -9; + return true; + } + break; + case 'N': + case 'n': + switch (value) + { + case { } when value.Equals("NotFound", comparisonType): + result = -3; + return true; + } + break; + case 'S': + case 's': + switch (value) + { + case { } when value.Equals("Success", comparisonType): + result = 0; + return true; + case { } when value.Equals("ServerError", comparisonType): + result = -10; + return true; + } + break; + case 'T': + case 't': + switch (value) + { + case { } when value.Equals("Timeout", comparisonType): + result = -4; + return true; + } + break; + case 'U': + case 'u': + switch (value) + { + case { } when value.Equals("Unknown", comparisonType): + result = -1; + return true; + case { } when value.Equals("Unauthorized", comparisonType): + result = -5; + return true; + } + break; + } + + result = 0; + return false; } /// @@ -193,15 +339,8 @@ public static bool TryParse( StringComparison comparisonType, out StatusCode result) { - bool success = EnumStringParser.TryParse(name, s_stringParser, comparisonType, throwOnFailure: false, out int number); - if (!success) - { - result = 0; - return false; - } - - result = (StatusCode)number; - return true; + Unsafe.SkipInit(out result); + return TryParseName(name.AsSpan(), comparisonType, throwOnFailure: false, out Unsafe.As(ref result)); } /// @@ -220,7 +359,8 @@ public static bool TryParseIgnoreCase( [NotNullWhen(true)] string? name, out StatusCode result) { - return TryParse(name.AsSpan(), ignoreCase: true, out result); + Unsafe.SkipInit(out result); + return TryParseName(name.AsSpan(), StringComparison.OrdinalIgnoreCase, throwOnFailure: false, out Unsafe.As(ref result)); } /// @@ -235,7 +375,7 @@ public static bool TryParseIgnoreCase( [Obsolete("Use TryParse overload with 'ignoreCase' parameter")] public static StatusCode? TryParseIgnoreCase(string? name) { - return TryParse(name.AsSpan(), ignoreCase: true, out StatusCode result) ? result : null; + return TryParseName(name.AsSpan(), StringComparison.OrdinalIgnoreCase, throwOnFailure: false, out var result) ? (StatusCode?)result : null; } /// @@ -252,7 +392,7 @@ public static bool TryParseIgnoreCase( [Obsolete("Use TryParse overload with 'ignoreCase' parameter")] public static StatusCode? TryParse(string? name, StringComparison comparisonType) { - return TryParse(name, comparisonType, out StatusCode result) ? result : null; + return TryParseName(name.AsSpan(), comparisonType, throwOnFailure: false, out var result) ? (StatusCode?)result : null; } /// @@ -265,9 +405,9 @@ public static bool TryParseIgnoreCase( /// is empty or does not represent a valid value. public static StatusCode ParseFromEnumMemberValue(string value, bool ignoreCase = false) { - if (value is null) ThrowArgumentNullException(nameof(value)); - TryParseFromEnumMemberValue(value.AsSpan(), ignoreCase, throwOnFailure: true, out var result); - return result; + if (value is null) ThrowHelper.ThrowArgumentNullException(nameof(value)); + TryParseEnumMemberValue(value.AsSpan(), ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal, throwOnFailure: true, out var result); + return (StatusCode)result; } /// @@ -279,8 +419,8 @@ public static StatusCode ParseFromEnumMemberValue(string value, bool ignoreCase /// is empty or does not represent a valid value. public static StatusCode ParseFromEnumMemberValue(ReadOnlySpan value, bool ignoreCase = false) { - TryParseFromEnumMemberValue(value, ignoreCase, throwOnFailure: true, out var result); - return result; + TryParseEnumMemberValue(value, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal, throwOnFailure: true, out var result); + return (StatusCode)result; } /// @@ -294,8 +434,8 @@ public static StatusCode ParseFromEnumMemberValue(ReadOnlySpan value, bool public static StatusCode? ParseFromEnumMemberValueOrNull(string? value, bool ignoreCase = false) { if (value is null) return null; - TryParseFromEnumMemberValue(value.AsSpan(), ignoreCase, throwOnFailure: true, out var result); - return result; + TryParseEnumMemberValue(value.AsSpan(), ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal, throwOnFailure: true, out var result); + return (StatusCode)result; } /// @@ -312,7 +452,8 @@ public static StatusCode ParseFromEnumMemberValue(ReadOnlySpan value, bool /// true if the value parameter was converted successfully; otherwise, false. public static bool TryParseFromEnumMemberValue([NotNullWhen(true)] string? value, bool ignoreCase, out StatusCode result) { - return TryParseFromEnumMemberValue(value.AsSpan(), ignoreCase, throwOnFailure: false, out result); + Unsafe.SkipInit(out result); + return TryParseEnumMemberValue(value.AsSpan(), ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal, throwOnFailure: false, out Unsafe.As(ref result)); } /// @@ -328,7 +469,8 @@ public static bool TryParseFromEnumMemberValue([NotNullWhen(true)] string? value /// true if the value parameter was converted successfully; otherwise, false. public static bool TryParseFromEnumMemberValue([NotNullWhen(true)] string? value, out StatusCode result) { - return TryParseFromEnumMemberValue(value.AsSpan(), ignoreCase: false, throwOnFailure: false, out result); + Unsafe.SkipInit(out result); + return TryParseEnumMemberValue(value.AsSpan(), StringComparison.Ordinal, throwOnFailure: false, out Unsafe.As(ref result)); } /// @@ -342,7 +484,7 @@ public static bool TryParseFromEnumMemberValue([NotNullWhen(true)] string? value /// public static StatusCode? TryParseFromEnumMemberValue(string? value, bool ignoreCase = false) { - return TryParseFromEnumMemberValue(value.AsSpan(), ignoreCase, throwOnFailure: false, out StatusCode result) ? result : null; + return TryParseEnumMemberValue(value.AsSpan(), ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal, throwOnFailure: false, out var result) ? (StatusCode?)result : null; } /// @@ -359,7 +501,8 @@ public static bool TryParseFromEnumMemberValue([NotNullWhen(true)] string? value /// true if the value parameter was converted successfully; otherwise, false. public static bool TryParseFromEnumMemberValue(ReadOnlySpan value, bool ignoreCase, out StatusCode result) { - return TryParseFromEnumMemberValue(value, ignoreCase, throwOnFailure: false, out result); + Unsafe.SkipInit(out result); + return TryParseEnumMemberValue(value, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal, throwOnFailure: false, out Unsafe.As(ref result)); } /// @@ -375,7 +518,8 @@ public static bool TryParseFromEnumMemberValue(ReadOnlySpan value, bool ig /// true if the value parameter was converted successfully; otherwise, false. public static bool TryParseFromEnumMemberValue(ReadOnlySpan value, out StatusCode result) { - return TryParseFromEnumMemberValue(value, ignoreCase: false, throwOnFailure: false, out result); + Unsafe.SkipInit(out result); + return TryParseEnumMemberValue(value, StringComparison.Ordinal, throwOnFailure: false, out Unsafe.As(ref result)); } /// @@ -389,25 +533,166 @@ public static bool TryParseFromEnumMemberValue(ReadOnlySpan value, out Sta /// public static StatusCode? TryParseFromEnumMemberValue(ReadOnlySpan value, bool ignoreCase = false) { - return TryParseFromEnumMemberValue(value, ignoreCase, throwOnFailure: false, out StatusCode result) ? result : null; + return TryParseEnumMemberValue(value, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal, throwOnFailure: false, out var result) ? (StatusCode?)result : null; } - private static bool TryParseFromEnumMemberValue(ReadOnlySpan value, bool ignoreCase, bool throwOnFailure, out StatusCode result) + private static bool TryParseEnumMemberValue(ReadOnlySpan value, StringComparison comparisonType, bool throwOnFailure, out int result) { - return TryParseFromEnumMemberValue(value, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal, throwOnFailure, out result); + if (!value.IsEmpty) + { + char c = value[0]; + if (char.IsWhiteSpace(c)) + { + value = value.TrimStart(); + if (value.IsEmpty) + { + goto ParseFailure; + } + + c = value[0]; + } + + if ((c < '0' || c > '9') && c != '-' && c != '+') + { + return TryParseNonNumericEnumMemberValue(value, comparisonType, throwOnFailure, out result); + } + + bool success = EnumNumericParser.TryParse(value, out result); + if (success) + { + return true; + } + + return TryParseNonNumericEnumMemberValue(value, comparisonType, throwOnFailure, out result); + } + + ParseFailure: + if (throwOnFailure) + { + ThrowHelper.ThrowInvalidEmptyParseArgument(nameof(value)); + } + + result = 0; + return false; } - private static bool TryParseFromEnumMemberValue(ReadOnlySpan value, StringComparison comparisonType, bool throwOnFailure, out StatusCode result) + private static bool TryParseNonNumericEnumMemberValue(ReadOnlySpan value, StringComparison comparisonType, bool throwOnFailure, out int result) { - bool success = EnumStringParser.TryParse(value, s_serializationStringParser, comparisonType, throwOnFailure, out int number); - if (!success) + bool success = TryParseSingleEnumMemberValue(value, comparisonType, out result); + if (success) { - result = 0; - return false; + return true; } - result = (StatusCode)number; - return true; + if (throwOnFailure) + { + ThrowHelper.ThrowValueNotFound(value, nameof(value)); + } + + return false; + } + + private static bool TryParseSingleEnumMemberValue(ReadOnlySpan value, StringComparison comparisonType, out int result) + { + if (value.IsEmpty) + { + result = 0; + return false; + } + + switch (value[0]) + { + case 'C': + case 'c': + switch (value) + { + case { } when value.Equals("Conflict", comparisonType): + result = -7; + return true; + } + break; + case 'E': + case 'e': + switch (value) + { + case { } when value.Equals("Error", comparisonType): + result = -2; + return true; + } + break; + case 'F': + case 'f': + switch (value) + { + case { } when value.Equals("Forbidden", comparisonType): + result = -6; + return true; + } + break; + case 'G': + case 'g': + switch (value) + { + case { } when value.Equals("Gone", comparisonType): + result = -8; + return true; + } + break; + case 'I': + case 'i': + switch (value) + { + case { } when value.Equals("InvalidRequest", comparisonType): + result = -9; + return true; + } + break; + case 'N': + case 'n': + switch (value) + { + case { } when value.Equals("Not Found", comparisonType): + result = -3; + return true; + } + break; + case 'S': + case 's': + switch (value) + { + case { } when value.Equals("Success", comparisonType): + result = 0; + return true; + case { } when value.Equals("ServerError", comparisonType): + result = -10; + return true; + } + break; + case 'T': + case 't': + switch (value) + { + case { } when value.Equals("Timeout", comparisonType): + result = -4; + return true; + } + break; + case 'U': + case 'u': + switch (value) + { + case { } when value.Equals("Unknown", comparisonType): + result = -1; + return true; + case { } when value.Equals("Unauthorized", comparisonType): + result = -5; + return true; + } + break; + } + + result = 0; + return false; } /// @@ -429,7 +714,8 @@ public static bool TryParseFromEnumMemberValue( StringComparison comparisonType, out StatusCode result) { - return TryParseFromEnumMemberValue(value.AsSpan(), comparisonType, throwOnFailure: false, out result); + Unsafe.SkipInit(out result); + return TryParseEnumMemberValue(value.AsSpan(), comparisonType, throwOnFailure: false, out Unsafe.As(ref result)); } /// @@ -446,7 +732,7 @@ public static bool TryParseFromEnumMemberValue( [Obsolete("Use TryParseFromEnumMemberValue overload with 'ignoreCase' parameter")] public static StatusCode? TryParseFromEnumMemberValue(string? value, StringComparison comparisonType) { - return TryParseFromEnumMemberValue(value.AsSpan(), comparisonType, throwOnFailure: false, out StatusCode result) ? result : null; + return TryParseEnumMemberValue(value.AsSpan(), comparisonType, throwOnFailure: false, out var result) ? (StatusCode?)result : null; } public static bool TryCreateFromDisplayShortName( @@ -611,11 +897,5 @@ public static string[] GetNames() "ServerError", }; } - - [DoesNotReturn] - private static void ThrowArgumentNullException(string paramName) - { - throw new ArgumentNullException(paramName); - } } } diff --git a/version.json b/version.json index b95f3d1..b940a29 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/main/src/NerdBank.GitVersioning/version.schema.json", - "version": "1.8", + "version": "1.9", "publicReleaseRefSpec": [ "^refs/tags/v\\d+\\.\\d+" ],