From e3a568f2889cc59dd708f2e6372861c5abe5b5a2 Mon Sep 17 00:00:00 2001 From: Corniel Nobel Date: Fri, 19 Apr 2024 14:42:29 +0200 Subject: [PATCH] Amount used decimal precision to serialize to JSON. --- specs/Qowaiv.Specs/Financial/Amount_specs.cs | 18 +++++++++++++++--- src/Qowaiv/Financial/Amount.cs | 12 +++++++++++- .../Json/Financial/AmountJsonConverter.cs | 4 ++++ .../Json/Mathematics/FractionJsonConverter.cs | 4 ++++ src/Qowaiv/Json/SvoJsonConverter.cs | 10 +++++++++- src/Qowaiv/Mathematics/Fraction.cs | 10 ++++++++++ 6 files changed, 53 insertions(+), 5 deletions(-) diff --git a/specs/Qowaiv.Specs/Financial/Amount_specs.cs b/specs/Qowaiv.Specs/Financial/Amount_specs.cs index 8f4b63e7..af521179 100644 --- a/specs/Qowaiv.Specs/Financial/Amount_specs.cs +++ b/specs/Qowaiv.Specs/Financial/Amount_specs.cs @@ -120,16 +120,24 @@ public void System_Text_JSON_deserialization_min_value() amount.Should().Be(Amount.MinValue); } - [Test] - public void System_Text_JSON_deserialization_max_value() + [TestCase("7.922816251426434E+28")] + [TestCase("79228162514264337593543950335")] + public void System_Text_JSON_deserialization_max_value(string json) { - var amount = System.Text.Json.JsonSerializer.Deserialize("7.922816251426434E+28"); + var amount = System.Text.Json.JsonSerializer.Deserialize(json); amount.Should().Be(Amount.MaxValue); } [TestCase(1234.56, 1234.56)] public void System_Text_JSON_serialization(Amount svo, object json) => JsonTester.Write_System_Text_JSON(svo).Should().Be(json); + + [Test] + public void System_Text_JSON_serialization_Max_value() + { + var json = System.Text.Json.JsonSerializer.Serialize(Amount.MaxValue); + json.Should().Be("79228162514264337593543950335"); + } #endif [TestCase("1234.56", 1234.56)] [TestCase(1234.56, 1234.56)] @@ -141,6 +149,10 @@ public void convention_based_deserialization(object json, Amount svo) public void convention_based_serialization(Amount svo, object json) => JsonTester.Write(svo).Should().Be(json); + [Test] + public void convention_based_serialization_max_value() + => JsonTester.Write(Amount.MaxValue).Should().Be(79228162514264337593543950335M); + [TestCase("Invalid input", typeof(FormatException))] [TestCase("2017-06-11", typeof(FormatException))] public void throws_for_invalid_json(object json, Type exceptionType) diff --git a/src/Qowaiv/Financial/Amount.cs b/src/Qowaiv/Financial/Amount.cs index 7ba7ebda..3d520c8e 100644 --- a/src/Qowaiv/Financial/Amount.cs +++ b/src/Qowaiv/Financial/Amount.cs @@ -130,7 +130,7 @@ namespace Qowaiv.Financial; /// enough to have a representation of -0. /// [Pure] - public double ToJson() => (double)m_Value; + public decimal ToJson() => m_Value; /// Returns a that represents the current Amount for debug purposes. [DebuggerBrowsable(DebuggerBrowsableState.Never)] @@ -147,6 +147,16 @@ public string ToString(string? format, IFormatProvider? formatProvider) [Pure] private string ToXmlString() => ToString(CultureInfo.InvariantCulture); + /// Deserializes the amount from a JSON number. + /// + /// The JSON number to deserialize. + /// + /// + /// The deserialized amount. + /// + [Pure] + public static Amount FromJson(decimal json) => new(json); + /// Deserializes the amount from a JSON number. /// /// The JSON number to deserialize. diff --git a/src/Qowaiv/Json/Financial/AmountJsonConverter.cs b/src/Qowaiv/Json/Financial/AmountJsonConverter.cs index 2b10ad8c..79069b10 100644 --- a/src/Qowaiv/Json/Financial/AmountJsonConverter.cs +++ b/src/Qowaiv/Json/Financial/AmountJsonConverter.cs @@ -16,6 +16,10 @@ public class AmountJsonConverter : SvoJsonConverter [Pure] protected override Amount FromJson(long json) => Amount.FromJson(json); + /// + [Pure] + protected override Amount FromJson(decimal json) => Amount.FromJson(json); + /// [Pure] protected override Amount FromJson(double json) => Amount.FromJson(json); diff --git a/src/Qowaiv/Json/Mathematics/FractionJsonConverter.cs b/src/Qowaiv/Json/Mathematics/FractionJsonConverter.cs index 582eb7b8..67303ee6 100644 --- a/src/Qowaiv/Json/Mathematics/FractionJsonConverter.cs +++ b/src/Qowaiv/Json/Mathematics/FractionJsonConverter.cs @@ -16,6 +16,10 @@ public class FractionJsonConverter : SvoJsonConverter [Pure] protected override Fraction FromJson(long json) => Fraction.FromJson(json); + /// + [Pure] + protected override Fraction FromJson(decimal json) => Fraction.FromJson(json); + /// [Pure] protected override Fraction FromJson(double json) => Fraction.FromJson(json); diff --git a/src/Qowaiv/Json/SvoJsonConverter.cs b/src/Qowaiv/Json/SvoJsonConverter.cs index 50f72703..0b941aab 100644 --- a/src/Qowaiv/Json/SvoJsonConverter.cs +++ b/src/Qowaiv/Json/SvoJsonConverter.cs @@ -109,6 +109,10 @@ public override void WriteAsPropertyName(Utf8JsonWriter writer, TSvo value, Json [Pure] protected virtual TSvo FromJson(long json) => FromJson(json.ToString(CultureInfo.InvariantCulture)); + /// Creates the SVO based on its JSON (decimal) number representation. + [Pure] + protected virtual TSvo FromJson(decimal json) => FromJson((double)json); + /// Creates the SVO based on its JSON (double) number representation. [Pure] protected virtual TSvo FromJson(double json) => FromJson(json.ToString(CultureInfo.InvariantCulture)); @@ -123,10 +127,14 @@ private TSvo ReadNumber(ref Utf8JsonReader reader) { return FromJson(num); } - else if (reader.TryGetDouble(out double dec)) + else if (reader.TryGetDecimal(out decimal dec)) { return FromJson(dec); } + else if (reader.TryGetDouble(out double dbl)) + { + return FromJson(dbl); + } else throw new JsonException($"QowaivJsonConverter does not support writing from {reader.GetString()}."); } } diff --git a/src/Qowaiv/Mathematics/Fraction.cs b/src/Qowaiv/Mathematics/Fraction.cs index caab435c..c2eee543 100644 --- a/src/Qowaiv/Mathematics/Fraction.cs +++ b/src/Qowaiv/Mathematics/Fraction.cs @@ -325,6 +325,16 @@ void ISerializable.GetObjectData(SerializationInfo info, StreamingContext contex [Pure] public string ToJson() => ToString(CultureInfo.InvariantCulture); + /// Deserializes the fraction from a JSON number. + /// + /// The JSON number to deserialize. + /// + /// + /// The deserialized fraction. + /// + [Pure] + public static Fraction FromJson(decimal json) => Cast(json); + /// Deserializes the fraction from a JSON number. /// /// The JSON number to deserialize.