From c60bdf501b1d4d9b7378be515e3dbf9ac7a94240 Mon Sep 17 00:00:00 2001 From: Ting Liang Date: Mon, 3 Mar 2025 11:52:53 +1300 Subject: [PATCH] feat: Add support for TomlFieldAttribute (#54) --- Tomlet/Attributes/TomlFieldAttribute.cs | 19 +++++++++++++++++++ Tomlet/TomlCompositeDeserializer.cs | 14 +++++++++----- Tomlet/TomlCompositeSerializer.cs | 12 ++++++------ 3 files changed, 34 insertions(+), 11 deletions(-) create mode 100644 Tomlet/Attributes/TomlFieldAttribute.cs diff --git a/Tomlet/Attributes/TomlFieldAttribute.cs b/Tomlet/Attributes/TomlFieldAttribute.cs new file mode 100644 index 0000000..b01be30 --- /dev/null +++ b/Tomlet/Attributes/TomlFieldAttribute.cs @@ -0,0 +1,19 @@ +using System; + +namespace Tomlet.Attributes; + +[AttributeUsage(AttributeTargets.Field)] +public class TomlFieldAttribute : Attribute +{ + private readonly string _mapFrom; + + public TomlFieldAttribute(string mapFrom) + { + _mapFrom = mapFrom; + } + + public string GetMappedString() + { + return _mapFrom; + } +} \ No newline at end of file diff --git a/Tomlet/TomlCompositeDeserializer.cs b/Tomlet/TomlCompositeDeserializer.cs index 6a42204..eae3cd9 100644 --- a/Tomlet/TomlCompositeDeserializer.cs +++ b/Tomlet/TomlCompositeDeserializer.cs @@ -52,7 +52,10 @@ public static TomlSerializationMethods.Deserialize For(Type type, TomlSe var fields = type.GetFields(memberFlags); //Ignore NonSerialized and CompilerGenerated fields. - fields = fields.Where(f => !f.IsNotSerialized && GenericExtensions.GetCustomAttribute(f) == null).ToArray(); + var fieldsDict = fields + .Where(f => !f.IsNotSerialized && GenericExtensions.GetCustomAttribute(f) == null) + .Select(f => new KeyValuePair(f, GenericExtensions.GetCustomAttribute(f))) + .ToDictionary(tuple => tuple.Key, tuple => tuple.Value); var props = type.GetProperties(memberFlags); @@ -62,7 +65,7 @@ public static TomlSerializationMethods.Deserialize For(Type type, TomlSe .Select(p => new KeyValuePair(p, GenericExtensions.GetCustomAttribute(p))) .ToDictionary(tuple => tuple.Key, tuple => tuple.Value); - if (fields.Length + propsDict.Count == 0) + if (fieldsDict.Count + propsDict.Count == 0) return value => CreateInstance(type, value, options, out _); deserializer = value => @@ -72,12 +75,13 @@ public static TomlSerializationMethods.Deserialize For(Type type, TomlSe var instance = CreateInstance(type, value, options, out var assignedMembers); - foreach (var field in fields) + foreach (var (field, attribute) in fieldsDict) { - if (!options.OverrideConstructorValues && assignedMembers.Contains(field.Name)) + var name = attribute?.GetMappedString() ?? field.Name; + if (!options.OverrideConstructorValues && assignedMembers.Contains(name)) continue; - if (!table.TryGetValue(field.Name, out var entry)) + if (!table.TryGetValue(name, out var entry)) continue; //TODO: Do we want to make this configurable? As in, throw exception if data is missing? object fieldValue; diff --git a/Tomlet/TomlCompositeSerializer.cs b/Tomlet/TomlCompositeSerializer.cs index f92f254..26421fe 100644 --- a/Tomlet/TomlCompositeSerializer.cs +++ b/Tomlet/TomlCompositeSerializer.cs @@ -35,7 +35,7 @@ public static TomlSerializationMethods.Serialize For(Type type, TomlSeri var fields = type.GetFields(memberFlags); var fieldAttribs = fields - .ToDictionary(f => f, f => new {inline = GenericExtensions.GetCustomAttribute(f), preceding = GenericExtensions.GetCustomAttribute(f), noInline = GenericExtensions.GetCustomAttribute(f)}); + .ToDictionary(f => f, f => new {inline = GenericExtensions.GetCustomAttribute(f), preceding = GenericExtensions.GetCustomAttribute(f), field = GenericExtensions.GetCustomAttribute(f), noInline = GenericExtensions.GetCustomAttribute(f)}); var props = type.GetProperties(memberFlags) .ToArray(); var propAttribs = props @@ -73,7 +73,7 @@ public static TomlSerializationMethods.Serialize For(Type type, TomlSeri if(tomlValue == null) continue; - var commentAttribs = fieldAttribs[field]; + var thisFieldAttribs = fieldAttribs[field]; if (resultTable.ContainsKey(field.Name)) //Do not overwrite fields if they have the same name as something already in the table @@ -81,13 +81,13 @@ public static TomlSerializationMethods.Serialize For(Type type, TomlSeri //in its supertype. continue; - tomlValue.Comments.InlineComment = commentAttribs.inline?.Comment; - tomlValue.Comments.PrecedingComment = commentAttribs.preceding?.Comment; + tomlValue.Comments.InlineComment = thisFieldAttribs.inline?.Comment; + tomlValue.Comments.PrecedingComment = thisFieldAttribs.preceding?.Comment; - if(commentAttribs.noInline != null && tomlValue is TomlTable table) + if(thisFieldAttribs.noInline != null && tomlValue is TomlTable table) table.ForceNoInline = true; - resultTable.PutValue(field.Name, tomlValue); + resultTable.PutValue(thisFieldAttribs.field?.GetMappedString() ?? field.Name, tomlValue); } foreach (var prop in props)