Skip to content

Commit a28e05a

Browse files
Fix Source Gen List of Lists for CBOR (#10)
1 parent b619c9c commit a28e05a

2 files changed

Lines changed: 73 additions & 0 deletions

File tree

src/CarpaNet.SourceGen/Generation/CborContextGenerator.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,12 @@ private static string GetArrayConverterExpression(
604604
return ListConverterRef(refType, CborTypeInfoRef(refType));
605605
}
606606

607+
if (refKind == LexiconTypeKind.Array)
608+
{
609+
var innerConverter = GetConverterExpressionForArrayRef(items.Ref!, currentNsid, registry);
610+
return ListConverterRef(refType, innerConverter);
611+
}
612+
607613
var converter = GetPrimitiveConverterForRef(items.Ref!, currentNsid, registry);
608614
return ListConverterRef(refType, converter);
609615
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using CarpaNet.Generation;
2+
using CarpaNet.Models;
3+
using CarpaNet.Utilities;
4+
5+
using Xunit;
6+
7+
namespace CarpaNet.UnitTests.Generation;
8+
9+
public class CborContextGeneratorTests
10+
{
11+
[Fact]
12+
public void ArrayOfArrayRef_UsesListConverterNotStringConverter()
13+
{
14+
// Arrange: reproduce the MebiByte pattern where "transform" is an array
15+
// of "transformRow" refs, and "transformRow" is itself an array of strings.
16+
// Without the fix, the inner List<string> element gets a StringCborConverter
17+
// instead of a CborListTypeInfo<string>.
18+
var registry = new TypeRegistry();
19+
var doc = new LexiconDocument
20+
{
21+
Id = "test.nested.array",
22+
Defs = new Dictionary<string, LexiconDefinition>
23+
{
24+
["transformRow"] = new LexiconDefinition
25+
{
26+
Type = "array",
27+
Items = new LexiconDefinition { Type = "string" },
28+
},
29+
["main"] = new LexiconDefinition
30+
{
31+
Type = "object",
32+
Properties = new Dictionary<string, LexiconDefinition>
33+
{
34+
["transform"] = new LexiconDefinition
35+
{
36+
Type = "array",
37+
Items = new LexiconDefinition
38+
{
39+
Type = "ref",
40+
Ref = "#transformRow",
41+
},
42+
},
43+
},
44+
},
45+
},
46+
};
47+
registry.RegisterDocument(doc);
48+
49+
var sb = new SourceBuilder();
50+
var options = new GeneratorOptions();
51+
var mainDef = doc.Defs["main"];
52+
53+
// Act
54+
CborContextGenerator.GenerateCborTypeInfo(
55+
sb, "TestNested.Array.DefsMain", "TestNested_Array_DefsMain",
56+
mainDef, "test.nested.array", registry, options);
57+
58+
var result = sb.ToString();
59+
60+
// Assert: the transform property should wrap the inner List<string> in a
61+
// CborListTypeInfo, not pass a StringCborConverter directly as the element
62+
// converter for List<List<string>>.
63+
// Correct: CborListTypeInfo<List<string>>( CborListTypeInfo<string>( StringCborConverter ) )
64+
// Wrong: CborListTypeInfo<List<string>>( StringCborConverter )
65+
Assert.Contains("new CarpaNet.Cbor.CborListTypeInfo<global::System.Collections.Generic.List<string>>(new CarpaNet.Cbor.CborListTypeInfo<string>(new CarpaNet.Cbor.Converters.StringCborConverter()))", result);
66+
}
67+
}

0 commit comments

Comments
 (0)