Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serialization for CalendarSystem. #2

Merged
merged 1 commit into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions Orleans.Serialization.NodaTime.Tests/CalendarSystemCodecTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using NodaTime;
using Orleans.Serialization.Cloning;
using Orleans.Serialization.TestKit;
using Xunit.Abstractions;

namespace Orleans.Serialization.NodaTime.Tests;

public class CalendarSystemCodecTests(ITestOutputHelper output)
: FieldCodecTester<CalendarSystem?, CalendarSystemCodec>(output)
{
protected override void Configure(ISerializerBuilder builder)
{
ArgumentNullException.ThrowIfNull(builder);

builder.Services.AddSingleton<IGeneralizedCopier, CalendarSystemCopier>();
base.Configure(builder);
}

protected override CalendarSystem? CreateValue() => CalendarSystem.Iso;

protected override CalendarSystem?[] TestValues =>
CalendarSystem
.Ids
.Select(CalendarSystem.ForId)
.ToArray();
}
20 changes: 20 additions & 0 deletions Orleans.Serialization.NodaTime.Tests/CalendarSystemCopierTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Linq;
using NodaTime;
using Orleans.Serialization.TestKit;
using Xunit.Abstractions;

namespace Orleans.Serialization.NodaTime.Tests;

public class CalendarSystemCopierTests(ITestOutputHelper output)
: CopierTester<CalendarSystem?, CalendarSystemCopier>(output)
{
protected override bool IsImmutable => true;

protected override CalendarSystem? CreateValue() => CalendarSystem.Iso;

protected override CalendarSystem?[] TestValues =>
CalendarSystem
.Ids
.Select(CalendarSystem.ForId)
.ToArray();
}
10 changes: 5 additions & 5 deletions Orleans.Serialization.NodaTime.Tests/DateTimeZoneCodecTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using NodaTime;
using Orleans.Serialization.Cloning;
Expand All @@ -7,14 +8,13 @@

namespace Orleans.Serialization.NodaTime.Tests;

public class DateTimeZoneCodecTests : FieldCodecTester<DateTimeZone?, DateTimeZoneCodec>
public class DateTimeZoneCodecTests(ITestOutputHelper output)
: FieldCodecTester<DateTimeZone?, DateTimeZoneCodec>(output)
{
public DateTimeZoneCodecTests(ITestOutputHelper output) : base(output)
{
}

protected override void Configure(ISerializerBuilder builder)
{
ArgumentNullException.ThrowIfNull(builder);

builder.Services.AddSingleton<IGeneralizedCopier, DateTimeZoneCopier>();
builder.Services.AddSingleton<IGeneralizedCodec, DateTimeZoneCodec>();
base.Configure(builder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@

namespace Orleans.Serialization.NodaTime.Tests;

public class DateTimeZoneCopierTests: CopierTester<DateTimeZone?, DateTimeZoneCopier>
public class DateTimeZoneCopierTests(ITestOutputHelper output) : CopierTester<DateTimeZone?, DateTimeZoneCopier>(output)
{
public DateTimeZoneCopierTests(ITestOutputHelper output) : base(output)
{
}

protected override bool IsImmutable => true;

protected override DateTimeZone? CreateValue() => DateTimeZone.Utc;
Expand Down
7 changes: 2 additions & 5 deletions Orleans.Serialization.NodaTime.Tests/InstantCodecTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@

namespace Orleans.Serialization.NodaTime.Tests;

public class InstantCodecTests: FieldCodecTester<Instant, InstantCodec>
public class InstantCodecTests(ITestOutputHelper output)
: FieldCodecTester<Instant, InstantCodec>(output)
{
public InstantCodecTests(ITestOutputHelper output) : base(output)
{
}

protected override Instant CreateValue() =>
SystemClock.Instance.GetCurrentInstant();

Expand Down
7 changes: 2 additions & 5 deletions Orleans.Serialization.NodaTime.Tests/InstantCopierTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@

namespace Orleans.Serialization.NodaTime.Tests;

public class InstantCopierTests: CopierTester<Instant, InstantCopier>
public class InstantCopierTests(ITestOutputHelper output)
: CopierTester<Instant, InstantCopier>(output)
{
public InstantCopierTests(ITestOutputHelper output) : base(output)
{
}

protected override Instant CreateValue() =>
SystemClock.Instance.GetCurrentInstant();

Expand Down
8 changes: 2 additions & 6 deletions Orleans.Serialization.NodaTime.Tests/LocalTimeCodecTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,9 @@

namespace Orleans.Serialization.NodaTime.Tests;

public class LocalTimeCodecTests : FieldCodecTester<LocalTime, LocalTimeCodec>
public class LocalTimeCodecTests(ITestOutputHelper output)
: FieldCodecTester<LocalTime, LocalTimeCodec>(output)
{
public LocalTimeCodecTests(ITestOutputHelper output)
: base(output)
{
}

protected override LocalTime CreateValue() => LocalTime.Noon;

protected override LocalTime[] TestValues => new[]
Expand Down
7 changes: 2 additions & 5 deletions Orleans.Serialization.NodaTime.Tests/LocalTimeCopierTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@

namespace Orleans.Serialization.NodaTime.Tests;

public class LocalTimeCopierTests : CopierTester<LocalTime, LocalTimeCopier>
public class LocalTimeCopierTests(ITestOutputHelper output)
: CopierTester<LocalTime, LocalTimeCopier>(output)
{
public LocalTimeCopierTests(ITestOutputHelper output) : base(output)
{
}

protected override LocalTime CreateValue() => LocalTime.Noon;

protected override LocalTime[] TestValues => new[]
Expand Down
7 changes: 2 additions & 5 deletions Orleans.Serialization.NodaTime.Tests/OffsetCodecTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@

namespace Orleans.Serialization.NodaTime.Tests;

public class OffsetCodecTests: FieldCodecTester<Offset, OffsetCodec>
public class OffsetCodecTests(ITestOutputHelper output)
: FieldCodecTester<Offset, OffsetCodec>(output)
{
public OffsetCodecTests(ITestOutputHelper output) : base(output)
{
}

protected override Offset CreateValue() => Offset.Zero;

protected override Offset[] TestValues => new[]
Expand Down
7 changes: 2 additions & 5 deletions Orleans.Serialization.NodaTime.Tests/OffsetCopierTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@

namespace Orleans.Serialization.NodaTime.Tests;

public class OffsetCopierTests: CopierTester<Offset, OffsetCopier>
public class OffsetCopierTests(ITestOutputHelper output)
: CopierTester<Offset, OffsetCopier>(output)
{
public OffsetCopierTests(ITestOutputHelper output) : base(output)
{
}

protected override Offset CreateValue() => Offset.Zero;

protected override Offset[] TestValues => new[]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AnalysisMode>All</AnalysisMode>
<RootNamespace>Orleans.Serialization.NodaTime.Tests</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="xunit" Version="2.6.5" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.6">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<PackageReference Include="coverlet.collector" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Orleans.Serialization.TestKit" Version="7.1.1" />
<PackageReference Include="Microsoft.Orleans.Serialization.TestKit" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
55 changes: 55 additions & 0 deletions Orleans.Serialization.NodaTime/CalendarSystemCodec.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System;
using System.Buffers;
using System.Text;
using NodaTime;
using Orleans.Serialization.Buffers;
using Orleans.Serialization.Codecs;
using Orleans.Serialization.WireProtocol;

namespace Orleans.Serialization.NodaTime;

/// <summary>
/// Serializer for <see cref="CalendarSystem"/>.
/// </summary>
[RegisterSerializer]
public class CalendarSystemCodec : IFieldCodec<CalendarSystem?>
{
public void WriteField<TBufferWriter>(
ref Writer<TBufferWriter> writer,
uint fieldIdDelta,
Type expectedType,
CalendarSystem? value)
where TBufferWriter : IBufferWriter<byte>
{
if (ReferenceCodec.TryWriteReferenceField(ref writer, fieldIdDelta, expectedType, value))
{
return;
}

if (value is null)
{
throw new NotImplementedException();
}

writer.WriteFieldHeader(fieldIdDelta, expectedType, typeof(CalendarSystem), WireType.LengthPrefixed);
var bytes = Encoding.UTF8.GetBytes(value.Id);
writer.WriteVarUInt32((uint)bytes.Length);
writer.Write(bytes);
}

public CalendarSystem? ReadValue<TInput>(ref Reader<TInput> reader, Field field)
{
if (field.WireType == WireType.Reference)
Copy link
Contributor

@ReubenBond ReubenBond Apr 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (field.WireType == WireType.Reference)
{
  return ReferenceCodec.ReadReference<CalendarSystem?, TInput>(ref reader, field);
}

Also, I recommend you remove MarkValueField and use ReferenceCodec.RecordObject instead.

{
return ReferenceCodec.ReadReference<CalendarSystem, TInput>(ref reader, field);
}

field.EnsureWireType(WireType.LengthPrefixed);
var length = reader.ReadVarUInt32();
var buffer = reader.ReadBytes(length);
var id = Encoding.UTF8.GetString(buffer);
var value = CalendarSystem.ForId(id);
ReferenceCodec.RecordObject(reader.Session, value);
return value;
}
}
19 changes: 19 additions & 0 deletions Orleans.Serialization.NodaTime/CalendarSystemCopier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using NodaTime;
using Orleans.Serialization.Cloning;

namespace Orleans.Serialization.NodaTime;

/// <summary>
/// Copier for <see cref="CalendarSystem"/>.
/// </summary>
[RegisterCopier]
public class CalendarSystemCopier: IDeepCopier<CalendarSystem?>, IGeneralizedCopier
{
public CalendarSystem? DeepCopy(CalendarSystem? input, CopyContext context)
{
return input;
}

public bool IsSupportedType(Type type) => typeof(CalendarSystem).IsAssignableFrom(type);
}
33 changes: 14 additions & 19 deletions Orleans.Serialization.NodaTime/DateTimeZoneCodec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ public void WriteField<TBufferWriter>(
DateTimeZone? value)
where TBufferWriter : IBufferWriter<byte>
{
// If the value is null, write it as the null reference.
if (value is null)
if (ReferenceCodec.TryWriteReferenceField(ref writer, fieldIdDelta, expectedType, value))
{
ReferenceCodec.WriteNullReference(ref writer, fieldIdDelta);
return;
}

ReferenceCodec.MarkValueField(writer.Session);
if (value is null)
{
throw new NotImplementedException();
}

writer.WriteFieldHeader(fieldIdDelta, expectedType, typeof(DateTimeZone), WireType.LengthPrefixed);
var bytes = Encoding.UTF8.GetBytes(value.Id);
writer.WriteVarUInt32((uint)(bytes.Length + 1));
Expand All @@ -41,36 +43,29 @@ public void WriteField<TBufferWriter>(

public DateTimeZone? ReadValue<TInput>(ref Reader<TInput> reader, Field field)
{
// This will only be true if the value is null.
if (field.WireType == WireType.Reference)
{
ReferenceCodec.MarkValueField(reader.Session);
var reference = reader.ReadVarUInt32();
if (reference != 0)
{
ThrowInvalidReference(reference);
}

return null;
return ReferenceCodec.ReadReference<DateTimeZone?, TInput>(ref reader, field);
}

ReferenceCodec.MarkValueField(reader.Session);
field.EnsureWireType(WireType.LengthPrefixed);
var length = reader.ReadVarUInt32();
var buffer = reader.ReadBytes(length);
var id = Encoding.UTF8.GetString(buffer.AsSpan(1));
return buffer[0] switch
var value = buffer[0] switch
{
1 => DateTimeZoneProviders.Tzdb[id],
2 => DateTimeZoneProviders.Bcl[id],
_ => throw new UnreachableException(
"Only 1 and 2 are valid values to indicate DateTimeZoneProvider.")
};

ReferenceCodec.RecordObject(reader.Session, value);
return value;
}

public bool IsSupportedType(Type type) =>
typeof(DateTimeZone).IsAssignableFrom(type)
public bool IsSupportedType(Type? type) =>
type is not null
&& typeof(DateTimeZone).IsAssignableFrom(type)
&& typeof(DateTimeZone).Assembly.FullName == type.Assembly.FullName;

private static void ThrowInvalidReference(uint reference) => throw new ReferenceNotFoundException(typeof(DateTimeZone), reference);
}
1 change: 0 additions & 1 deletion Orleans.Serialization.NodaTime/InstantCodec.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Buffers;
using System.Runtime.InteropServices.JavaScript;
using System.Text;
using NodaTime;
using NodaTime.Text;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AnalysisMode>All</AnalysisMode>
<RootNamespace>Orleans.Serialization.NodaTime</RootNamespace>
<Version>0.0.1-alpha</Version>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Orleans.Serialization" Version="7.1.1" />
<PackageReference Include="NodaTime" Version="3.1.9" />
<PackageReference Include="Microsoft.Orleans.Serialization" Version="8.0.0" />
<PackageReference Include="NodaTime" Version="3.1.10" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading