Skip to content

Commit

Permalink
JSON-deserialization from decimal.MaxValue (as double) should not fail
Browse files Browse the repository at this point in the history
  • Loading branch information
Corniel committed Apr 19, 2024
1 parent 24b0ea3 commit 00166b0
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 3 deletions.
14 changes: 14 additions & 0 deletions specs/Qowaiv.Specs/Financial/Amount_specs.cs
Expand Up @@ -88,6 +88,20 @@ public class Supports_JSON_serialization
public void System_Text_JSON_deserialization(object json, Amount svo)
=> JsonTester.Read_System_Text_JSON<Amount>(json).Should().Be(svo);

[Test]
public void System_Text_JSON_deserialization_min_value()
{
var amount = System.Text.Json.JsonSerializer.Deserialize<Amount>("-7.922816251426434E+28");
amount.Should().Be(Amount.MinValue);
}

[Test]
public void System_Text_JSON_deserialization_max_value()
{
var amount = System.Text.Json.JsonSerializer.Deserialize<Amount>("7.922816251426434E+28");
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);
Expand Down
18 changes: 16 additions & 2 deletions src/Qowaiv/Cast.cs
Expand Up @@ -12,6 +12,12 @@
/// <summary>Helper class to facilitate <see cref="InvalidCastException"/> on SVO casting.</summary>
internal static class Cast
{
private static class Dbl
{
public const double DecimalMin = (double)decimal.MinValue;
public const double DecimalMax = (double)decimal.MaxValue;
}

/// <summary>Casts from a primitive (not <see cref="string"/>) to a SVO.</summary>
[Pure]
public static TSvo Primitive<TPrimitive, TSvo>(TryCreate<TPrimitive, TSvo> tryCreate, TPrimitive? value)
Expand Down Expand Up @@ -39,9 +45,17 @@ public static TSvo InvariantString<TSvo>(TryParseInvariant<TSvo> tryParse, strin
public static decimal ToDecimal<TSvo>(double value)
=> double.IsNaN(value)
|| double.IsInfinity(value)
|| !value.IsInRange((double)decimal.MinValue, (double)decimal.MaxValue)
|| !value.IsInRange(Dbl.DecimalMin, Dbl.DecimalMax)
? throw Exceptions.InvalidCast<double, TSvo>()
: (decimal)value;
: ToDecimal(value);

[Pure]
private static decimal ToDecimal(double value)
{
if (value >= Dbl.DecimalMax) return decimal.MaxValue;
if (value <= Dbl.DecimalMin) return decimal.MinValue;
return (decimal)value;
}

/// <summary>Casts a <see cref="double"/> to <see cref="int"/> for the SVO.</summary>
[Pure]
Expand Down
4 changes: 3 additions & 1 deletion src/Qowaiv/Qowaiv.csproj
Expand Up @@ -5,9 +5,11 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Version>6.6.1</Version>
<Version>6.6.2</Version>
<PackageId>Qowaiv</PackageId>
<PackageReleaseNotes>
v6.6.2
- JSON-deserialization from decimal.MaxValue (as double) should not fail. #380 (fix)
v6.6.1
- Add missing IParsable interface for Id. #372
v6.6.0
Expand Down

0 comments on commit 00166b0

Please sign in to comment.