Skip to content

Commit

Permalink
Added ValueTuple support
Browse files Browse the repository at this point in the history
fix #129
  • Loading branch information
mcatanzariti committed Apr 6, 2024
1 parent 87ce05a commit 3b14ada
Show file tree
Hide file tree
Showing 4 changed files with 656 additions and 0 deletions.
63 changes: 63 additions & 0 deletions src/Dahomey.Cbor.Tests/TupleTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using Xunit;

namespace Dahomey.Cbor.Tests
{
public class TupleTests
{
[Fact]
public void ReadTuple()
{
const string hexBuffer = "82664C6F6E646F6E1907E7"; //["London", 2023]
(string stringValue, int intValue) = Helper.Read<(string, int)>(hexBuffer);

Assert.Equal("London", stringValue);
Assert.Equal(2023, intValue);
}

[Fact]
public void WriteTuple()
{
const string hexBuffer = "82664C6F6E646F6E1907E7"; //["London", 2023]
string hexResult = Helper.Write(("London", 2023));

Assert.Equal(hexBuffer, hexResult);
}

public class TupleObject
{
public int Int { get; set; }
public (int, string) Tuple { get; set; }
public string String { get; set; }
}

[Fact]
public void ReadTupleObject()
{
// {"Int":12, "Tuple":[12, "foo"], "String": "foo"}
const string hexBuffer = "A363496E740C655475706C65820C63666F6F66537472696E6763666F6F";

TupleObject obj = Helper.Read<TupleObject>(hexBuffer);
Assert.NotNull(obj);
Assert.Equal(12, obj.Int);
Assert.Equal(12, obj.Tuple.Item1);
Assert.Equal("foo", obj.Tuple.Item2);
Assert.Equal("foo", obj.String);
}

[Fact]
public void WriteTupleObject()
{
// {"Int":12, "Tuple":[12, "foo"], "String": "foo"}
const string hexBuffer = "A363496E740C655475706C65820C63666F6F66537472696E6763666F6F";

TupleObject obj = new TupleObject
{
Int = 12,
Tuple = (12, "foo"),
String = "foo",
};

Helper.TestWrite(obj, hexBuffer);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public CborConverterRegistry(CborOptions options)

// order matters. It's in reverse order of how they'll get consumed
RegisterConverterProvider(new ObjectConverterProvider());
RegisterConverterProvider(new TupleConverterProvider());
RegisterConverterProvider(new CollectionConverterProvider());
RegisterConverterProvider(new PrimitiveConverterProvider());
RegisterConverterProvider(new ByAttributeConverterProvider());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace Dahomey.Cbor.Serialization.Converters.Providers
{
public class TupleConverterProvider : CborConverterProviderBase
{
private static readonly HashSet<Type> ValueTupleTypes = new HashSet<Type>(
[
typeof(ValueTuple<>),
typeof(ValueTuple<,>),
typeof(ValueTuple<,,>),
typeof(ValueTuple<,,,>),
typeof(ValueTuple<,,,,>),
typeof(ValueTuple<,,,,,>),
typeof(ValueTuple<,,,,,,>),
typeof(ValueTuple<,,,,,,,>)
]);

public override ICborConverter? GetConverter(Type type, CborOptions options)
{
if (type.IsGenericType && ValueTupleTypes.Contains(type.GetGenericTypeDefinition()))
{
FieldInfo[] fields = type.GetFields();
switch (fields.Length)
{
case 2:
return CreateGenericConverter(options, typeof(Tuple2Converter<,>), fields.Select(field => field.FieldType).ToArray());

case 3:
return CreateGenericConverter(options, typeof(Tuple3Converter<,,>), fields.Select(field => field.FieldType).ToArray());

case 4:
return CreateGenericConverter(options, typeof(Tuple4Converter<,,,>), fields.Select(field => field.FieldType).ToArray());

case 5:
return CreateGenericConverter(options, typeof(Tuple5Converter<,,,,>), fields.Select(field => field.FieldType).ToArray());

case 6:
return CreateGenericConverter(options, typeof(Tuple6Converter<,,,,,>), fields.Select(field => field.FieldType).ToArray());

case 7:
return CreateGenericConverter(options, typeof(Tuple7Converter<,,,,,,>), fields.Select(field => field.FieldType).ToArray());

case 8:
return CreateGenericConverter(options, typeof(Tuple8Converter<,,,,,,,>), fields.Select(field => field.FieldType).ToArray());

default:
throw new CborException($"Tuples of length {fields.Length} are not supported");
}
}

return null;
}
}
}
Loading

0 comments on commit 3b14ada

Please sign in to comment.