From 3df4ebd6b4d78a20d9fa25cd18d5f737f49890ea Mon Sep 17 00:00:00 2001 From: Andrea Cuneo Date: Mon, 4 Sep 2023 17:31:48 +0200 Subject: [PATCH] feat: add support for Duration type By default, BclTicks (100ns) representation is used. Provides also a Nanosecond precision as opt-in. resolves: #19 --- .../DurationMessagePackFormatterTest.cs | 32 +++++++++++++ .../DurationMessagePackFormatter.cs | 46 +++++++++++++++++++ MessagePack.NodaTime/NodatimeResolver.cs | 2 + 3 files changed, 80 insertions(+) create mode 100644 MessagePack.NodaTime.Tests/NodaTimeTests/DurationMessagePackFormatterTest.cs create mode 100644 MessagePack.NodaTime/DurationMessagePackFormatter.cs diff --git a/MessagePack.NodaTime.Tests/NodaTimeTests/DurationMessagePackFormatterTest.cs b/MessagePack.NodaTime.Tests/NodaTimeTests/DurationMessagePackFormatterTest.cs new file mode 100644 index 0000000..9526137 --- /dev/null +++ b/MessagePack.NodaTime.Tests/NodaTimeTests/DurationMessagePackFormatterTest.cs @@ -0,0 +1,32 @@ +// Copyright (c) ARK LTD. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for +// license information. +using MessagePack.NodaTime.Tests.Helpers; +using NodaTime; +using System; +using Xunit; + +namespace MessagePack.NodaTime.Tests +{ + [Collection("ResolverCollection")] + public class DurationMessagePackFormatterTest + { + [Fact] + public void DurationTest() + { + var d = Duration.FromDays(1); + Assert.Equal(TestTools.Convert(d), d); + } + + [Fact] + public void DurationArrayTest() + { + var p = new Duration[] + { + Duration.FromDays(1), + Duration.FromNanoseconds(100), + }; + Assert.Equal(TestTools.Convert(p), p); + } + } +} diff --git a/MessagePack.NodaTime/DurationMessagePackFormatter.cs b/MessagePack.NodaTime/DurationMessagePackFormatter.cs new file mode 100644 index 0000000..b25641a --- /dev/null +++ b/MessagePack.NodaTime/DurationMessagePackFormatter.cs @@ -0,0 +1,46 @@ +// Copyright (c) ARK LTD. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for +// license information. +using MessagePack.Formatters; + +using NodaTime; +using NodaTime.Text; + +using System; + +namespace MessagePack.NodaTime +{ + public sealed class DurationAsNanosecondsMessagePackFormatter : IMessagePackFormatter + { + public static readonly DurationAsNanosecondsMessagePackFormatter Instance = new DurationAsNanosecondsMessagePackFormatter(); + + public Duration Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) + { + var s = reader.ReadInt64(); + + return Duration.FromNanoseconds(s); + } + + public void Serialize(ref MessagePackWriter writer, Duration value, MessagePackSerializerOptions options) + { + writer.Write(value.ToInt64Nanoseconds()); + } + } + + public sealed class DurationAsBclTicksMessagePackFormatter : IMessagePackFormatter + { + public static readonly DurationAsBclTicksMessagePackFormatter Instance = new DurationAsBclTicksMessagePackFormatter(); + + public Duration Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) + { + var s = reader.ReadInt64(); + + return Duration.FromTicks(s); + } + + public void Serialize(ref MessagePackWriter writer, Duration value, MessagePackSerializerOptions options) + { + writer.Write(value.BclCompatibleTicks); + } + } +} \ No newline at end of file diff --git a/MessagePack.NodaTime/NodatimeResolver.cs b/MessagePack.NodaTime/NodatimeResolver.cs index 4a011bf..ded02cd 100644 --- a/MessagePack.NodaTime/NodatimeResolver.cs +++ b/MessagePack.NodaTime/NodatimeResolver.cs @@ -44,6 +44,7 @@ internal static class NodatimeResolverGetFormatterHelper {typeof(Offset), OffsetMessagePackFormatter.Instance}, {typeof(Period), PeriodAsIntArrayMessagePackFormatter.Instance}, + {typeof(Duration), DurationAsBclTicksMessagePackFormatter.Instance }, {typeof(OffsetDateTime), OffsetDateTimeMessagePackFormatter.Instance}, {typeof(ZonedDateTime), ZonedDateTimeMessagePackFormatter.Instance}, @@ -55,6 +56,7 @@ internal static class NodatimeResolverGetFormatterHelper {typeof(Offset?), new NullableFormatter() }, {typeof(OffsetDateTime?), new NullableFormatter() }, {typeof(ZonedDateTime?), new NullableFormatter() }, + {typeof(Duration?), new NullableFormatter() }, }; internal static object? GetFormatter(Type t)