Skip to content

Commit 9a8ee1c

Browse files
authored
Added more node ID value serializers. (#7538)
1 parent d8b055a commit 9a8ee1c

File tree

5 files changed

+172
-1
lines changed

5 files changed

+172
-1
lines changed

src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.IdSerializer.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ public static IRequestExecutorBuilder AddDefaultNodeIdSerializer(
5050
builder.Services.AddSingleton<INodeIdValueSerializer, Int32NodeIdValueSerializer>();
5151
builder.Services.AddSingleton<INodeIdValueSerializer, Int64NodeIdValueSerializer>();
5252
builder.Services.AddSingleton<INodeIdValueSerializer>(new GuidNodeIdValueSerializer(compress: outputNewIdFormat));
53+
builder.Services.AddSingleton<INodeIdValueSerializer, DecimalNodeIdValueSerializer>();
54+
builder.Services.AddSingleton<INodeIdValueSerializer, SingleNodeIdValueSerializer>();
55+
builder.Services.AddSingleton<INodeIdValueSerializer, DoubleNodeIdValueSerializer>();
5356
}
5457

5558
builder.Services.TryAddSingleton<INodeIdSerializer>(sp =>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#nullable enable
2+
using System.Buffers.Text;
3+
using System.Diagnostics.CodeAnalysis;
4+
5+
namespace HotChocolate.Types.Relay;
6+
7+
internal sealed class DecimalNodeIdValueSerializer : INodeIdValueSerializer
8+
{
9+
public bool IsSupported(Type type) => type == typeof(decimal) || type == typeof(decimal?);
10+
11+
public NodeIdFormatterResult Format(Span<byte> buffer, object value, out int written)
12+
{
13+
if (value is decimal i)
14+
{
15+
return Utf8Formatter.TryFormat(i, buffer, out written)
16+
? NodeIdFormatterResult.Success
17+
: NodeIdFormatterResult.BufferTooSmall;
18+
}
19+
20+
written = 0;
21+
return NodeIdFormatterResult.InvalidValue;
22+
}
23+
24+
public bool TryParse(ReadOnlySpan<byte> buffer, [NotNullWhen(true)] out object? value)
25+
{
26+
if (Utf8Parser.TryParse(buffer, out decimal parsedValue, out _))
27+
{
28+
value = parsedValue;
29+
return true;
30+
}
31+
32+
value = null;
33+
return false;
34+
}
35+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#nullable enable
2+
using System.Buffers.Text;
3+
using System.Diagnostics.CodeAnalysis;
4+
5+
namespace HotChocolate.Types.Relay;
6+
7+
internal sealed class DoubleNodeIdValueSerializer : INodeIdValueSerializer
8+
{
9+
public bool IsSupported(Type type) => type == typeof(double) || type == typeof(double?);
10+
11+
public NodeIdFormatterResult Format(Span<byte> buffer, object value, out int written)
12+
{
13+
if (value is double i)
14+
{
15+
return Utf8Formatter.TryFormat(i, buffer, out written)
16+
? NodeIdFormatterResult.Success
17+
: NodeIdFormatterResult.BufferTooSmall;
18+
}
19+
20+
written = 0;
21+
return NodeIdFormatterResult.InvalidValue;
22+
}
23+
24+
public bool TryParse(ReadOnlySpan<byte> buffer, [NotNullWhen(true)] out object? value)
25+
{
26+
if (Utf8Parser.TryParse(buffer, out double parsedValue, out _))
27+
{
28+
value = parsedValue;
29+
return true;
30+
}
31+
32+
value = null;
33+
return false;
34+
}
35+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#nullable enable
2+
using System.Buffers.Text;
3+
using System.Diagnostics.CodeAnalysis;
4+
5+
namespace HotChocolate.Types.Relay;
6+
7+
internal sealed class SingleNodeIdValueSerializer : INodeIdValueSerializer
8+
{
9+
public bool IsSupported(Type type) => type == typeof(float) || type == typeof(float?);
10+
11+
public NodeIdFormatterResult Format(Span<byte> buffer, object value, out int written)
12+
{
13+
if (value is float i)
14+
{
15+
return Utf8Formatter.TryFormat(i, buffer, out written)
16+
? NodeIdFormatterResult.Success
17+
: NodeIdFormatterResult.BufferTooSmall;
18+
}
19+
20+
written = 0;
21+
return NodeIdFormatterResult.InvalidValue;
22+
}
23+
24+
public bool TryParse(ReadOnlySpan<byte> buffer, [NotNullWhen(true)] out object? value)
25+
{
26+
if (Utf8Parser.TryParse(buffer, out float parsedValue, out _))
27+
{
28+
value = parsedValue;
29+
return true;
30+
}
31+
32+
value = null;
33+
return false;
34+
}
35+
}

src/HotChocolate/Core/test/Types.Tests/Types/Relay/OptimizedNodeIdSerializerTests.cs

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,36 @@ public void Format_Int64Id_Legacy_Format()
154154
Assert.Equal("Rm9vCmw2NA==", id);
155155
}
156156

157+
[Fact]
158+
public void Format_DecimalId()
159+
{
160+
var serializer = CreateSerializer("Foo", new DecimalNodeIdValueSerializer());
161+
162+
var id = serializer.Format("Foo", (decimal)6);
163+
164+
Assert.Equal("Rm9vOjY=", id);
165+
}
166+
167+
[Fact]
168+
public void Format_FloatId()
169+
{
170+
var serializer = CreateSerializer("Foo", new SingleNodeIdValueSerializer());
171+
172+
var id = serializer.Format("Foo", (float)6);
173+
174+
Assert.Equal("Rm9vOjY=", id);
175+
}
176+
177+
[Fact]
178+
public void Format_DoubleId()
179+
{
180+
var serializer = CreateSerializer("Foo", new DoubleNodeIdValueSerializer());
181+
182+
var id = serializer.Format("Foo", (double)6);
183+
184+
Assert.Equal("Rm9vOjY=", id);
185+
}
186+
157187
[Fact]
158188
public void Format_Empty_Guid()
159189
{
@@ -363,6 +393,39 @@ public void Parse_Legacy_Int64Id()
363393
Assert.Equal((long)123, id.InternalId);
364394
}
365395

396+
[Fact]
397+
public void Parse_DecimalId()
398+
{
399+
var serializer = CreateSerializer("Foo", new DecimalNodeIdValueSerializer());
400+
401+
var id = serializer.Parse("Rm9vOjEyMw==", typeof(decimal));
402+
403+
Assert.Equal("Foo", id.TypeName);
404+
Assert.Equal((decimal)123, id.InternalId);
405+
}
406+
407+
[Fact]
408+
public void Parse_SingleId()
409+
{
410+
var serializer = CreateSerializer("Foo", new SingleNodeIdValueSerializer());
411+
412+
var id = serializer.Parse("Rm9vOjEyMw==", typeof(float));
413+
414+
Assert.Equal("Foo", id.TypeName);
415+
Assert.Equal((float)123, id.InternalId);
416+
}
417+
418+
[Fact]
419+
public void Parse_DoublelId()
420+
{
421+
var serializer = CreateSerializer("Foo", new DoubleNodeIdValueSerializer());
422+
423+
var id = serializer.Parse("Rm9vOjEyMw==", typeof(double));
424+
425+
Assert.Equal("Foo", id.TypeName);
426+
Assert.Equal((double)123, id.InternalId);
427+
}
428+
366429
[Fact]
367430
public void Parse_CompositeId()
368431
{
@@ -497,7 +560,7 @@ protected override NodeIdFormatterResult Format(Span<byte> buffer, CompositeId v
497560

498561
protected override bool TryParse(ReadOnlySpan<byte> buffer, out CompositeId value)
499562
{
500-
if(TryParseIdPart(buffer, out string a, out var ac) &&
563+
if (TryParseIdPart(buffer, out string a, out var ac) &&
501564
TryParseIdPart(buffer.Slice(ac), out int b, out var bc) &&
502565
TryParseIdPart(buffer.Slice(ac + bc), out Guid c, out var cc) &&
503566
TryParseIdPart(buffer.Slice(ac + bc + cc), out bool d, out _))

0 commit comments

Comments
 (0)