From fc593926cf5cc4bbd56338973318047ae8f28cba Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Fri, 20 Sep 2024 14:55:00 +1200 Subject: [PATCH] Fix enum parsing Signed-off-by: Thomas Farr --- src/OpenSearch.Net/Api/Enums.cs | 4 +- src/OpenSearch.Net/OpenSearch.Net.csproj | 1 + .../ClientConcepts/Enums/EnumParsingTests.cs | 62 +++++++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 tests/Tests/ClientConcepts/Enums/EnumParsingTests.cs diff --git a/src/OpenSearch.Net/Api/Enums.cs b/src/OpenSearch.Net/Api/Enums.cs index 6a07648f1a..be5dbe344b 100644 --- a/src/OpenSearch.Net/Api/Enums.cs +++ b/src/OpenSearch.Net/Api/Enums.cs @@ -90,7 +90,7 @@ private static Func GetEnumStringResolver(Type type) : e => dictionary[e]; } - public static TEnum Parse(string value) + internal static TEnum Parse(string value) where TEnum : struct, Enum { var parser = EnumStringParsers.GetOrAdd(typeof(TEnum), GetEnumStringParser); @@ -113,7 +113,7 @@ private static Func GetEnumStringParser(Type type) var isFlag = type.GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0; return isFlag - ? s => (Enum) Convert.ChangeType(s.ToLowerInvariant().Split(',').Aggregate(0ul, (acc, value) => acc | Convert.ToUInt64(dictionary[value])), type) + ? s => (Enum)Enum.ToObject(type, s.ToLowerInvariant().Split(',').Aggregate(0, (acc, value) => acc | Convert.ToInt32(dictionary[value]))) : s => dictionary[s.ToLowerInvariant()]; } } diff --git a/src/OpenSearch.Net/OpenSearch.Net.csproj b/src/OpenSearch.Net/OpenSearch.Net.csproj index 155b16c0fd..fe4682bf85 100644 --- a/src/OpenSearch.Net/OpenSearch.Net.csproj +++ b/src/OpenSearch.Net/OpenSearch.Net.csproj @@ -41,6 +41,7 @@ + diff --git a/tests/Tests/ClientConcepts/Enums/EnumParsingTests.cs b/tests/Tests/ClientConcepts/Enums/EnumParsingTests.cs new file mode 100644 index 0000000000..be0e0487b4 --- /dev/null +++ b/tests/Tests/ClientConcepts/Enums/EnumParsingTests.cs @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ + +using System; +using System.Runtime.Serialization; +using FluentAssertions; +using OpenSearch.Net; +using OpenSearch.OpenSearch.Xunit.XunitPlumbing; + +namespace Tests.ClientConcepts.Enums; + +public class EnumParsingTests +{ + [U] + public void CanParseRegularEnum() => KnownEnums.Parse("first").Should().Be(RegularEnum.First); + + [U] + public void CanParseEnumWithAttribute() => KnownEnums.Parse("second_value").Should().Be(EnumWithAttribute.Second); + + [U] + public void CanParseFlagsEnum() => KnownEnums.Parse("first,third").Should().Be(FlagsEnum.First | FlagsEnum.Third); + + [U] + public void CanParseFlagsEnumWithAttribute() => KnownEnums.Parse("first_value,third_value").Should().Be(FlagsEnumWithAttribute.First | FlagsEnumWithAttribute.Third); + +private enum RegularEnum + { + First, + Second + } + + private enum EnumWithAttribute + { + [EnumMember(Value = "first_value")] + First, + [EnumMember(Value = "second_value")] + Second + } + + [Flags] + private enum FlagsEnum + { + First = 1 << 0, + Second = 1 << 1, + Third = 1 << 2 + } + + [Flags] + private enum FlagsEnumWithAttribute + { + [EnumMember(Value = "first_value")] + First = 1 << 0, + [EnumMember(Value = "second_value")] + Second = 1 << 1, + [EnumMember(Value = "third_value")] + Third = 1 << 2 + } +}