Skip to content

Commit

Permalink
Add support for using TypeId as dictionary keys with system.text.json
Browse files Browse the repository at this point in the history
  • Loading branch information
danspam committed Feb 21, 2024
1 parent c29e997 commit c58e8ce
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public void TypeId_Plain_Serialized()

json.Should().Be($"\"{TypeIdStr}\"");
}

[Test]
public void TypeId_NestedProperty_Serialized()
{
Expand All @@ -42,7 +42,7 @@ public void TypeId_Plain_Deserialized()

typeId.Should().Be(TypeId.Parse(TypeIdStr).Decode());
}

[Test]
public void TypeId_NestedProperty_Deserialized()
{
Expand All @@ -59,6 +59,24 @@ public void TypeId_Collection_Deserialized()
obj.Should().BeEquivalentTo(new TypeIdDecodedArrayContainer(new[] { TypeId.Parse(TypeIdStr).Decode(), TypeId.Parse("prefix_0123456789abcdefghjkmnpqrs").Decode() }));
}

[Test]
public void TypeId_DictionaryKey_Serialized()
{
var obj = new Dictionary<TypeIdDecoded, string> { { TypeId.Parse(TypeIdStr).Decode(), "Test" } };

var json = JsonSerializer.Serialize(obj, _options);

json.Should().Be($"{{\"{TypeIdStr}\":\"Test\"}}");
}

[Test]
public void TypeId_DictionaryKey_DeSerialized()
{
var obj = JsonSerializer.Deserialize<Dictionary<TypeIdDecoded, string>>($"{{\"{TypeIdStr}\":\"Test\"}}", _options);

obj.Should().BeEquivalentTo(new Dictionary<TypeIdDecoded, string> { { TypeId.Parse(TypeIdStr).Decode(), "Test" } });
}

private record TypeIdDecodedContainer(TypeIdDecoded Id, int Value);

private record TypeIdDecodedArrayContainer(TypeIdDecoded[] Items);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public void TypeId_Plain_Serialized()

json.Should().Be($"\"{TypeIdStr}\"");
}

[Test]
public void TypeId_NestedProperty_Serialized()
{
Expand All @@ -42,7 +42,7 @@ public void TypeId_Plain_Deserialized()

typeId.Should().Be(TypeId.Parse(TypeIdStr));
}

[Test]
public void TypeId_NestedProperty_Deserialized()
{
Expand All @@ -59,6 +59,24 @@ public void TypeId_Collection_Deserialized()
obj.Should().BeEquivalentTo(new TypeIdArrayContainer(new[] { TypeId.Parse(TypeIdStr), TypeId.Parse("prefix_0123456789abcdefghjkmnpqrs") }));
}

[Test]
public void TypeId_DictionaryKey_Serialized()
{
var obj = new Dictionary<TypeId, string> { { TypeId.Parse(TypeIdStr), "Test"} };

var json = JsonSerializer.Serialize(obj, _options);

json.Should().Be($"{{\"{TypeIdStr}\":\"Test\"}}");
}

[Test]
public void TypeId_DictionaryKey_DeSerialized()
{
var obj = JsonSerializer.Deserialize<Dictionary<TypeId, string>>($"{{\"{TypeIdStr}\":\"Test\"}}", _options);

obj.Should().BeEquivalentTo(new Dictionary<TypeId, string> { { TypeId.Parse(TypeIdStr), "Test" } });
}

private record TypeIdContainer(TypeId Id, int Value);

private record TypeIdArrayContainer(TypeId[] Items);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.Json;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace FastIDs.TypeId.Serialization.SystemTextJson;
Expand All @@ -15,4 +16,15 @@ public override void Write(Utf8JsonWriter writer, TypeId value, JsonSerializerOp
{
writer.WriteStringValue(value.ToString());
}

public override void WriteAsPropertyName(Utf8JsonWriter writer, [DisallowNull] TypeId value, JsonSerializerOptions options)
{
writer.WritePropertyName(value.ToString());
}

public override TypeId ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var val = reader.GetString();
return val is not null ? TypeId.Parse(val) : default;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.Json;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace FastIDs.TypeId.Serialization.SystemTextJson;
Expand All @@ -7,19 +8,44 @@ public class TypeIdDecodedConverter : JsonConverter<TypeIdDecoded>
{
public override TypeIdDecoded Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var val = reader.GetString();
return val is not null ? TypeId.Parse(val).Decode() : default;
return ReadTypeId(ref reader);
}

public override void Write(Utf8JsonWriter writer, TypeIdDecoded value, JsonSerializerOptions options)
{
var totalLength = value.Type.Length + 1 + 26;
Span<char> buffer = stackalloc char[totalLength];


CopyValueToBuffer(value, buffer);

writer.WriteStringValue(buffer);
}

public override TypeIdDecoded ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return ReadTypeId(ref reader);
}

public override void WriteAsPropertyName(Utf8JsonWriter writer, [DisallowNull] TypeIdDecoded value, JsonSerializerOptions options)
{
var totalLength = value.Type.Length + 1 + 26;
Span<char> buffer = stackalloc char[totalLength];

CopyValueToBuffer(value, buffer);

writer.WritePropertyName(buffer);
}

private static TypeIdDecoded ReadTypeId(ref Utf8JsonReader reader)
{
var val = reader.GetString();
return val is not null ? TypeId.Parse(val).Decode() : default;
}

private static void CopyValueToBuffer(TypeIdDecoded value, Span<char> buffer)
{
value.Type.AsSpan().CopyTo(buffer);
buffer[value.Type.Length] = '_';
value.GetSuffix(buffer[(value.Type.Length + 1)..]);

writer.WriteStringValue(buffer);
}
}

0 comments on commit c58e8ce

Please sign in to comment.