Skip to content

Commit

Permalink
Added more node ID value serializers. (#7538)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelstaib authored Sep 30, 2024
1 parent d8b055a commit 9a8ee1c
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ public static IRequestExecutorBuilder AddDefaultNodeIdSerializer(
builder.Services.AddSingleton<INodeIdValueSerializer, Int32NodeIdValueSerializer>();
builder.Services.AddSingleton<INodeIdValueSerializer, Int64NodeIdValueSerializer>();
builder.Services.AddSingleton<INodeIdValueSerializer>(new GuidNodeIdValueSerializer(compress: outputNewIdFormat));
builder.Services.AddSingleton<INodeIdValueSerializer, DecimalNodeIdValueSerializer>();
builder.Services.AddSingleton<INodeIdValueSerializer, SingleNodeIdValueSerializer>();
builder.Services.AddSingleton<INodeIdValueSerializer, DoubleNodeIdValueSerializer>();
}

builder.Services.TryAddSingleton<INodeIdSerializer>(sp =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#nullable enable
using System.Buffers.Text;
using System.Diagnostics.CodeAnalysis;

namespace HotChocolate.Types.Relay;

internal sealed class DecimalNodeIdValueSerializer : INodeIdValueSerializer
{
public bool IsSupported(Type type) => type == typeof(decimal) || type == typeof(decimal?);

public NodeIdFormatterResult Format(Span<byte> buffer, object value, out int written)
{
if (value is decimal i)
{
return Utf8Formatter.TryFormat(i, buffer, out written)
? NodeIdFormatterResult.Success
: NodeIdFormatterResult.BufferTooSmall;
}

written = 0;
return NodeIdFormatterResult.InvalidValue;
}

public bool TryParse(ReadOnlySpan<byte> buffer, [NotNullWhen(true)] out object? value)
{
if (Utf8Parser.TryParse(buffer, out decimal parsedValue, out _))
{
value = parsedValue;
return true;
}

value = null;
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#nullable enable
using System.Buffers.Text;
using System.Diagnostics.CodeAnalysis;

namespace HotChocolate.Types.Relay;

internal sealed class DoubleNodeIdValueSerializer : INodeIdValueSerializer
{
public bool IsSupported(Type type) => type == typeof(double) || type == typeof(double?);

public NodeIdFormatterResult Format(Span<byte> buffer, object value, out int written)
{
if (value is double i)
{
return Utf8Formatter.TryFormat(i, buffer, out written)
? NodeIdFormatterResult.Success
: NodeIdFormatterResult.BufferTooSmall;
}

written = 0;
return NodeIdFormatterResult.InvalidValue;
}

public bool TryParse(ReadOnlySpan<byte> buffer, [NotNullWhen(true)] out object? value)
{
if (Utf8Parser.TryParse(buffer, out double parsedValue, out _))
{
value = parsedValue;
return true;
}

value = null;
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#nullable enable
using System.Buffers.Text;
using System.Diagnostics.CodeAnalysis;

namespace HotChocolate.Types.Relay;

internal sealed class SingleNodeIdValueSerializer : INodeIdValueSerializer
{
public bool IsSupported(Type type) => type == typeof(float) || type == typeof(float?);

public NodeIdFormatterResult Format(Span<byte> buffer, object value, out int written)
{
if (value is float i)
{
return Utf8Formatter.TryFormat(i, buffer, out written)
? NodeIdFormatterResult.Success
: NodeIdFormatterResult.BufferTooSmall;
}

written = 0;
return NodeIdFormatterResult.InvalidValue;
}

public bool TryParse(ReadOnlySpan<byte> buffer, [NotNullWhen(true)] out object? value)
{
if (Utf8Parser.TryParse(buffer, out float parsedValue, out _))
{
value = parsedValue;
return true;
}

value = null;
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,36 @@ public void Format_Int64Id_Legacy_Format()
Assert.Equal("Rm9vCmw2NA==", id);
}

[Fact]
public void Format_DecimalId()
{
var serializer = CreateSerializer("Foo", new DecimalNodeIdValueSerializer());

var id = serializer.Format("Foo", (decimal)6);

Assert.Equal("Rm9vOjY=", id);
}

[Fact]
public void Format_FloatId()
{
var serializer = CreateSerializer("Foo", new SingleNodeIdValueSerializer());

var id = serializer.Format("Foo", (float)6);

Assert.Equal("Rm9vOjY=", id);
}

[Fact]
public void Format_DoubleId()
{
var serializer = CreateSerializer("Foo", new DoubleNodeIdValueSerializer());

var id = serializer.Format("Foo", (double)6);

Assert.Equal("Rm9vOjY=", id);
}

[Fact]
public void Format_Empty_Guid()
{
Expand Down Expand Up @@ -363,6 +393,39 @@ public void Parse_Legacy_Int64Id()
Assert.Equal((long)123, id.InternalId);
}

[Fact]
public void Parse_DecimalId()
{
var serializer = CreateSerializer("Foo", new DecimalNodeIdValueSerializer());

var id = serializer.Parse("Rm9vOjEyMw==", typeof(decimal));

Assert.Equal("Foo", id.TypeName);
Assert.Equal((decimal)123, id.InternalId);
}

[Fact]
public void Parse_SingleId()
{
var serializer = CreateSerializer("Foo", new SingleNodeIdValueSerializer());

var id = serializer.Parse("Rm9vOjEyMw==", typeof(float));

Assert.Equal("Foo", id.TypeName);
Assert.Equal((float)123, id.InternalId);
}

[Fact]
public void Parse_DoublelId()
{
var serializer = CreateSerializer("Foo", new DoubleNodeIdValueSerializer());

var id = serializer.Parse("Rm9vOjEyMw==", typeof(double));

Assert.Equal("Foo", id.TypeName);
Assert.Equal((double)123, id.InternalId);
}

[Fact]
public void Parse_CompositeId()
{
Expand Down Expand Up @@ -497,7 +560,7 @@ protected override NodeIdFormatterResult Format(Span<byte> buffer, CompositeId v

protected override bool TryParse(ReadOnlySpan<byte> buffer, out CompositeId value)
{
if(TryParseIdPart(buffer, out string a, out var ac) &&
if (TryParseIdPart(buffer, out string a, out var ac) &&
TryParseIdPart(buffer.Slice(ac), out int b, out var bc) &&
TryParseIdPart(buffer.Slice(ac + bc), out Guid c, out var cc) &&
TryParseIdPart(buffer.Slice(ac + bc + cc), out bool d, out _))
Expand Down

0 comments on commit 9a8ee1c

Please sign in to comment.