-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support for nullable with System.Text.Json source generator
Converters inheriting from `JsonConverter<T>` can only handle `T`, they can't also handle `Nullable<T>` directly if `T` for value types because they don't inherit from `JsonConverter<Nullable<T>>`. Instead, we need to wrap these in a `NodaNullableConverter` that handles the null cases. Fixes #127
- Loading branch information
1 parent
1817df2
commit f386a3e
Showing
4 changed files
with
127 additions
and
10 deletions.
There are no files selected for viewing
43 changes: 43 additions & 0 deletions
43
src/NodaTime.Serialization.SystemTextJson/NodaNullableConverter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// Copyright 2023 The Noda Time Authors. All rights reserved. | ||
// Use of this source code is governed by the Apache License 2.0, | ||
// as found in the LICENSE.txt file. | ||
|
||
using System; | ||
using System.Text.Json; | ||
using System.Text.Json.Serialization; | ||
|
||
namespace NodaTime.Serialization.SystemTextJson; | ||
|
||
internal class NodaNullableConverter<T> : JsonConverter<T?> where T : struct | ||
{ | ||
private readonly JsonConverter<T> _innerConverter; | ||
|
||
public NodaNullableConverter(JsonConverter<T> innerConverter) | ||
{ | ||
Preconditions.CheckNotNull(innerConverter, nameof(innerConverter)); | ||
|
||
_innerConverter = innerConverter; | ||
} | ||
|
||
public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | ||
{ | ||
if (reader.TokenType == JsonTokenType.Null) | ||
{ | ||
return null; | ||
} | ||
|
||
return _innerConverter.Read(ref reader, typeToConvert, options); | ||
} | ||
|
||
public override void Write(Utf8JsonWriter writer, T? value, JsonSerializerOptions options) | ||
{ | ||
if (value is null) | ||
{ | ||
writer.WriteNullValue(); | ||
} | ||
else | ||
{ | ||
_innerConverter.Write(writer, value.Value, options); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
src/NodaTime.Serialization.Test/SystemTextJson/NodaNullableConverterTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Copyright 2019 The Noda Time Authors. All rights reserved. | ||
// Use of this source code is governed by the Apache License 2.0, | ||
// as found in the LICENSE.txt file. | ||
|
||
using System.Text.Json; | ||
using NodaTime.Serialization.SystemTextJson; | ||
using NUnit.Framework; | ||
using static NodaTime.Serialization.Test.SystemText.TestHelper; | ||
|
||
namespace NodaTime.Serialization.Test.SystemText | ||
{ | ||
/// <summary> | ||
/// Tests for the converters exposed in NodaConverters. | ||
/// </summary> | ||
public class NodaNullableConverterTest | ||
{ | ||
[Test] | ||
public void InstantConverter_NotNull() | ||
{ | ||
Instant? value = Instant.FromUtc(2012, 1, 2, 3, 4, 5); | ||
string json = "\"2012-01-02T03:04:05Z\""; | ||
var converter = new NodaTimeDefaultJsonConverterFactory().CreateConverter(typeof(Instant?), new JsonSerializerOptions()); | ||
AssertConversions(value, json, converter); | ||
} | ||
|
||
[Test] | ||
public void InstantConverter_Null() | ||
{ | ||
Instant? value = null; | ||
string json = "null"; | ||
var converter = new NodaTimeDefaultJsonConverterFactory().CreateConverter(typeof(Instant?), new JsonSerializerOptions()); | ||
AssertConversions(value, json, converter); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters