diff --git a/src/NodaTime.Serialization.SystemTextJson/NodaConverters.cs b/src/NodaTime.Serialization.SystemTextJson/NodaConverters.cs index dcbc94f..1c8c228 100644 --- a/src/NodaTime.Serialization.SystemTextJson/NodaConverters.cs +++ b/src/NodaTime.Serialization.SystemTextJson/NodaConverters.cs @@ -117,13 +117,19 @@ public static JsonConverter CreateDateTimeZoneConverter(IDateTimeZ /// /// Converter for durations using . /// - public static JsonConverter DurationConverter { get; } + public static JsonConverter DurationConverter => DurationConverterImpl; + + // Note: this only exists because DurationConverter is non-generic. + internal static JsonConverter DurationConverterImpl { get; } = new NodaPatternConverter(DurationPattern.JsonRoundtrip); /// /// Converter for durations using . /// - public static JsonConverter RoundtripDurationConverter { get; } + public static JsonConverter RoundtripDurationConverter => RoundtripDurationConverterImpl; + + // Note: this only exists because RoundtripDurationConverter is non-generic. + internal static JsonConverter RoundtripDurationConverterImpl { get; } = new NodaPatternConverter(DurationPattern.Roundtrip); /// diff --git a/src/NodaTime.Serialization.SystemTextJson/NodaTimeDefaultJsonConverterFactory.cs b/src/NodaTime.Serialization.SystemTextJson/NodaTimeDefaultJsonConverterFactory.cs index e326c6d..43d8378 100644 --- a/src/NodaTime.Serialization.SystemTextJson/NodaTimeDefaultJsonConverterFactory.cs +++ b/src/NodaTime.Serialization.SystemTextJson/NodaTimeDefaultJsonConverterFactory.cs @@ -34,37 +34,35 @@ public NodaTimeDefaultJsonConverterFactory() private static Dictionary CreateConverterDictionary() { - var converters = new Dictionary() - { - { typeof(AnnualDate), NodaConverters.AnnualDateConverter }, - { typeof(AnnualDate?), CreateNullableConverter(NodaConverters.AnnualDateConverter) }, - { typeof(DateInterval), NodaConverters.DateIntervalConverter }, - { typeof(DateTimeZone), NodaConverters.CreateDateTimeZoneConverter(DateTimeZoneProviders.Tzdb) }, - { typeof(Duration), NodaConverters.DurationConverter }, - { typeof(Duration?), CreateNullableConverter((JsonConverter) NodaConverters.DurationConverter) }, - { typeof(Instant), NodaConverters.InstantConverter }, - { typeof(Instant?), CreateNullableConverter(NodaConverters.InstantConverter) }, - { typeof(Interval), NodaConverters.IntervalConverter }, - { typeof(Interval?), CreateNullableConverter(NodaConverters.IntervalConverter) }, - { typeof(LocalDate), NodaConverters.LocalDateConverter }, - { typeof(LocalDate?), CreateNullableConverter(NodaConverters.LocalDateConverter) }, - { typeof(LocalDateTime), NodaConverters.LocalDateTimeConverter }, - { typeof(LocalDateTime?), CreateNullableConverter(NodaConverters.LocalDateTimeConverter) }, - { typeof(LocalTime), NodaConverters.LocalTimeConverter }, - { typeof(LocalTime?), CreateNullableConverter(NodaConverters.LocalTimeConverter) }, - { typeof(Offset), NodaConverters.OffsetConverter }, - { typeof(Offset?), CreateNullableConverter(NodaConverters.OffsetConverter) }, - { typeof(OffsetDate), NodaConverters.OffsetDateConverter }, - { typeof(OffsetDate?), CreateNullableConverter(NodaConverters.OffsetDateConverter) }, - { typeof(OffsetDateTime), NodaConverters.OffsetDateTimeConverter }, - { typeof(OffsetDateTime?), CreateNullableConverter(NodaConverters.OffsetDateTimeConverter) }, - { typeof(OffsetTime), NodaConverters.OffsetTimeConverter }, - { typeof(OffsetTime?), CreateNullableConverter(NodaConverters.OffsetTimeConverter) }, - { typeof(Period), NodaConverters.RoundtripPeriodConverter }, - { typeof(ZonedDateTime), NodaConverters.CreateZonedDateTimeConverter(DateTimeZoneProviders.Tzdb) }, - { typeof(ZonedDateTime?), CreateNullableConverter(NodaConverters.CreateZonedDateTimeConverter(DateTimeZoneProviders.Tzdb)) } - }; + var converters = new Dictionary(); + + // Value types first, using the local function below to handle nullability. + Add(NodaConverters.AnnualDateConverter); + Add(NodaConverters.DurationConverterImpl); + Add(NodaConverters.InstantConverter); + Add(NodaConverters.IntervalConverter); + Add(NodaConverters.LocalDateConverter); + Add(NodaConverters.LocalDateTimeConverter); + Add(NodaConverters.LocalTimeConverter); + Add(NodaConverters.OffsetConverter); + Add(NodaConverters.OffsetDateConverter); + Add(NodaConverters.OffsetDateTimeConverter); + Add(NodaConverters.OffsetTimeConverter); + Add(NodaConverters.CreateZonedDateTimeConverter(DateTimeZoneProviders.Tzdb)); + + // Reference types + converters[typeof(DateInterval)] = NodaConverters.DateIntervalConverter; + converters[typeof(DateTimeZone)] = NodaConverters.CreateDateTimeZoneConverter(DateTimeZoneProviders.Tzdb); + converters[typeof(Period)] = NodaConverters.RoundtripPeriodConverter; return converters; + + // Adds the converter for a value type to the dictionary, + // and a nullable converter for the corresponding nullable value type. + void Add(JsonConverter converter) where T : struct + { + converters[typeof(T)] = converter; + converters[typeof(T?)] = new NodaNullableConverter(converter); + } } /// @@ -81,10 +79,4 @@ internal static JsonConverter GetConverter(Type typeToConvert) => /// public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) => GetConverter(typeToConvert); - - /// - /// Helper to construct a with generic type inference at the call site. - /// - private static NodaNullableConverter CreateNullableConverter(JsonConverter innerConverter) where T : struct - => new NodaNullableConverter(innerConverter); } \ No newline at end of file