Skip to content

Commit 77b8539

Browse files
authored
Merge pull request #1608 from fsprojects/repo-assist/fix-json-decimal-float-1230-a945dd1e3b1536f6
[Repo Assist] Fix JsonConversions.AsDecimal to handle JsonValue.Float
2 parents cd7a7a0 + addd405 commit 77b8539

2 files changed

Lines changed: 17 additions & 0 deletions

File tree

src/FSharp.Data.Json.Core/JsonConversions.fs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ type JsonConversions =
4747
static member AsDecimal cultureInfo =
4848
function
4949
| JsonValue.Number n -> Some n
50+
| JsonValue.Float f when not (Double.IsInfinity f) && not (Double.IsNaN f) ->
51+
try
52+
Some(decimal f)
53+
with :? OverflowException ->
54+
None
5055
| JsonValue.String s -> TextConversions.AsDecimal cultureInfo s
5156
| _ -> None
5257

tests/FSharp.Data.Tests/JsonProvider.fs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,18 @@ let ``ParseList return result list`` () =
816816
let prov = NumericFields.ParseList(""" [{"a":123}, {"a":987}] """)
817817
prov |> Array.map (fun v -> v.A) |> Array.sort |> should equal [|123M; 987M|]
818818

819+
// Regression test for https://github.com/fsprojects/FSharp.Data/issues/1230
820+
// When a JSON array sample mixes decimal and exponential-notation numbers, the inferred
821+
// type is decimal (because the exponential value is stored as JsonValue.Float and inferred
822+
// as integer, which is then unified with decimal). At runtime, any exponential-notation
823+
// number in the actual JSON must also be convertible to decimal.
824+
type ExponentialDecimalProvider = JsonProvider<"""{"mydata": [1, 2.34567E5, 3.14]}""">
825+
826+
[<Test>]
827+
let ``Decimal inferred from mixed-notation array can parse exponential notation at runtime`` () =
828+
let result = ExponentialDecimalProvider.Parse("""{"mydata": [2, 3.45678E5, 9.01]}""")
829+
result.Mydata |> should equal [| 2M; 345678M; 9.01M |]
830+
819831

820832
type ServiceResponse = JsonProvider<"""[
821833
{ "code": 0, "value": {"generic payload": "yes"}, "message": null},

0 commit comments

Comments
 (0)