Skip to content

Commit 08043ab

Browse files
authored
Parse bigints in the correct culture (#550)
1 parent 33ac946 commit 08043ab

4 files changed

Lines changed: 66 additions & 5 deletions

File tree

ConsumePlugin/GeneratedJson.fs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,12 @@ module ToGetExtensionMethodJsonParseExtension =
280280
sprintf "Required key '%s' not found on JSON object" ("whiskey")
281281
)
282282
)
283-
| Some node -> System.Numerics.BigInteger.Parse (node.ToJsonString ())
283+
| Some node ->
284+
System.Numerics.BigInteger.Parse (
285+
node.ToJsonString (),
286+
System.Globalization.NumberStyles.Float,
287+
System.Globalization.CultureInfo.InvariantCulture
288+
)
284289

285290
let arg_19 =
286291
match node.["victor"] |> Option.ofObj with
@@ -505,3 +510,28 @@ module ToGetExtensionMethodJsonParseExtension =
505510
Victor = arg_19
506511
Whiskey = arg_20
507512
}
513+
namespace ConsumePlugin
514+
515+
/// Module containing JSON parsing methods for the ContainsABigInt type
516+
[<RequireQualifiedAccess ; CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
517+
module ContainsABigInt =
518+
/// Parse from a JSON node.
519+
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : ContainsABigInt =
520+
let arg_0 =
521+
match node.["bigNum"] |> Option.ofObj with
522+
| None ->
523+
raise (
524+
System.Collections.Generic.KeyNotFoundException (
525+
sprintf "Required key '%s' not found on JSON object" ("bigNum")
526+
)
527+
)
528+
| Some node ->
529+
System.Numerics.BigInteger.Parse (
530+
node.ToJsonString (),
531+
System.Globalization.NumberStyles.Float,
532+
System.Globalization.CultureInfo.InvariantCulture
533+
)
534+
535+
{
536+
BigNum = arg_0
537+
}

ConsumePlugin/JsonRecord.fs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,9 @@ type ToGetExtensionMethod =
8282
[<RequireQualifiedAccess>]
8383
module ToGetExtensionMethod =
8484
let thisModuleWouldClash = 3
85+
86+
[<WoofWare.Myriad.Plugins.JsonParse>]
87+
type ContainsABigInt =
88+
{
89+
BigNum : bigint
90+
}

WoofWare.Myriad.Plugins.Test/TestJsonParse/TestJsonParse.fs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ namespace WoofWare.Myriad.Plugins.Test
22

33
open System
44
open System.Collections.Generic
5+
open System.Globalization
56
open System.Text.Json.Nodes
67
open ConsumePlugin
78
open NUnit.Framework
@@ -118,3 +119,21 @@ module TestJsonParse =
118119
|> JsonNode.Parse
119120
|> SomeEnum.jsonParse
120121
|> shouldEqual expected
122+
123+
[<Test>]
124+
[<NonParallelizable>]
125+
let ``Bigints are parsed in the invariant culture`` () =
126+
let currentCulture = CultureInfo.CurrentCulture
127+
let desiredCulture = CultureInfo.CreateSpecificCulture "for-test"
128+
desiredCulture.NumberFormat.NegativeSign <- "!"
129+
130+
CultureInfo.CurrentCulture <- desiredCulture
131+
132+
try
133+
"""{"bigNum": -3}"""
134+
|> JsonNode.Parse
135+
|> ContainsABigInt.jsonParse
136+
|> _.BigNum
137+
|> shouldEqual (bigint -3)
138+
finally
139+
CultureInfo.CurrentCulture <- currentCulture

WoofWare.Myriad.Plugins/JsonParseGenerator.fs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -455,10 +455,16 @@ module internal JsonParseGenerator =
455455
)
456456
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Map" ; "ofSeq" ])
457457
| BigInt ->
458-
node
459-
|> SynExpr.callMethod "ToJsonString"
460-
|> SynExpr.paren
461-
|> SynExpr.applyFunction (SynExpr.createLongIdent [ "System" ; "Numerics" ; "BigInteger" ; "Parse" ])
458+
SynExpr.createLongIdent [ "System" ; "Numerics" ; "BigInteger" ; "Parse" ]
459+
|> SynExpr.applyTo (
460+
SynExpr.tuple
461+
[
462+
node |> SynExpr.callMethod "ToJsonString"
463+
SynExpr.createLongIdent [ "System" ; "Globalization" ; "NumberStyles" ; "Float" ]
464+
SynExpr.createLongIdent [ "System" ; "Globalization" ; "CultureInfo" ; "InvariantCulture" ]
465+
]
466+
)
467+
462468
| Measure (_measure, primType) ->
463469
parseNumberType options propertyName node primType
464470
|> SynExpr.pipeThroughFunction (Measure.getLanguagePrimitivesMeasure primType)

0 commit comments

Comments
 (0)