argo 0.2021.10.18 → 0.2021.10.19
raw patch · 9 files changed
+131/−50 lines, 9 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Argo: type Pair = Pair String Value
- Argo: type Value = Value
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue Argo.Type.Value
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue Argo.Type.Value
- Argo.Type: type Pair = Pair String Value
- Argo.Type: type Value = Value
+ Argo: data Pair k v
+ Argo: data Value
+ Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue Argo.Type.Value.Value
+ Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue Argo.Type.Value.Value
+ Argo.Class.ToValue: negateNumber :: Number -> Number
- Argo: pattern Pair :: Text -> Value -> Pair
+ Argo: pattern Pair :: Text -> Value -> Pair String Value
- Argo: type Object = Array Int Pair
+ Argo: type Object = Array Int (Pair String Value)
- Argo.Pattern: pattern Pair :: Text -> Value -> Pair
+ Argo.Pattern: pattern Pair :: Text -> Value -> Pair String Value
- Argo.Type: type Object = Array Int Pair
+ Argo.Type: type Object = Array Int (Pair String Value)
Files
- CHANGELOG.md +4/−0
- README.md +6/−0
- argo.cabal +2/−1
- source/library/Argo.hs +11/−9
- source/library/Argo/Class/FromValue.hs +9/−10
- source/library/Argo/Class/ToValue.hs +13/−5
- source/library/Argo/Pattern.hs +7/−7
- source/library/Argo/Type.hs +2/−6
- source/test-suite/Main.hs +77/−12
+ CHANGELOG.md view
@@ -0,0 +1,4 @@+# Change log++Argo follows the [Package Versioning Policy](https://pvp.haskell.org). You can+find release notes [on GitHub](https://github.com/tfausak/argo/releases).
+ README.md view
@@ -0,0 +1,6 @@+# Argo++[](https://github.com/tfausak/argo/actions/workflows/ci.yaml)+[](https://hackage.haskell.org/package/argo)++:sailboat: Parse and render JSON.
argo.cabal view
@@ -1,11 +1,12 @@ cabal-version: 2.2 name: argo-version: 0.2021.10.18+version: 0.2021.10.19 build-type: Simple category: JSON description: Argo parses and renders JSON.+extra-source-files: CHANGELOG.md README.md license-file: LICENSE.txt license: MIT maintainer: Taylor Fausak
source/library/Argo.hs view
@@ -1,17 +1,17 @@ {-# LANGUAGE PatternSynonyms #-} module Argo- ( Type.Value+ ( Value.Value+ ( Pattern.Null+ , Pattern.Boolean+ , Pattern.Number+ , Pattern.String+ , Pattern.Array+ , Pattern.Object+ ) , Type.Array- , Type.Pair+ , Pair.Pair(Pattern.Pair) , Type.Object- , pattern Pattern.Null- , pattern Pattern.Boolean- , pattern Pattern.Number- , pattern Pattern.String- , pattern Pattern.Array- , pattern Pattern.Object- , pattern Pattern.Pair , Encode.encode , Decode.decode , FromValue.FromValue(fromValue)@@ -28,3 +28,5 @@ import qualified Argo.QuasiQuoter as QuasiQuoter import qualified Argo.Result as Result import qualified Argo.Type as Type+import qualified Argo.Type.Pair as Pair+import qualified Argo.Type.Value as Value
source/library/Argo/Class/FromValue.hs view
@@ -3,7 +3,6 @@ module Argo.Class.FromValue where import qualified Argo.Result as Result-import qualified Argo.Type as Type import qualified Argo.Type.Array as Array import qualified Argo.Type.Boolean as Boolean import qualified Argo.Type.Number as Number@@ -21,9 +20,9 @@ import qualified Data.Word as Word class FromValue a where- fromValue :: Type.Value -> Result.Result a+ fromValue :: Value.Value -> Result.Result a -instance FromValue Type.Value where+instance FromValue Value.Value where fromValue = Result.Success instance FromValue Bool where@@ -94,7 +93,7 @@ instance FromValue () where fromValue x = do- [] <- fromValue x :: Result.Result [Type.Value]+ [] <- fromValue x :: Result.Result [Value.Value] pure () instance (FromValue a, FromValue b) => FromValue (a, b) where@@ -125,32 +124,32 @@ . traverse (\ (Pair.Pair (String.String k, v)) -> (,) k <$> fromValue v) . Data.Array.elems -withBoolean :: String -> (Bool -> Result.Result a) -> Type.Value -> Result.Result a+withBoolean :: String -> (Bool -> Result.Result a) -> Value.Value -> Result.Result a withBoolean s f x = case x of Value.Boolean (Boolean.Boolean y) -> f y _ -> fail $ "expected " <> s <> " but got " <> show x -withNumber :: String -> (Integer -> Integer -> Result.Result a) -> Type.Value -> Result.Result a+withNumber :: String -> (Integer -> Integer -> Result.Result a) -> Value.Value -> Result.Result a withNumber s f x = case x of Value.Number (Number.Number y z) -> f y z _ -> fail $ "expected " <> s <> " but got " <> show x -withString :: String -> (Text.Text -> Result.Result a) -> Type.Value -> Result.Result a+withString :: String -> (Text.Text -> Result.Result a) -> Value.Value -> Result.Result a withString s f x = case x of Value.String (String.String y) -> f y _ -> fail $ "expected " <> s <> " but got " <> show x -withArray :: String -> (Data.Array.Array Int Type.Value -> Result.Result a) -> Type.Value -> Result.Result a+withArray :: String -> (Data.Array.Array Int Value.Value -> Result.Result a) -> Value.Value -> Result.Result a withArray s f x = case x of Value.Array (Array.Array y) -> f y _ -> fail $ "expected " <> s <> " but got " <> show x -withObject :: String -> (Data.Array.Array Int (Pair.Pair String.String Type.Value) -> Result.Result a) -> Type.Value -> Result.Result a+withObject :: String -> (Data.Array.Array Int (Pair.Pair String.String Value.Value) -> Result.Result a) -> Value.Value -> Result.Result a withObject s f x = case x of Value.Object (Object.Object y) -> f y _ -> fail $ "expected " <> s <> " but got " <> show x -viaInteger :: (Integral a, Bits.Bits a) => Type.Value -> Result.Result a+viaInteger :: (Integral a, Bits.Bits a) => Value.Value -> Result.Result a viaInteger value = do integer <- fromValue value case Bits.toIntegralSized (integer :: Integer) of
source/library/Argo/Class/ToValue.hs view
@@ -2,7 +2,6 @@ module Argo.Class.ToValue where -import qualified Argo.Type as Type import qualified Argo.Type.Array as Array import qualified Argo.Type.Boolean as Boolean import qualified Argo.Type.Null as Null@@ -22,9 +21,9 @@ import qualified Numeric class ToValue a where- toValue :: a -> Type.Value+ toValue :: a -> Value.Value -instance ToValue Type.Value where+instance ToValue Value.Value where toValue = id instance ToValue Bool where@@ -85,7 +84,7 @@ toValue = maybe (Value.Null $ Null.Null ()) toValue instance ToValue () where- toValue = const $ toValue ([] :: [Type.Value])+ toValue = const $ toValue ([] :: [Value.Value]) instance (ToValue a, ToValue b) => ToValue (a, b) where toValue (x, y) = toValue [toValue x, toValue y]@@ -114,7 +113,16 @@ realFloatToValue x | isNaN x = Value.Null $ Null.Null () | isInfinite x = Value.Null $ Null.Null ()- | otherwise = Value.Number . uncurry digitsToNumber $ Numeric.floatToDigits 10 x+ | otherwise =+ let isNegative = x < 0+ in Value.Number+ . (if isNegative then negateNumber else id)+ . uncurry digitsToNumber+ . Numeric.floatToDigits 10+ $ abs x++negateNumber :: Number.Number -> Number.Number+negateNumber (Number.Number x y) = Number.Number (-x) y digitsToNumber :: [Int] -> Int -> Number.Number digitsToNumber ds e = uncurry Number.number $ List.foldl'
source/library/Argo/Pattern.hs view
@@ -13,28 +13,28 @@ import qualified Argo.Type.Value as Value import qualified Data.Text as Text -pattern Null :: Type.Value+pattern Null :: Value.Value pattern Null = Value.Null (Null.Null ()) -pattern Boolean :: Bool -> Type.Value+pattern Boolean :: Bool -> Value.Value pattern Boolean x = Value.Boolean (Boolean.Boolean x) -pattern Number :: Integer -> Integer -> Type.Value+pattern Number :: Integer -> Integer -> Value.Value pattern Number x y <- Value.Number (Number.Number x y) where Number x y = Value.Number $ Number.number x y -pattern String :: Text.Text -> Type.Value+pattern String :: Text.Text -> Value.Value pattern String x = Value.String (String.String x) -pattern Array :: Type.Array -> Type.Value+pattern Array :: Type.Array -> Value.Value pattern Array x = Value.Array (Array.Array x) -pattern Object :: Type.Object -> Type.Value+pattern Object :: Type.Object -> Value.Value pattern Object x = Value.Object (Object.Object x) {-# COMPLETE Null, Boolean, Number, String, Array, Object #-} -pattern Pair :: Text.Text -> Type.Value -> Type.Pair+pattern Pair :: Text.Text -> Value.Value -> Pair.Pair String.String Value.Value pattern Pair k v = Pair.Pair (String.String k, v) {-# COMPLETE Pair #-}
source/library/Argo/Type.hs view
@@ -5,10 +5,6 @@ import qualified Argo.Type.Value as Value import qualified Data.Array -type Value = Value.Value--type Array = Data.Array.Array Int Value--type Pair = Pair.Pair String.String Value+type Array = Data.Array.Array Int Value.Value -type Object = Data.Array.Array Int Pair+type Object = Data.Array.Array Int (Pair.Pair String.String Value.Value)
source/test-suite/Main.hs view
@@ -1,3 +1,6 @@+{-# OPTIONS_GHC -Wno-orphans #-}++{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} @@ -418,8 +421,60 @@ , Tasty.testGroup "property" [ Tasty.testProperty "decode . encode" . Tasty.forAll genValue $ \ x -> Tasty.shrinking shrinkValue x $ \ y -> (resultToMaybe . Argo.decode . LazyByteString.toStrict . Builder.toLazyByteString $ Argo.encode y) === Just y- , Tasty.testProperty "fromValue . toValue" . Tasty.forAll genValue $ \ x -> Tasty.shrinking shrinkValue x $ \ y ->- (resultToMaybe . Argo.fromValue $ Argo.toValue y) === Just y+ , Tasty.testGroup "fromValue . toValue"+ [ Tasty.testProperty "Value" . Tasty.forAll genValue $ \ x -> Tasty.shrinking shrinkValue x $ \ y ->+ (resultToMaybe . Argo.fromValue $ Argo.toValue y) === Just y+ , Tasty.testProperty "Bool" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: Bool)+ , Tasty.testProperty "Char" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: Char)+ , Tasty.testProperty "Int" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: Int)+ , Tasty.testProperty "Int8" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: Int.Int8)+ , Tasty.testProperty "Int16" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: Int.Int16)+ , Tasty.testProperty "Int32" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: Int.Int32)+ , Tasty.testProperty "Int64" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: Int.Int64)+ , Tasty.testProperty "Word" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: Word)+ , Tasty.testProperty "Word8" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: Word.Word8)+ , Tasty.testProperty "Word16" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: Word.Word16)+ , Tasty.testProperty "Word32" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: Word.Word32)+ , Tasty.testProperty "Word64" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: Word.Word64)+ , Tasty.testProperty "Integer" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: Integer)+ , Tasty.testProperty "Float" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: Float)+ , Tasty.testProperty "Double" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: Double)+ , Tasty.testProperty "String" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: String)+ , Tasty.testProperty "Text" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: Text.Text)+ , Tasty.testProperty "LazyText" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: LazyText.Text)+ , Tasty.testProperty "Maybe a" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: Maybe Bool)+ , Tasty.testProperty "()" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: ())+ , Tasty.testProperty "(a, b)" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: (Bool, Int.Int8))+ , Tasty.testProperty "Array Int a" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: Array.Array Int Bool)+ , Tasty.testProperty "[a]" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: [Bool])+ , Tasty.testProperty "NonEmpty a" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: NonEmpty Bool)+ , Tasty.testProperty "Map Text a" $ \ x ->+ Argo.fromValue (Argo.toValue x) === Argo.Success (x :: Map.Map Text.Text Bool)+ ] ] ] @@ -434,14 +489,11 @@ [ pure Argo.Null , Argo.Boolean <$> Tasty.arbitrary , Argo.Number <$> Tasty.arbitrary <*> Tasty.arbitrary- , Argo.String <$> genText+ , Argo.String <$> Tasty.arbitrary , Argo.Array <$> genArray size (genValueSized newSize)- , Argo.Object <$> genArray size (Argo.Pair <$> genText <*> genValueSized newSize)+ , Argo.Object <$> genArray size (Argo.Pair <$> Tasty.arbitrary <*> genValueSized newSize) ] -genText :: Tasty.Gen Text.Text-genText = Text.pack <$> Tasty.arbitrary- genArray :: Int -> Tasty.Gen a -> Tasty.Gen (Array.Array Int a) genArray n = fmap (Array.listArray (0, n - 1)) . Tasty.vectorOf n @@ -452,12 +504,9 @@ Argo.Null -> [] Argo.Boolean y -> Argo.Boolean <$> Tasty.shrink y Argo.Number y z -> uncurry Argo.Number <$> Tasty.shrink (y, z)- Argo.String y -> Argo.String <$> shrinkText y+ Argo.String y -> Argo.String <$> Tasty.shrink y Argo.Array y -> Argo.Array <$> shrinkArray shrinkValue y- Argo.Object y -> Argo.Object <$> shrinkArray (\ (Argo.Pair k v) -> Argo.Pair <$> shrinkText k <*> shrinkValue v) y--shrinkText :: Shrink Text.Text-shrinkText = Tasty.shrinkMap Text.pack Text.unpack+ Argo.Object y -> Argo.Object <$> shrinkArray (\ (Argo.Pair k v) -> Argo.Pair <$> Tasty.shrink k <*> shrinkValue v) y shrinkArray :: Shrink a -> Shrink (Array.Array Int a) shrinkArray = Tasty.shrinkMapBy array Array.elems . Tasty.shrinkList@@ -466,3 +515,19 @@ resultToMaybe r = case r of Argo.Failure _ -> Nothing Argo.Success x -> Just x++instance Tasty.Arbitrary Text.Text where+ arbitrary = Text.pack <$> Tasty.arbitrary+ shrink = Tasty.shrinkMap Text.pack Text.unpack++instance Tasty.Arbitrary LazyText.Text where+ arbitrary = LazyText.pack <$> Tasty.arbitrary+ shrink = Tasty.shrinkMap LazyText.pack LazyText.unpack++instance Tasty.Arbitrary a => Tasty.Arbitrary (NonEmpty a) where+ arbitrary = (:|) <$> Tasty.arbitrary <*> Tasty.arbitrary+ shrink (x :| xs) = uncurry (:|) <$> Tasty.shrink (x, xs)++instance Tasty.Arbitrary a => Tasty.Arbitrary (Array.Array Int a) where+ arbitrary = array <$> Tasty.arbitrary+ shrink = Tasty.shrinkMap array Array.elems