Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions Tomlet/Attributes/TomlFieldAttribute.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
14 changes: 9 additions & 5 deletions Tomlet/TomlCompositeDeserializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ public static TomlSerializationMethods.Deserialize<object> For(Type type, TomlSe
var fields = type.GetFields(memberFlags);

//Ignore NonSerialized and CompilerGenerated fields.
fields = fields.Where(f => !f.IsNotSerialized && GenericExtensions.GetCustomAttribute<CompilerGeneratedAttribute>(f) == null).ToArray();
var fieldsDict = fields
.Where(f => !f.IsNotSerialized && GenericExtensions.GetCustomAttribute<CompilerGeneratedAttribute>(f) == null)
.Select(f => new KeyValuePair<FieldInfo, TomlFieldAttribute?>(f, GenericExtensions.GetCustomAttribute<TomlFieldAttribute>(f)))
.ToDictionary(tuple => tuple.Key, tuple => tuple.Value);

var props = type.GetProperties(memberFlags);

Expand All @@ -62,7 +65,7 @@ public static TomlSerializationMethods.Deserialize<object> For(Type type, TomlSe
.Select(p => new KeyValuePair<PropertyInfo, TomlPropertyAttribute?>(p, GenericExtensions.GetCustomAttribute<TomlPropertyAttribute>(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 =>
Expand All @@ -72,12 +75,13 @@ public static TomlSerializationMethods.Deserialize<object> 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;
Expand Down
12 changes: 6 additions & 6 deletions Tomlet/TomlCompositeSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public static TomlSerializationMethods.Serialize<object> For(Type type, TomlSeri

var fields = type.GetFields(memberFlags);
var fieldAttribs = fields
.ToDictionary(f => f, f => new {inline = GenericExtensions.GetCustomAttribute<TomlInlineCommentAttribute>(f), preceding = GenericExtensions.GetCustomAttribute<TomlPrecedingCommentAttribute>(f), noInline = GenericExtensions.GetCustomAttribute<TomlDoNotInlineObjectAttribute>(f)});
.ToDictionary(f => f, f => new {inline = GenericExtensions.GetCustomAttribute<TomlInlineCommentAttribute>(f), preceding = GenericExtensions.GetCustomAttribute<TomlPrecedingCommentAttribute>(f), field = GenericExtensions.GetCustomAttribute<TomlFieldAttribute>(f), noInline = GenericExtensions.GetCustomAttribute<TomlDoNotInlineObjectAttribute>(f)});
var props = type.GetProperties(memberFlags)
.ToArray();
var propAttribs = props
Expand Down Expand Up @@ -73,21 +73,21 @@ public static TomlSerializationMethods.Serialize<object> 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
//This fixes serializing types which re-declare a field using the `new` keyword, overwriting a field of the same name
//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)
Expand Down
Loading