Skip to content

Commit

Permalink
Fix model to TOML when primitives are mixed with tables/table arrays (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
xoofx committed Apr 21, 2022
1 parent 88bca64 commit 9d6ebf3
Show file tree
Hide file tree
Showing 9 changed files with 267 additions and 205 deletions.
48 changes: 42 additions & 6 deletions src/Tomlyn.Tests/ModelTests/TomlTableModelTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,25 +247,61 @@ public void TestArrayAndInline()
[Test]
public void TestImplicitAndExplicitTable()
{
var input = @"[a.b.c]
answer = 42
[a]
var input = @"[a]
better = 43
[a.b.c]
answer = 42
";
var json = @"{
""a"": {
""better"": 43,
""b"": {
""c"": {
""answer"": 42
}
},
""better"": 43
}
}
}";
AssertJson(input, json);
}

[Test]
public void TestPrimitiveOrder()
{
var root = new Tomlyn.Model.TomlTable()
{
{
"root",
new Tomlyn.Model.TomlTable()
{
{"a", "a" },
{"b",
new Tomlyn.Model.TomlTable()
{
{ "d", "d"}
}
},
{"c", "c" },

}
}
};
var toml = Tomlyn.Toml.FromModel(root);

var root2 = Tomlyn.Toml.ToModel(toml);
var toml2 = Tomlyn.Toml.FromModel(root2);

if (toml != toml2)
{
Console.WriteLine("expected\n=====================\n");
Console.WriteLine(toml);
Console.WriteLine("result\n=====================\n");
Console.WriteLine(toml2);
Assert.AreEqual(toml, toml2);
}
}

private static void AssertJson(string input, string expectedJson)
{
var syntax = Toml.Parse(input);
Expand Down
2 changes: 1 addition & 1 deletion src/Tomlyn/Model/Accessors/DictionaryDynamicAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal class DictionaryDynamicAccessor : ObjectDynamicAccessor
{
private readonly DictionaryAccessor _dictionaryAccessor;

public DictionaryDynamicAccessor(DynamicModelReadContext context, Type type, Type keyType, Type valueType) : base(context, type)
public DictionaryDynamicAccessor(DynamicModelReadContext context, Type type, Type keyType, Type valueType) : base(context, type, ReflectionObjectKind.Dictionary)
{
if (TargetType == typeof(TomlTable))
{
Expand Down
5 changes: 4 additions & 1 deletion src/Tomlyn/Model/Accessors/DynamicAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ namespace Tomlyn.Model.Accessors;

internal abstract class DynamicAccessor
{
protected DynamicAccessor(DynamicModelReadContext context, Type targetType)
protected DynamicAccessor(DynamicModelReadContext context, Type targetType, ReflectionObjectKind kind)
{
Context = context;
TargetType = targetType;
Kind = kind;
}

public ReflectionObjectKind Kind { get; }

public DynamicModelReadContext Context { get; }

public Type TargetType { get; }
Expand Down
4 changes: 2 additions & 2 deletions src/Tomlyn/Model/Accessors/DynamicModelReadContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public DynamicAccessor GetAccessor(Type type)
accessor = new PrimitiveDynamicAccessor(this, reflectionInfo.GenericArgument1!, true);
break;
case ReflectionObjectKind.NullableStruct:
accessor = new StandardObjectDynamicAccessor(this, reflectionInfo.GenericArgument1!); ;
accessor = new StandardObjectDynamicAccessor(this, reflectionInfo.GenericArgument1!, ReflectionObjectKind.Struct); ;
break;
case ReflectionObjectKind.Collection:
accessor = new ListDynamicAccessor(this, type, reflectionInfo.GenericArgument1!);
Expand All @@ -56,7 +56,7 @@ public DynamicAccessor GetAccessor(Type type)
break;
case ReflectionObjectKind.Struct:
case ReflectionObjectKind.Object:
accessor = new StandardObjectDynamicAccessor(this, type); ;
accessor = new StandardObjectDynamicAccessor(this, type, reflectionInfo.Kind); ;
break;
default:
throw new ArgumentOutOfRangeException($"Unsupported {reflectionInfo.Kind}");
Expand Down
2 changes: 1 addition & 1 deletion src/Tomlyn/Model/Accessors/ListDynamicAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ internal class ListDynamicAccessor : DynamicAccessor
private readonly PropertyInfo? _propCount;
private readonly MethodInfo? _addMethod;

public ListDynamicAccessor(DynamicModelReadContext context, Type type, Type elementType) : base(context, type)
public ListDynamicAccessor(DynamicModelReadContext context, Type type, Type elementType) : base(context, type, ReflectionObjectKind.Collection)
{
ElementType = elementType;

Expand Down
2 changes: 1 addition & 1 deletion src/Tomlyn/Model/Accessors/ObjectDynamicAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Tomlyn.Model.Accessors;

internal abstract class ObjectDynamicAccessor : DynamicAccessor
{
protected ObjectDynamicAccessor(DynamicModelReadContext context, Type targetType) : base(context, targetType)
protected ObjectDynamicAccessor(DynamicModelReadContext context, Type targetType, ReflectionObjectKind kind) : base(context, targetType, kind)
{
}

Expand Down
2 changes: 1 addition & 1 deletion src/Tomlyn/Model/Accessors/PrimitiveDynamicAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace Tomlyn.Model.Accessors;

internal sealed class PrimitiveDynamicAccessor : DynamicAccessor
{
public PrimitiveDynamicAccessor(DynamicModelReadContext context, Type targetType, bool isNullable) : base(context, targetType)
public PrimitiveDynamicAccessor(DynamicModelReadContext context, Type targetType, bool isNullable) : base(context, targetType, ReflectionObjectKind.Primitive)
{
IsNullable = isNullable;
}
Expand Down
Loading

0 comments on commit 9d6ebf3

Please sign in to comment.