diff --git a/Open.Serialization.Json.Newtonsoft/Open.Serialization.Json.Newtonsoft.csproj b/Open.Serialization.Json.Newtonsoft/Open.Serialization.Json.Newtonsoft.csproj index d704945..81e330f 100644 --- a/Open.Serialization.Json.Newtonsoft/Open.Serialization.Json.Newtonsoft.csproj +++ b/Open.Serialization.Json.Newtonsoft/Open.Serialization.Json.Newtonsoft.csproj @@ -25,10 +25,11 @@ true snupkg logo.png + README.md - + @@ -36,10 +37,14 @@ True + + True + \ + - + diff --git a/Open.Serialization.Json.Newtonsoft/SerializationExtensions.cs b/Open.Serialization.Json.Newtonsoft/SerializationExtensions.cs index 02b4d69..4b940ec 100644 --- a/Open.Serialization.Json.Newtonsoft/SerializationExtensions.cs +++ b/Open.Serialization.Json.Newtonsoft/SerializationExtensions.cs @@ -8,6 +8,9 @@ namespace Open.Serialization.Json.Newtonsoft; +/// +/// Extensions for Newtonsof.Json serialization with Open.Serialization.Json. +/// public static class SerializationExtensions { /// diff --git a/Open.Serialization.Json.System/CamelCaseJson.cs b/Open.Serialization.Json.System/CamelCaseJson.cs index b4abc23..c9a3dd3 100644 --- a/Open.Serialization.Json.System/CamelCaseJson.cs +++ b/Open.Serialization.Json.System/CamelCaseJson.cs @@ -2,8 +2,14 @@ namespace Open.Serialization.Json.System; +/// +/// Provides default 'camel case' serialization configurations. +/// public static class CamelCaseJson { + /// + /// Default relaxed serializations. + /// public static JsonSerializerOptions Default(bool indent = false) { var options = RelaxedJson.Options(indent); @@ -11,10 +17,9 @@ public static JsonSerializerOptions Default(bool indent = false) return options; } + /// + /// Default relaxed serializations but also ignores null values. + /// public static JsonSerializerOptions Minimal(bool indent = false) - { - var options = Default(indent); - options.IgnoreNullValues = true; - return options; - } + => Default(indent).SetIgnoreNullValues(); } diff --git a/Open.Serialization.Json.System/CaseSensitiveJson.cs b/Open.Serialization.Json.System/CaseSensitiveJson.cs index f9f4920..16c0bbc 100644 --- a/Open.Serialization.Json.System/CaseSensitiveJson.cs +++ b/Open.Serialization.Json.System/CaseSensitiveJson.cs @@ -2,15 +2,20 @@ namespace Open.Serialization.Json.System; +/// +/// Provides default 'case sensitive' serialization configurations. +/// public static class CaseSensitiveJson { + /// + /// Default relaxed serializations. + /// public static JsonSerializerOptions Default(bool indent = false) => RelaxedJson.Options(indent, true); + /// + /// Default relaxed serializations but also ignores null values. + /// public static JsonSerializerOptions Minimal(bool indent = false) - { - var options = Default(indent); - options.IgnoreNullValues = true; - return options; - } + => Default(indent).SetIgnoreNullValues(); } diff --git a/Open.Serialization.Json.System/Converters/JsonDecimalConverter.cs b/Open.Serialization.Json.System/Converters/JsonDecimalConverter.cs index 31ff0af..d80557f 100644 --- a/Open.Serialization.Json.System/Converters/JsonDecimalConverter.cs +++ b/Open.Serialization.Json.System/Converters/JsonDecimalConverter.cs @@ -4,19 +4,30 @@ namespace Open.Serialization.Json.System.Converters; +/// +/// Converter for decimals. +/// public class JsonDecimalConverter : JsonValueConverterBase { + /// + /// Constructs a . + /// protected JsonDecimalConverter() { // Prevent unnecessary replication. } + /// + /// The shared instance of a . + /// public static readonly JsonDecimalConverter Instance = new(); + /// public override decimal Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => reader.GetDecimal(); + /// public override void Write(Utf8JsonWriter writer, decimal value, JsonSerializerOptions options) { if (writer is null) throw new ArgumentNullException(nameof(writer)); diff --git a/Open.Serialization.Json.System/Converters/JsonDecimalRoundingConverter.cs b/Open.Serialization.Json.System/Converters/JsonDecimalRoundingConverter.cs index 06bc3ed..d2757cb 100644 --- a/Open.Serialization.Json.System/Converters/JsonDecimalRoundingConverter.cs +++ b/Open.Serialization.Json.System/Converters/JsonDecimalRoundingConverter.cs @@ -3,9 +3,21 @@ namespace Open.Serialization.Json.System.Converters; +/// +/// Converter for decimals that rounds to a maximum number of digits after the decimal. +/// public class JsonDecimalRoundingConverter : JsonDecimalConverter { + /// + /// The maximum number of digits after the decimal. + /// public int Maximum { get; } + + /// + /// Constructs a . + /// + /// The maximum number of digits after the decimal. + /// If the maximum is less than zero. public JsonDecimalRoundingConverter(int maximum) { if (maximum < 0) @@ -13,9 +25,11 @@ public JsonDecimalRoundingConverter(int maximum) Maximum = maximum; } + /// public override decimal Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => Math.Round(reader.GetDecimal(), Maximum); + /// public override void Write(Utf8JsonWriter writer, decimal value, JsonSerializerOptions options) => base.Write(writer, Math.Round(value, Maximum), options); } diff --git a/Open.Serialization.Json.System/Converters/JsonDoubleRoundingConverter.cs b/Open.Serialization.Json.System/Converters/JsonDoubleRoundingConverter.cs index 9798c04..6773d44 100644 --- a/Open.Serialization.Json.System/Converters/JsonDoubleRoundingConverter.cs +++ b/Open.Serialization.Json.System/Converters/JsonDoubleRoundingConverter.cs @@ -14,9 +14,11 @@ public JsonDoubleRoundingConverter(int maximum) Maximum = maximum; } + /// public override double Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => Math.Round(reader.GetDouble(), Maximum); + /// public override void Write(Utf8JsonWriter writer, double value, JsonSerializerOptions options) { if (writer is null) throw new ArgumentNullException(nameof(writer)); diff --git a/Open.Serialization.Json.System/Converters/JsonNullableDecimalConverter.cs b/Open.Serialization.Json.System/Converters/JsonNullableDecimalConverter.cs index 8d30d58..941ea13 100644 --- a/Open.Serialization.Json.System/Converters/JsonNullableDecimalConverter.cs +++ b/Open.Serialization.Json.System/Converters/JsonNullableDecimalConverter.cs @@ -15,9 +15,11 @@ protected JsonNullableDecimalConverter() public static readonly JsonNullableDecimalConverter Instance = new(); + /// public override bool CanConvert(Type objectType) => objectType == typeof(decimal?) || objectType == typeof(decimal); + /// public override decimal? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => reader.TokenType switch { @@ -26,6 +28,7 @@ public override bool CanConvert(Type objectType) _ => throw new JsonException("Unexpected token type."), }; + /// public override void Write(Utf8JsonWriter writer, decimal? value, JsonSerializerOptions options) { if (writer is null) throw new ArgumentNullException(nameof(writer)); diff --git a/Open.Serialization.Json.System/Converters/JsonNullableDecimalRoundingConverter.cs b/Open.Serialization.Json.System/Converters/JsonNullableDecimalRoundingConverter.cs index 1b4255f..9c86c7e 100644 --- a/Open.Serialization.Json.System/Converters/JsonNullableDecimalRoundingConverter.cs +++ b/Open.Serialization.Json.System/Converters/JsonNullableDecimalRoundingConverter.cs @@ -14,11 +14,13 @@ public JsonNullableDecimalRoundingConverter(int maximum) Maximum = maximum; } + /// public override decimal? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => reader.TokenType == JsonTokenType.Number ? Math.Round(reader.GetDecimal(), Maximum) : base.Read(ref reader, typeToConvert, options); + /// public override void Write(Utf8JsonWriter writer, decimal? value, JsonSerializerOptions options) { if (value.HasValue) diff --git a/Open.Serialization.Json.System/Converters/JsonNullableDoubleRoundingConverter.cs b/Open.Serialization.Json.System/Converters/JsonNullableDoubleRoundingConverter.cs index ea02ade..41f9384 100644 --- a/Open.Serialization.Json.System/Converters/JsonNullableDoubleRoundingConverter.cs +++ b/Open.Serialization.Json.System/Converters/JsonNullableDoubleRoundingConverter.cs @@ -13,11 +13,13 @@ public JsonNullableDoubleRoundingConverter(int maximum) Maximum = maximum; } + /// public override double? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => reader.TokenType == JsonTokenType.Number ? Math.Round(reader.GetDouble(), Maximum) : base.Read(ref reader, typeToConvert, options); + /// public override void Write(Utf8JsonWriter writer, double? value, JsonSerializerOptions options) { if (value.HasValue) diff --git a/Open.Serialization.Json.System/Converters/JsonValueConverterBase.cs b/Open.Serialization.Json.System/Converters/JsonValueConverterBase.cs index aee6ded..f0d66ea 100644 --- a/Open.Serialization.Json.System/Converters/JsonValueConverterBase.cs +++ b/Open.Serialization.Json.System/Converters/JsonValueConverterBase.cs @@ -3,8 +3,11 @@ namespace Open.Serialization.Json.System.Converters; +/// Base class for other json value converters. +/// public abstract class JsonValueConverterBase : JsonConverter { + /// public override bool CanConvert(Type objectType) => objectType == typeof(T); } diff --git a/Open.Serialization.Json.System/Open.Serialization.Json.System.csproj b/Open.Serialization.Json.System/Open.Serialization.Json.System.csproj index f671a5b..283398b 100644 --- a/Open.Serialization.Json.System/Open.Serialization.Json.System.csproj +++ b/Open.Serialization.Json.System/Open.Serialization.Json.System.csproj @@ -29,7 +29,7 @@ - + @@ -44,9 +44,9 @@ - + - + diff --git a/Open.Serialization.Json.System/RelaxedJson.cs b/Open.Serialization.Json.System/RelaxedJson.cs index 43147b3..6bb2086 100644 --- a/Open.Serialization.Json.System/RelaxedJson.cs +++ b/Open.Serialization.Json.System/RelaxedJson.cs @@ -23,10 +23,13 @@ static readonly JsonSerializerOptions DeserializerOptions public static IJsonDeserialize GetDeserializer() => DeserializerOptions.GetSerializer(); + public static IJsonDeserialize GetDeserializer() => DeserializerOptions.GetSerializer(); + public static TValue Deserialize(string? value) => DeserializerOptions.Deserialize(value!); + public static TValue Deserialize(ReadOnlySpan value) => DeserializerOptions.Deserialize(value); } diff --git a/Open.Serialization.Json.System/SerializationsExtensions.cs b/Open.Serialization.Json.System/SerializationsExtensions.cs index b90c503..631548f 100644 --- a/Open.Serialization.Json.System/SerializationsExtensions.cs +++ b/Open.Serialization.Json.System/SerializationsExtensions.cs @@ -9,6 +9,9 @@ namespace Open.Serialization.Json.System; +/// +/// Extensions for System.Text.Json serialization with Open.Serialization.Json. +/// public static class SerializationsExtensions { /// @@ -36,33 +39,70 @@ public static IServiceCollection AddJsonSerializer(this IServiceCollection se return services; } + /// + /// Returns a delegate that can deserialize with the given options. + /// public static Func GetDeserialize(this JsonSerializerOptions options) => json => JsonSerializer.Deserialize(json, options)!; + /// + /// Returns a delegate that can serialze a to with the given options. + /// public static Func GetSerialize(this JsonSerializerOptions options) => item => JsonSerializer.Serialize(item, options)!; + /// + /// Returns a delegate that can serialze a to an with the given options. + /// public static Func GetSerialize(this JsonSerializerOptions options) => item => JsonSerializer.Serialize(item, options); + /// + /// Returns a with the given options. + /// public static IJsonSerializer GetSerializer(this JsonSerializerOptions options) => new JsonSerializerInternal(options); + /// + /// Returns a with the given options. + /// public static IJsonSerializer GetSerializer(this JsonSerializerOptions options) => new JsonSerializerInternal(options).Cast(); + /// + /// Returns a with the given options. + /// public static IJsonSerializerFactory GetSerializerFactory(this JsonSerializerOptions options) => new JsonSerializerFactory(options); + /// + /// Serializes to a using the given options. + /// public static string? Serialize(this JsonSerializerOptions options, TValue value) => JsonSerializer.Serialize(value, options); + + /// + /// Serializes to a using the given options. + /// public static string? Serialize(this JsonSerializerOptions options, object? value) => JsonSerializer.Serialize(value, options); + + /// + /// Deserializes to a using the given options. + /// public static TValue Deserialize(this JsonSerializerOptions options, string value) => JsonSerializer.Deserialize(value, options)!; + + /// + /// Deserializes to a using the given options. + /// public static TValue Deserialize(this JsonSerializerOptions options, ReadOnlySpan value) => JsonSerializer.Deserialize(value, options)!; + /// + /// Returns a shallow copy of the options. + /// + /// If is null. public static JsonSerializerOptions Clone(this JsonSerializerOptions options) { if (options is null) throw new ArgumentNullException(nameof(options)); @@ -94,6 +134,10 @@ public static JsonSerializerOptions Clone(this JsonSerializerOptions options) return clone; } + /// + /// Sets the value. + /// + /// If is null. public static JsonSerializerOptions SetPropertyNameCaseInsensitive(this JsonSerializerOptions options, bool value) { if (options is null) throw new ArgumentNullException(nameof(options)); @@ -103,15 +147,32 @@ public static JsonSerializerOptions SetPropertyNameCaseInsensitive(this JsonSeri return options; } - public static JsonSerializerOptions SetIgnoreNullValues(this JsonSerializerOptions options, bool value = true) + /// + /// Sets the value. + /// A of sets the condtion to .
+ /// A of sets the condtion to . + ///
+ /// If is null. + public static JsonSerializerOptions SetIgnoreNullValues(this JsonSerializerOptions options, bool value) + => SetIgnoreNullValues(options, value ? JsonIgnoreCondition.WhenWritingNull : JsonIgnoreCondition.Never); + + /// + /// Sets the value, defaulting to ignore nulls. + /// + /// If is null. + public static JsonSerializerOptions SetIgnoreNullValues(this JsonSerializerOptions options, JsonIgnoreCondition value = JsonIgnoreCondition.WhenWritingNull) { if (options is null) throw new ArgumentNullException(nameof(options)); Contract.EndContractBlock(); - options.IgnoreNullValues = value; + options.DefaultIgnoreCondition = value; return options; } + /// + /// Sets the value to . + /// + /// If is null. public static JsonSerializerOptions UseUnsafeEncoding(this JsonSerializerOptions options) { if (options is null) throw new ArgumentNullException(nameof(options)); @@ -121,6 +182,10 @@ public static JsonSerializerOptions UseUnsafeEncoding(this JsonSerializerOptions return options; } + /// + /// Adds a converter to the options. + /// + /// If is null. public static JsonSerializerOptions AddConverter(this JsonSerializerOptions options, JsonConverter converter) { if (options is null) throw new ArgumentNullException(nameof(options)); @@ -155,6 +220,10 @@ static JsonSerializerOptions RoundNullableDoublesCore(this JsonSerializerOptions }; } + /// + /// Adds a special converter that rounds double values to the level. + /// + /// If is null. public static JsonSerializerOptions RoundDoubles(this JsonSerializerOptions options, int maxDecimals) { if (options is null) throw new ArgumentNullException(nameof(options)); @@ -165,6 +234,10 @@ public static JsonSerializerOptions RoundDoubles(this JsonSerializerOptions opti .RoundNullableDoublesCore(maxDecimals); } + /// + /// Adds a special converter that normalizes decimals so they are consistent regardless of trailing zeros. + /// + /// If is null. public static JsonSerializerOptions NormalizeDecimals(this JsonSerializerOptions options) { if (options is null) throw new ArgumentNullException(nameof(options)); @@ -223,6 +296,10 @@ static JsonSerializerOptions RoundNullableDecimalsCore(this JsonSerializerOption }; } + /// + /// Adds a special converter that rounds decimal values to the level. + /// + /// If is null. public static JsonSerializerOptions RoundDecimals(this JsonSerializerOptions options, int maxDecimals) { if (options is null) throw new ArgumentNullException(nameof(options)); diff --git a/Open.Serialization.Json.Utf8Json/Open.Serialization.Json.Utf8Json.csproj b/Open.Serialization.Json.Utf8Json/Open.Serialization.Json.Utf8Json.csproj index 562a935..a5851e4 100644 --- a/Open.Serialization.Json.Utf8Json/Open.Serialization.Json.Utf8Json.csproj +++ b/Open.Serialization.Json.Utf8Json/Open.Serialization.Json.Utf8Json.csproj @@ -25,10 +25,11 @@ true snupkg logo.png + README.md - + @@ -36,10 +37,14 @@ True + + True + \ + - + diff --git a/Open.Serialization.Json/Open.Serialization.Json.csproj b/Open.Serialization.Json/Open.Serialization.Json.csproj index c2db2a1..2b15588 100644 --- a/Open.Serialization.Json/Open.Serialization.Json.csproj +++ b/Open.Serialization.Json/Open.Serialization.Json.csproj @@ -25,10 +25,11 @@ true snupkg logo.png + README.md - + @@ -36,6 +37,10 @@ True + + True + \ + diff --git a/Open.Serialization.Tests/DefaultImplementationTests.cs b/Open.Serialization.Tests/DefaultImplementationTests.cs index f5d143b..bbeb062 100644 --- a/Open.Serialization.Tests/DefaultImplementationTests.cs +++ b/Open.Serialization.Tests/DefaultImplementationTests.cs @@ -2,38 +2,38 @@ using System; using Xunit; -namespace Open.Serialization.Tests +namespace Open.Serialization.Tests; + +public static class DefaultImplementationTests { - public static class DefaultImplementationTests + class A : IDeserializeObject + { + public object Deserialize(string value, Type type) => 1; + } + + class B : A + { + [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822:Mark members as static")] + public T Deserialize(string _) => default; + } + + class C : B, IDeserializeObject { - class A : IDeserializeObject - { - public object Deserialize(string value, Type type) => 1; - } - - class B : A - { - public T Deserialize(string _) => default; - } - - class C : B, IDeserializeObject - { - } - - [Fact] - public static void DefaultImplementation() - { - IDeserializeObject a1 = new A(); - Assert.Equal(1, a1.Deserialize("0")); - - var b1 = new B(); - Assert.Equal(0, b1.Deserialize("0")); - - IDeserializeObject b2 = new B(); - Assert.Equal(1, b2.Deserialize("0")); - - var c1 = new C(); - Assert.Equal(0, c1.Deserialize("0")); - } + } + + [Fact] + public static void DefaultImplementation() + { + IDeserializeObject a1 = new A(); + Assert.Equal(1, a1.Deserialize("0")); + + var b1 = new B(); + Assert.Equal(0, b1.Deserialize("0")); + + IDeserializeObject b2 = new B(); + Assert.Equal(1, b2.Deserialize("0")); + + var c1 = new C(); + Assert.Equal(0, c1.Deserialize("0")); } } diff --git a/Open.Serialization.Tests/Newtonsoft/JsonExtensionTests.cs b/Open.Serialization.Tests/Newtonsoft/JsonExtensionTests.cs index 442faf6..ef98a07 100644 --- a/Open.Serialization.Tests/Newtonsoft/JsonExtensionTests.cs +++ b/Open.Serialization.Tests/Newtonsoft/JsonExtensionTests.cs @@ -3,131 +3,130 @@ using System; using Xunit; -namespace Open.Serialization.Tests.Newtonsoft +namespace Open.Serialization.Tests.Newtonsoft; + +public static class JsonExtensionTests { - public static class JsonExtensionTests + [Fact] + public static void ValidateJsonExtensions() { - [Fact] - public static void ValidateJsonExtensions() { - { - var basic = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }; - var serializer = basic - .NormalizeDecimals() - .RoundDoubles(2) - .RoundDecimals(2) - .GetSerializer(); - - var json = serializer.Serialize(SampleModel.Instance); - var obj = serializer.Deserialize(json); - Assert.NotNull(obj); - } + var basic = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }; + var serializer = basic + .NormalizeDecimals() + .RoundDoubles(2) + .RoundDecimals(2) + .GetSerializer(); + + var json = serializer.Serialize(SampleModel.Instance); + var obj = serializer.Deserialize(json); + Assert.NotNull(obj); + } - { - var basic = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }; - var serializer = basic - .RoundDoubles(2) - .RoundDecimals(2) - .GetSerializer(); - - var json = serializer.Serialize(SampleModel.Instance); - var obj = serializer.Deserialize(json); - Assert.NotNull(obj); - } + { + var basic = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }; + var serializer = basic + .RoundDoubles(2) + .RoundDecimals(2) + .GetSerializer(); + + var json = serializer.Serialize(SampleModel.Instance); + var obj = serializer.Deserialize(json); + Assert.NotNull(obj); + } - { - var basic = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }; - var serializer = basic - .RoundDecimals(2) - .RoundDoubles(2) - .GetSerializer(); - - var json = serializer.Serialize(SampleModel.Instance); - var obj = serializer.Deserialize(json); - Assert.NotNull(obj); - } + { + var basic = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }; + var serializer = basic + .RoundDecimals(2) + .RoundDoubles(2) + .GetSerializer(); + + var json = serializer.Serialize(SampleModel.Instance); + var obj = serializer.Deserialize(json); + Assert.NotNull(obj); } + } - [Fact] - public static void ValidateDecimals() + [Fact] + public static void ValidateDecimals() + { + const decimal sample = 0.234567890123456789012345m; { - const decimal sample = 0.234567890123456789012345m; - { - var serializer = CamelCaseJson - .Default() - .NormalizeDecimals() - .GetSerializer(); + var serializer = CamelCaseJson + .Default() + .NormalizeDecimals() + .GetSerializer(); + { + var model = new SampleModel { - var model = new SampleModel - { - DecimalValue1 = sample - }; - var json = serializer.Serialize(model); - Assert.Equal(sample, serializer.Deserialize(json).DecimalValue1); - } + DecimalValue1 = sample + }; + var json = serializer.Serialize(model); + Assert.Equal(sample, serializer.Deserialize(json).DecimalValue1); + } + { + var model = new SampleModel { - var model = new SampleModel - { - NullableDecimalValue = sample - }; - var json = serializer.Serialize(model); - Assert.Equal(sample, serializer.Deserialize(json).NullableDecimalValue); - } + NullableDecimalValue = sample + }; + var json = serializer.Serialize(model); + Assert.Equal(sample, serializer.Deserialize(json).NullableDecimalValue); } + } - { - var serializer = CamelCaseJson - .Default() - .RoundDecimals(2) - .GetSerializer(); + { + var serializer = CamelCaseJson + .Default() + .RoundDecimals(2) + .GetSerializer(); - var sample2 = Math.Round(sample, 2); + var sample2 = Math.Round(sample, 2); + { + var model = new SampleModel { - var model = new SampleModel - { - DecimalValue1 = sample - }; - var json = serializer.Serialize(model); - Assert.Equal(sample2, serializer.Deserialize(json).DecimalValue1); - } + DecimalValue1 = sample + }; + var json = serializer.Serialize(model); + Assert.Equal(sample2, serializer.Deserialize(json).DecimalValue1); + } + { + var model = new SampleModel { - var model = new SampleModel - { - NullableDecimalValue = sample - }; - var json = serializer.Serialize(model); - Assert.Equal(sample2, serializer.Deserialize(json).NullableDecimalValue); - } + NullableDecimalValue = sample + }; + var json = serializer.Serialize(model); + Assert.Equal(sample2, serializer.Deserialize(json).NullableDecimalValue); } + } - { - var serializer = CamelCaseJson - .Default() - .GetSerializer(); + { + var serializer = CamelCaseJson + .Default() + .GetSerializer(); - const int sample3 = 1; + const int sample3 = 1; + { + var model = new SampleModel { - var model = new SampleModel - { - DecimalValue1 = sample3 - }; - var json = serializer.Serialize(model); - Assert.Equal(sample3, serializer.Deserialize(json).DecimalValue1); - } + DecimalValue1 = sample3 + }; + var json = serializer.Serialize(model); + Assert.Equal(sample3, serializer.Deserialize(json).DecimalValue1); + } + { + var model = new SampleModel { - var model = new SampleModel - { - NullableDecimalValue = sample3 - }; - var json = serializer.Serialize(model); - Assert.Equal(sample3, serializer.Deserialize(json).NullableDecimalValue); - } + NullableDecimalValue = sample3 + }; + var json = serializer.Serialize(model); + Assert.Equal(sample3, serializer.Deserialize(json).NullableDecimalValue); } } } diff --git a/Open.Serialization.Tests/Open.Serialization.Tests.csproj b/Open.Serialization.Tests/Open.Serialization.Tests.csproj index 3528f0c..588a2b7 100644 --- a/Open.Serialization.Tests/Open.Serialization.Tests.csproj +++ b/Open.Serialization.Tests/Open.Serialization.Tests.csproj @@ -1,19 +1,20 @@  - netcoreapp3.1 + net6.0 false - + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Open.Serialization.Tests/ParityTests.cs b/Open.Serialization.Tests/ParityTests.cs index 87b903e..ab1b6d1 100644 --- a/Open.Serialization.Tests/ParityTests.cs +++ b/Open.Serialization.Tests/ParityTests.cs @@ -4,72 +4,71 @@ using System.Threading.Tasks; using Xunit; -namespace Open.Serialization.Tests +namespace Open.Serialization.Tests; + +public static class ParityTests { - public static class ParityTests + [Fact] + public static async Task EnsureBasicParity() { - [Fact] - public static async Task EnsureBasicParity() { - { - var newtonsoftFactory = new Json.Newtonsoft.JsonSerializerFactory(Json.Newtonsoft.CamelCaseJson.Minimal(true)); - var systemFactory = new Json.System.JsonSerializerFactory(Json.System.CamelCaseJson.Minimal(true)); + var newtonsoftFactory = new Json.Newtonsoft.JsonSerializerFactory(Json.Newtonsoft.CamelCaseJson.Minimal(true)); + var systemFactory = new Json.System.JsonSerializerFactory(Json.System.CamelCaseJson.Minimal(true)); - await CompareFactories(newtonsoftFactory, systemFactory); - } + await CompareFactories(newtonsoftFactory, systemFactory); + } - { - var newtonsoftFactory = new Json.Newtonsoft.JsonSerializerFactory(); - var systemFactory = new Json.System.JsonSerializerFactory(); + { + var newtonsoftFactory = new Json.Newtonsoft.JsonSerializerFactory(); + var systemFactory = new Json.System.JsonSerializerFactory(); - await CompareFactories(newtonsoftFactory, systemFactory); - } + await CompareFactories(newtonsoftFactory, systemFactory); + } - { - var newtonsoftFactory = new Json.Newtonsoft.JsonSerializerFactory(Json.Newtonsoft.CamelCaseJson.Minimal(true)); - var utf8JsonFactory = new Json.Utf8Json.JsonSerializerFactory(Utf8Json.Resolvers.StandardResolver.ExcludeNullCamelCase, true); + { + var newtonsoftFactory = new Json.Newtonsoft.JsonSerializerFactory(Json.Newtonsoft.CamelCaseJson.Minimal(true)); + var utf8JsonFactory = new Json.Utf8Json.JsonSerializerFactory(Utf8Json.Resolvers.StandardResolver.ExcludeNullCamelCase, true); - await CompareFactories(newtonsoftFactory, utf8JsonFactory); + await CompareFactories(newtonsoftFactory, utf8JsonFactory); - var ns = newtonsoftFactory.GetObjectSerializer(); - var utf8 = utf8JsonFactory.GetObjectSerializer(); + var ns = newtonsoftFactory.GetObjectSerializer(); + var utf8 = utf8JsonFactory.GetObjectSerializer(); - var instance = SampleModel.Instance; - var type = SampleModel.Instance.GetType(); - var expected = ns.Serialize(instance, type); - var actual = utf8.Serialize(instance, type); - if (Debugger.IsAttached) Debug.Assert(expected == actual); - Assert.Equal(expected, actual); - } + var instance = SampleModel.Instance; + var type = SampleModel.Instance.GetType(); + var expected = ns.Serialize(instance, type); + var actual = utf8.Serialize(instance, type); + if (Debugger.IsAttached) Debug.Assert(expected == actual); + Assert.Equal(expected, actual); } + } - static async ValueTask CompareFactories(IJsonSerializerFactory expectedFactory, IJsonSerializerFactory actualFactory) - { - var expectedSerializer = expectedFactory.GetSerializer(); - var actualSerializer = actualFactory.GetSerializer(); + static async ValueTask CompareFactories(IJsonSerializerFactory expectedFactory, IJsonSerializerFactory actualFactory) + { + var expectedSerializer = expectedFactory.GetSerializer(); + var actualSerializer = actualFactory.GetSerializer(); - await CompareSerializer(SampleModel.Instance); - await CompareSerializer(SampleModel.DecimalList); - await CompareSerializer(SampleModel.DecimalLookup); - await CompareSerializer(SampleModel.DoubleLookup); - expectedFactory.GetSerializer().Deserialize(actualSerializer.Serialize(SampleModel.Instance)); + await CompareSerializer(SampleModel.Instance); + await CompareSerializer(SampleModel.DecimalList); + await CompareSerializer(SampleModel.DecimalLookup); + await CompareSerializer(SampleModel.DoubleLookup); + expectedFactory.GetSerializer().Deserialize(actualSerializer.Serialize(SampleModel.Instance)); - async ValueTask CompareSerializer(T instance) - { - var expected = expectedSerializer.Serialize(instance); - var actual = actualSerializer.Serialize(instance); - if (Debugger.IsAttached) Debug.Assert(expected == actual); - Assert.Equal(expected, actual); + async ValueTask CompareSerializer(T instance) + { + var expected = expectedSerializer.Serialize(instance); + var actual = actualSerializer.Serialize(instance); + if (Debugger.IsAttached) Debug.Assert(expected == actual); + Assert.Equal(expected, actual); - using var stream = new MemoryStream(); - await actualSerializer.SerializeAsync(stream, instance); + using var stream = new MemoryStream(); + await actualSerializer.SerializeAsync(stream, instance); - stream.Position = 0; - var result = await actualSerializer.DeserializeAsync(stream); - var actualAsync = actualSerializer.Serialize(result); - if (Debugger.IsAttached) Debug.Assert(expected == actualAsync); - Assert.Equal(expected, actual); - } + stream.Position = 0; + var result = await actualSerializer.DeserializeAsync(stream); + var actualAsync = actualSerializer.Serialize(result); + if (Debugger.IsAttached) Debug.Assert(expected == actualAsync); + Assert.Equal(expected, actual); } } } diff --git a/Open.Serialization.Tests/SampleModel.cs b/Open.Serialization.Tests/SampleModel.cs index 8101330..28b9953 100644 --- a/Open.Serialization.Tests/SampleModel.cs +++ b/Open.Serialization.Tests/SampleModel.cs @@ -1,37 +1,36 @@ using System.Collections.Generic; -namespace Open.Serialization.Tests +namespace Open.Serialization.Tests; + +public class SampleModel { - public class SampleModel - { - public static IList DecimalList = new decimal?[] { 3.45678m, 45.6789m, null }; + public static readonly IReadOnlyList DecimalList = new decimal?[] { 3.45678m, 45.6789m, null }; - public static IDictionary DecimalLookup { get; set; } = new SortedDictionary { { "NumberOne", 1.2345m }, { "NumberTwo", 2345.6m } }; + public static IDictionary DecimalLookup { get; set; } = new SortedDictionary { { "NumberOne", 1.2345m }, { "NumberTwo", 2345.6m } }; - public static IDictionary DoubleLookup { get; set; } = new SortedDictionary { { "NumberOne", 1.2345 }, { "NumberTwo", 2345.6 } }; + public static IDictionary DoubleLookup { get; set; } = new SortedDictionary { { "NumberOne", 1.2345 }, { "NumberTwo", 2345.6 } }; - public int IntegerValue { get; set; } = 11; + public int IntegerValue { get; set; } = 11; - public double DoubleValue { get; set; } = 1.2345678901234567; - public decimal DecimalValue1 { get; set; } = 1.2345678901234567m; + public double DoubleValue { get; set; } = 1.2345678901234567; + public decimal DecimalValue1 { get; set; } = 1.2345678901234567m; - public decimal DecimalValue2 { get; set; } = 1.2345000m; - public decimal DecimalValue3 { get; set; } = 11.000m; + public decimal DecimalValue2 { get; set; } = 1.2345000m; + public decimal DecimalValue3 { get; set; } = 11.000m; - public string StringValue { get; set; } = "Hello"; - public string StringValueNull { get; set; } = null; + public string StringValue { get; set; } = "Hello"; + public string StringValueNull { get; set; } = null; - public int? NullableIntegerValue { get; set; } = 11; - public int? NullableIntegerNull { get; set; } = null; + public int? NullableIntegerValue { get; set; } = 11; + public int? NullableIntegerNull { get; set; } = null; - public double? NullableDoubleNull { get; set; } = null; + public double? NullableDoubleNull { get; set; } = null; - public double? NullableDoubleValue { get; set; } = 1.2345678901234567; - public decimal? NullableDecimalValue { get; set; } = 1.2345678901234567m; - public decimal? NullableDecimalNull { get; set; } = null; + public double? NullableDoubleValue { get; set; } = 1.2345678901234567; + public decimal? NullableDecimalValue { get; set; } = 1.2345678901234567m; + public decimal? NullableDecimalNull { get; set; } = null; - public SampleModel Child { get; set; } + public SampleModel Child { get; set; } - public static readonly SampleModel Instance = new SampleModel() { Child = new SampleModel() }; - } + public static readonly SampleModel Instance = new() { Child = new SampleModel() }; } diff --git a/Open.Serialization.Tests/System/JsonExtensionTests.cs b/Open.Serialization.Tests/System/JsonExtensionTests.cs index d31c749..293f567 100644 --- a/Open.Serialization.Tests/System/JsonExtensionTests.cs +++ b/Open.Serialization.Tests/System/JsonExtensionTests.cs @@ -1,67 +1,67 @@ using Open.Serialization.Json.System; using Open.Serialization.Json.System.Converters; using System.Text.Json; +using System.Text.Json.Serialization; using Xunit; -namespace Open.Serialization.Tests.System +namespace Open.Serialization.Tests.System; + +public static class JsonExtensionTests { - public static class JsonExtensionTests + [Fact] + public static void ValidateJsonExtensions() { - [Fact] - public static void ValidateJsonExtensions() - { - var basic = new JsonSerializerOptions() { IgnoreNullValues = true }; - var converter = basic.GetConverter(typeof(decimal)); - Assert.NotNull(converter); + var basic = new JsonSerializerOptions() { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }; + var converter = basic.GetConverter(typeof(decimal)); + Assert.NotNull(converter); - converter = basic.GetConverter(typeof(decimal?)); - Assert.NotNull(converter); // Was null in previous versions. + converter = basic.GetConverter(typeof(decimal?)); + Assert.NotNull(converter); // Was null in previous versions. - basic.Converters.Add(JsonDecimalConverter.Instance); - converter = basic.GetConverter(typeof(decimal)); - Assert.True(converter is JsonDecimalConverter); + basic.Converters.Add(JsonDecimalConverter.Instance); + converter = basic.GetConverter(typeof(decimal)); + Assert.True(converter is JsonDecimalConverter); - basic.RoundDecimals(2); - converter = basic.GetConverter(typeof(decimal)); - Assert.True(converter is JsonDecimalRoundingConverter); + basic.RoundDecimals(2); + converter = basic.GetConverter(typeof(decimal)); + Assert.True(converter is JsonDecimalRoundingConverter); - basic - .NormalizeDecimals() - .RoundDoubles(2) - .RoundDecimals(2); + basic + .NormalizeDecimals() + .RoundDoubles(2) + .RoundDecimals(2); - var serializer = basic.GetSerializer(); - var json = serializer.Serialize(SampleModel.Instance); - var obj = serializer.Deserialize(json); - Assert.NotNull(obj); - } + var serializer = basic.GetSerializer(); + var json = serializer.Serialize(SampleModel.Instance); + var obj = serializer.Deserialize(json); + Assert.NotNull(obj); + } - [Fact] - public static void ValidateDecimals() - { - const decimal sample = 1.234567890123456789012345m; - var basic = new JsonSerializerOptions() { IgnoreNullValues = true }; - var serializer = basic - .NormalizeDecimals() - .GetSerializer(); + [Fact] + public static void ValidateDecimals() + { + const decimal sample = 1.234567890123456789012345m; + var basic = new JsonSerializerOptions() { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }; + var serializer = basic + .NormalizeDecimals() + .GetSerializer(); + { + var model = new SampleModel { - var model = new SampleModel - { - DecimalValue1 = sample - }; - var json = serializer.Serialize(model); - Assert.Equal(sample, serializer.Deserialize(json).DecimalValue1); - } + DecimalValue1 = sample + }; + var json = serializer.Serialize(model); + Assert.Equal(sample, serializer.Deserialize(json).DecimalValue1); + } + { + var model = new SampleModel { - var model = new SampleModel - { - NullableDecimalValue = sample - }; - var json = serializer.Serialize(model); - Assert.Equal(sample, serializer.Deserialize(json).NullableDecimalValue); - } + NullableDecimalValue = sample + }; + var json = serializer.Serialize(model); + Assert.Equal(sample, serializer.Deserialize(json).NullableDecimalValue); } } } diff --git a/Open.Serialization/Open.Serialization.csproj b/Open.Serialization/Open.Serialization.csproj index 06c18ac..fd87d4e 100644 --- a/Open.Serialization/Open.Serialization.csproj +++ b/Open.Serialization/Open.Serialization.csproj @@ -25,10 +25,12 @@ true snupkg logo.png + true + README.md - + @@ -36,6 +38,10 @@ True + + True + \ + diff --git a/Open.Serialization/Open.Serialization.xml b/Open.Serialization/Open.Serialization.xml index d9624e9..43227a3 100644 --- a/Open.Serialization/Open.Serialization.xml +++ b/Open.Serialization/Open.Serialization.xml @@ -41,7 +41,7 @@ - Default extensions for pure serialization interfaces. + Default extensions for pure serialization interfaces.