git.iko.soy/rowtype-yoga/purescript-yoga-json
on main help sign in
Fix #8
0e8a34cMark Eibes
spago.dhall+1
@@ -19,6 +19,7 @@
19 , "maybe"
19 , "maybe"
20 , "newtype"
20 , "newtype"
21 , "nullable"
21 , "nullable"
22+ , "numbers"
22 , "ordered-collections"
23 , "ordered-collections"
23 , "partial"
24 , "partial"
24 , "prelude"
25 , "prelude"
src/Yoga/JSON.purs+15−7
@@ -41,7 +41,7 @@ import Data.Array.NonEmpty (NonEmptyArray, fromArray, toArray)
41import Data.Bifunctor (lmap)
41import Data.Bifunctor (lmap)
42import Data.BigInt (BigInt)
42import Data.BigInt (BigInt)
43import Data.BigInt as BigInt
43import Data.BigInt as BigInt
44−import Data.Either (Either, hush, note)
44+import Data.Either (Either(..), hush, note)
45import Data.FoldableWithIndex (foldrWithIndex)
45import Data.FoldableWithIndex (foldrWithIndex)
46import Data.Identity (Identity(..))
46import Data.Identity (Identity(..))
47import Data.Int as Int
47import Data.Int as Int
@@ -51,6 +51,7 @@ import Data.Map as Map
51import Data.Maybe (Maybe(..), fromMaybe, fromMaybe', maybe)
51import Data.Maybe (Maybe(..), fromMaybe, fromMaybe', maybe)
52import Data.Newtype (class Newtype)
52import Data.Newtype (class Newtype)
53import Data.Nullable (Nullable, toMaybe, toNullable)
53import Data.Nullable (Nullable, toMaybe, toNullable)
54+import Data.Number as Number
54import Data.Symbol (class IsSymbol, reflectSymbol)
55import Data.Symbol (class IsSymbol, reflectSymbol)
55import Data.Traversable (sequence, traverse)
56import Data.Traversable (sequence, traverse)
56import Data.TraversableWithIndex (traverseWithIndex)
57import Data.TraversableWithIndex (traverseWithIndex)
@@ -185,18 +186,25 @@ readBigInt ∷
185readBigInt = unsafeReadTagged "BigInt"
186readBigInt = unsafeReadTagged "BigInt"
186
187
187instance ReadForeign BigInt where
188instance ReadForeign BigInt where
188− readImpl fValue = tryInt fValue <|> readBigInt fValue <|> tryString fValue
189+ readImpl fValue = tryInt fValue <|> tryNumber fValue <|> readBigInt fValue <|> tryString fValue
189 where
190 where
190 tryInt f = readInt f <#> BigInt.fromInt
191 tryInt f = readInt f <#> BigInt.fromInt
192+ tryNumber f = do
193+ num <- readNumber f
194+ if Number.round num == num then
195+ BigInt.fromNumber num
196+ # note (err $ "Cannot convert Number " <> show num <> " to BigInt")
197+ # except
198+ else
199+ (Left $ err $ "Cannot convert decimal Number " <> show num <> " to BigInt")
200+ # except
191 tryString f = do
201 tryString f = do
192 bi ← readString f
202 bi ← readString f
193 BigInt.fromString bi
203 BigInt.fromString bi
194− # note
204+ # note ( err $ "Cannot convert String " <> bi <> " to BigInt")
195− ( singleton $ ForeignError $ "String " <> bi <>
196− " could not be converted to BigInt"
197− )
198 # except
205 # except
199−
206+ err = pure <<< ForeignError
207+
200instance ReadForeign String where
208instance ReadForeign String where
201 readImpl = readString
209 readImpl = readString
202
210
test/BasicsSpec.purs+4−4
@@ -54,9 +54,9 @@ spec = describe "En- and decoding" $ do
54 $ roundtrips (Map.fromFoldable [(Inty 4 /\ "B"),(Inty 8 /\ "D")])
54 $ roundtrips (Map.fromFoldable [(Inty 4 /\ "B"),(Inty 8 /\ "D")])
55 it "roundtrips BigInt" do
55 it "roundtrips BigInt" do
56 let
56 let
57− inputStr = """{ "number":1, "big": 18014398509481982, "smallBig": 10 }"""
57+ inputStr = """{ "number":1, "big": 18014398509481982, "mediumBig": 1652955871799, "smallBig": 10 }"""
58− expected = """{"smallBig":"10","number":1,"big":"18014398509481982"}"""
58+ expected = """{"smallBig":"10","number":1,"mediumBig":"1652955871799","big":"18014398509481982"}"""
59− parsed ∷ _ ({ number ∷ Int, big ∷ BigInt, smallBig ∷ BigInt })
59+ parsed ∷ _ ({ number ∷ Int, mediumBig :: BigInt, big ∷ BigInt, smallBig ∷ BigInt })
60 parsed = readJSON inputStr
60 parsed = readJSON inputStr
61 stringified = parsed <#> writeJSON
61 stringified = parsed <#> writeJSON
62 stringified `shouldEqual` (Right expected)
62 stringified `shouldEqual` (Right expected)
@@ -65,7 +65,7 @@ spec = describe "En- and decoding" $ do
65 -- let
65 -- let
66 -- smallBig = BigInt.fromInt 10
66 -- smallBig = BigInt.fromInt 10
67 -- big = unsafePartial $ fromJust $ BigInt.fromString "18014398509481982"
67 -- big = unsafePartial $ fromJust $ BigInt.fromString "18014398509481982"
68−
68+
69 -- expected = { big, smallBig }
69 -- expected = { big, smallBig }
70 -- json = spy "json" $ writeJSON expected
70 -- json = spy "json" $ writeJSON expected
71
71
test/GenericsSpec.purs+1
@@ -46,6 +46,7 @@ spec = describe "Generics" $ do
46 writeJSON (ATaggedInt 1) `shouldEqual` """{"type":"ATaggedInt","value":1}"""
46 writeJSON (ATaggedInt 1) `shouldEqual` """{"type":"ATaggedInt","value":1}"""
47 writeJSON (ATaggedString "Abc") `shouldEqual` """{"type":"ATaggedString","value":"Abc"}"""
47 writeJSON (ATaggedString "Abc") `shouldEqual` """{"type":"ATaggedString","value":"Abc"}"""
48
48
49+
49 describe "data HalfEnum = NotEnum Int | IsEnum" do
50 describe "data HalfEnum = NotEnum Int | IsEnum" do
50 it "roundtrips" do
51 it "roundtrips" do
51 roundtrips (NotEnum 1)
52 roundtrips (NotEnum 1)