diff --git a/Tomlet.Tests/EnumSerializationTests.cs b/Tomlet.Tests/EnumSerializationTests.cs deleted file mode 100644 index c04631d..0000000 --- a/Tomlet.Tests/EnumSerializationTests.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using Tomlet.Tests.TestModelClasses; -using Xunit; - -namespace Tomlet.Tests; - -public class EnumSerializationTests -{ - [Fact] - public void CanSerializeEnum() - { - var toml = TomletMain.TomlStringFrom(new {EnumValue = TestEnum.Value1}).Trim(); - Assert.Equal("EnumValue = \"Value1\"", toml); - } - - [Fact] - public void SerializingAnUndefinedEnumValueThrows() - { - var testObj = new { EnumValue = (TestEnum)4 }; - Assert.Throws(() => TomletMain.TomlStringFrom(testObj)); - } -} \ No newline at end of file diff --git a/Tomlet.Tests/EnumTests.cs b/Tomlet.Tests/EnumTests.cs new file mode 100644 index 0000000..c8166f7 --- /dev/null +++ b/Tomlet.Tests/EnumTests.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using Tomlet.Tests.TestModelClasses; +using Xunit; +using Xunit.Abstractions; + +namespace Tomlet.Tests; + +public class EnumTests +{ + private readonly ITestOutputHelper _testOutputHelper; + + public EnumTests(ITestOutputHelper testOutputHelper) + { + _testOutputHelper = testOutputHelper; + } + + [Fact] + public void CanSerializeEnum() + { + var toml = TomletMain.TomlStringFrom(new {EnumValue = TestEnum.Value1}).Trim(); + Assert.Equal("EnumValue = \"Value1\"", toml); + } + + [Fact] + public void SerializingAnUndefinedEnumValueThrows() + { + var testObj = new {EnumValue = (TestEnum)4}; + Assert.Throws(() => TomletMain.TomlStringFrom(testObj)); + } + + [Fact] + public void CanSerializeDictWithEnumValues() + { + var testObj = new Dictionary {{TestEnum.Value1, 1}, {TestEnum.Value2, 2}, {TestEnum.Value3, 3}}; + var toml = TomletMain.TomlStringFrom(testObj); + Assert.Equal("Value1 = 1\nValue2 = 2\nValue3 = 3\n", toml); + } + + [Fact] + public void CanSerializeNonInlinedClass() + { + var testObj = new Dictionary + { + { + TestEnum.Value1, new ClassWithDoNotInlineMembers + { + ShouldNotBeInlinedField = new Dictionary {{"Key", "Value1"}} + } + }, + }; + var toml = TomletMain.TomlStringFrom(testObj); + var expected = "[Value1]\nShouldBeInlined = { }\n[Value1.ShouldNotBeInlinedField]\nKey = \"Value1\"\n\n[Value1.ShouldNotBeInlinedProp]\n\n\n"; + Assert.Equal(expected, toml); + } + + [Fact] + public void CanDeserializeEnumDictionary() + { + var toml = "Value1 = 1\nValue2 = 2\nValue3 = 3\n"; + var result = TomletMain.To>(toml); + var expected = new Dictionary {{TestEnum.Value1, 1}, {TestEnum.Value2, 2}, {TestEnum.Value3, 3}}; + Assert.Equal(expected, result); + } + + [Fact] + public void CanDeserializeEnumDictionaryWithFields() + { + var toml = @" +[Value1] +a = 'A' +b = 'B' +"; + var result = TomletMain.To>(toml); + var expected = new Dictionary + { + {TestEnum.Value1, new Subname {a = "A", b = "B"}}, + }; + + Assert.Equal(expected, result); + } + + [Fact] + public void CanDeserializeEnumDictionaryInClass() + { + var toml = @" +[Subnames] +[Subnames.Value1] +a = 'A' +b = 'B' +"; + var result = TomletMain.To(toml); + var expected = new TomlTestClassWithEnumDict + { + Subnames = new Dictionary {{TestEnum.Value1, new Subname {a = "A", b = "B"}}}, + }; + + Assert.Equal(expected.Subnames, result.Subnames); + } +} \ No newline at end of file diff --git a/Tomlet.Tests/TestModelClasses/Name.cs b/Tomlet.Tests/TestModelClasses/Name.cs deleted file mode 100644 index 255a1a1..0000000 --- a/Tomlet.Tests/TestModelClasses/Name.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tomlet.Tests.TestModelClasses; - -public class Subname -{ - public string a; - public string b; -} \ No newline at end of file diff --git a/Tomlet.Tests/TestModelClasses/Subname.cs b/Tomlet.Tests/TestModelClasses/Subname.cs new file mode 100644 index 0000000..3d34d78 --- /dev/null +++ b/Tomlet.Tests/TestModelClasses/Subname.cs @@ -0,0 +1,27 @@ +using System; + +namespace Tomlet.Tests.TestModelClasses; + +public class Subname +{ + public string a; + public string b; + + protected bool Equals(Subname other) + { + return a == other.a && b == other.b; + } + + public override bool Equals(object obj) + { + if (obj is null) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != GetType()) return false; + return Equals((Subname)obj); + } + + public override int GetHashCode() + { + return HashCode.Combine(a, b); + } +} \ No newline at end of file diff --git a/Tomlet.Tests/TomlTestClassWithEnum.cs b/Tomlet.Tests/TestModelClasses/TomlTestClassWithEnum.cs similarity index 100% rename from Tomlet.Tests/TomlTestClassWithEnum.cs rename to Tomlet.Tests/TestModelClasses/TomlTestClassWithEnum.cs diff --git a/Tomlet.Tests/TestModelClasses/TomlTestClassWithEnumDict.cs b/Tomlet.Tests/TestModelClasses/TomlTestClassWithEnumDict.cs new file mode 100644 index 0000000..c05785b --- /dev/null +++ b/Tomlet.Tests/TestModelClasses/TomlTestClassWithEnumDict.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; +using Tomlet.Tests.TestModelClasses; + +namespace Tomlet.Tests; + +public class TomlTestClassWithEnumDict +{ + public Dictionary Subnames; +} \ No newline at end of file diff --git a/Tomlet.Tests/TomlTestEnum.cs b/Tomlet.Tests/TestModelClasses/TomlTestEnum.cs similarity index 100% rename from Tomlet.Tests/TomlTestEnum.cs rename to Tomlet.Tests/TestModelClasses/TomlTestEnum.cs diff --git a/Tomlet/TomlSerializationMethods.cs b/Tomlet/TomlSerializationMethods.cs index 792d17b..d3ac220 100644 --- a/Tomlet/TomlSerializationMethods.cs +++ b/Tomlet/TomlSerializationMethods.cs @@ -382,14 +382,32 @@ private static Deserialize> PrimitiveKeyedDictionaryDes #endif { var valueDeserializer = GetDeserializer(typeof(TValue), options); - + var type = typeof(TKey); return value => { if (value is not TomlTable table) throw new TomlTypeMismatchException(typeof(TomlTable), value.GetType(), typeof(Dictionary)); return table.Entries.ToDictionary( - entry => (TKey)(entry.Key as IConvertible).ToType(typeof(TKey), CultureInfo.InvariantCulture), + entry => + { + if (!type.IsEnum) + { + return (TKey)(entry.Key as IConvertible).ToType(typeof(TKey), CultureInfo.InvariantCulture); + } + + try + { + return (TKey)Enum.Parse(type, entry.Key, true); + } + catch (ArgumentException) + { + if (options.IgnoreInvalidEnumValues) + return (TKey)Enum.GetValues(type).GetValue(0)!; + + throw new TomlEnumParseException(entry.Key, typeof(TKey)); + } + }, entry => (TValue)valueDeserializer(entry.Value) ); };