unjson 0.15.2.1 → 0.15.3
raw patch · 4 files changed
+47/−51 lines, 4 filesdep ~aesondep ~basenew-uploaderPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: aeson, base
API changes (from Hackage documentation)
- Data.Unjson: instance (GHC.Classes.Eq a, Data.Hashable.Class.Hashable a, Data.Unjson.Unjson a, Data.Typeable.Internal.Typeable a) => Data.Unjson.Unjson (Data.HashSet.HashSet a)
+ Data.Unjson: instance (GHC.Classes.Eq a, Data.Hashable.Class.Hashable a, Data.Unjson.Unjson a, Data.Typeable.Internal.Typeable a) => Data.Unjson.Unjson (Data.HashSet.Base.HashSet a)
+ Data.Unjson: instance Control.Monad.Fail.MonadFail Data.Unjson.Result
- Data.Unjson: renderDocForPath :: Monad m => Path -> UnjsonDef a -> m Doc
+ Data.Unjson: renderDocForPath :: MonadFail m => Path -> UnjsonDef a -> m Doc
- Data.Unjson: renderForPath :: (Functor m, Monad m) => Path -> UnjsonDef a -> m String
+ Data.Unjson: renderForPath :: MonadFail m => Path -> UnjsonDef a -> m String
Files
- CHANGELOG.md +3/−0
- src/Data/Unjson.hs +10/−19
- test/Test.hs +31/−28
- unjson.cabal +3/−4
CHANGELOG.md view
@@ -1,3 +1,6 @@+# unjson-0.15.3 (2020-05-05)+* GHC 8.8 and 8.10 support+ # unjson-0.15.2.1 (2018-11-19) * GHC 8.6 support ([#12](https://github.com/scrive/unjson/pull/12)). * Documentation fixes
src/Data/Unjson.hs view
@@ -1,8 +1,4 @@- {-# LANGUAGE CPP #-}-#if __GLASGOW_HASKELL__ < 710-{-# LANGUAGE OverlappingInstances #-}-#endif -- | @Unjson@: bidirectional JSON (de)serialization with strong error -- reporting capabilities and automatic documentation generation.@@ -187,7 +183,8 @@ import qualified Data.HashMap.Lazy as LazyHashMap import Control.Exception -import Control.Monad+import Control.Monad hiding (fail)+import Control.Monad.Fail (MonadFail (..)) import Data.Bits import Data.Word import Data.Int@@ -195,15 +192,7 @@ import Data.List import qualified Text.ParserCombinators.ReadP as ReadP import Data.Char--#if !MIN_VERSION_base(4,6,0)-import Prelude hiding (catch)-#endif--#if !MIN_VERSION_base(4,8,0)-import Control.Applicative-import Data.Traversable-#endif+import Prelude hiding (fail) import qualified Text.PrettyPrint.HughesPJ as P @@ -284,6 +273,8 @@ return = pure Result a [] >>= m = m a Result _ es@(e:_) >>= _ = Result (throw e) es++instance MonadFail Result where fail str = Result (throw anchoredMessage) [anchoredMessage] where anchoredMessage = Anchored mempty (Text.pack str) @@ -1478,7 +1469,7 @@ -- | Render only selected part of structure documentation. Path should -- point to a subtree, if it does not then Nothing is returned.-renderForPath :: (Functor m, Monad m) => Path -> UnjsonDef a -> m String+renderForPath :: (MonadFail m) => Path -> UnjsonDef a -> m String renderForPath path def = fmap P.render (renderDocForPath path def) -- | Renders documentation for a parser into a 'P.Doc'. See 'render'@@ -1501,7 +1492,7 @@ -- | Render only selected part of structure documentation as -- 'P.Doc'. Path should point to a subtree, if it does not then -- Nothing is returned.-renderDocForPath :: (Monad m) => Path -> UnjsonDef a -> m P.Doc+renderDocForPath :: (MonadFail m) => Path -> UnjsonDef a -> m P.Doc renderDocForPath path def = findNestedUnjson path def @@ -1531,20 +1522,20 @@ where s = renderDoc d -findNestedUnjson :: (Monad m) => Path -> UnjsonDef a -> m P.Doc+findNestedUnjson :: (MonadFail m) => Path -> UnjsonDef a -> m P.Doc findNestedUnjson (Path []) u = return (renderDoc u) findNestedUnjson (Path (PathElemIndex n : rest)) (TupleUnjsonDef d) = findNestedTupleUnjson n (Path rest) d findNestedUnjson (Path (PathElemIndex _ : rest)) (ArrayUnjsonDef _ _ _ _ d) = findNestedUnjson (Path rest) d findNestedUnjson (Path (PathElemKey k : rest)) (ObjectUnjsonDef d) = findNestedFieldUnjson k (Path rest) d findNestedUnjson _ _ = fail "cannot find crap" -findNestedTupleUnjson :: (Monad m) => Int -> Path -> Ap (TupleFieldDef s) a -> m P.Doc+findNestedTupleUnjson :: (MonadFail m) => Int -> Path -> Ap (TupleFieldDef s) a -> m P.Doc findNestedTupleUnjson n path (Ap (TupleFieldDef index _f d) _r) | n == index = findNestedUnjson path d findNestedTupleUnjson n path (Ap (TupleFieldDef _index _f _d) r) = findNestedTupleUnjson n path r findNestedTupleUnjson _ _ _ = fail "findNestedTupleUnjson" -findNestedFieldUnjson :: (Monad m) => Text.Text -> Path -> Ap (FieldDef s) a -> m P.Doc+findNestedFieldUnjson :: (MonadFail m) => Text.Text -> Path -> Ap (FieldDef s) a -> m P.Doc findNestedFieldUnjson key (Path []) (Ap f@(FieldReqDef k _ _ _d) _r) | k==key = return (renderField f) findNestedFieldUnjson key (Path []) (Ap f@(FieldOptDef k _ _ _d) _r) | k==key = return (renderField f) findNestedFieldUnjson key (Path []) (Ap f@(FieldDefDef k _ _ _ _d) _r) | k==key = return (renderField f)
test/Test.hs view
@@ -2,6 +2,7 @@ {-# OPTIONS_GHC -fno-warn-type-defaults #-} module Main where +import Prelude hiding (fail) import qualified Data.Text as Text import qualified Data.ByteString.Lazy.Char8 as BSL import Data.Int@@ -9,25 +10,17 @@ import Data.Unjson import qualified Data.Aeson as Aeson import Data.Aeson ((.=))-import Test.HUnit import Data.List import Data.Data import Data.Functor.Invariant+import Control.Monad.Fail (MonadFail(fail))+import Test.HUnit import qualified Data.HashMap.Strict as HashMap import qualified Data.HashMap.Lazy as LazyHashMap import qualified Data.Map as Map import System.Exit (ExitCode (..), exitWith) -#if !MIN_VERSION_base(4,6,0)-import Prelude hiding (catch)-#endif--#if !MIN_VERSION_base(4,8,0)-import Control.Applicative-import Data.Monoid-#endif- default (Text.Text, String, Int, Double) -- As an example we will use a hypothetical configuration data.@@ -182,14 +175,14 @@ let Result _val iss = parse unjsonKonfig json assertEqual "Number of issues in parsing" 3 (length iss) assertEqual "Hostname must be string error info is present"- (Anchored (Path [ PathElemKey "hostname"- ]) "expected Text, encountered Number") (iss!!0)+ (Anchored (Path [PathElemKey "hostname"])+ "parsing Text failed, expected String, but encountered Number") (iss!!0) assertEqual "Port must be number error info is present"- (Anchored (Path [ PathElemKey "port"- ]) "expected Integer, encountered Object") (iss!!1)+ (Anchored (Path [ PathElemKey "port" ])+ "parsing Integer failed, expected Number, but encountered Object") (iss!!1) assertEqual "Credentials must be object error info is present" (Anchored (Path [ PathElemKey "credentials"- ]) "Error in $: expected HashMap ~Text v, encountered String") (iss!!2)+ ]) "Error in $: parsing HashMap ~Text failed, expected Object, but encountered String") (iss!!2) return () test_tuple_parsing :: Test@@ -212,13 +205,17 @@ let Result (_ :: (Integer, Integer, Text.Text)) iss'' = parse unjsonDef json assertEqual "Issues in parsing"- [ Anchored (Path [PathElemIndex 0]) "expected Integer, encountered String"- , Anchored (Path [PathElemIndex 1]) "expected Integer, encountered String"- , Anchored (Path [PathElemIndex 2]) "expected Text, encountered Number"- ] iss''+ [ Anchored (Path [PathElemIndex 0])+ "parsing Integer failed, expected Number, but encountered String"+ , Anchored (Path [PathElemIndex 1])+ "parsing Integer failed, expected Number, but encountered String"+ , Anchored (Path [PathElemIndex 2])+ "parsing Text failed, expected String, but encountered Number"+ ] iss'' let Result (_ :: (String, Text.Text)) iss''' = parse unjsonDef json- assertEqual "Array too long for 2-tuple" [Anchored mempty "cannot parse array of length 3 into tuple of size 2"] iss'''+ assertEqual "Array too long for 2-tuple" [Anchored mempty+ "cannot parse array of length 3 into tuple of size 2"] iss''' return () @@ -343,7 +340,8 @@ [ "value" .= (13 :: Int) ] let Result _val iss = parse unjsonButThirteen json- assertEqual "Problem is reported" [Anchored (Path [PathElemKey "value"]) "13 is a bad luck number"] iss+ assertEqual "Problem is reported" [Anchored (Path [PathElemKey "value"])+ "13 is a bad luck number"] iss -- assertEqual "Just numerical_value present" (13) val unjsonEitherIntText :: UnjsonDef (Either Int Text.Text)@@ -386,7 +384,8 @@ , "numerical_value" .= 12345 ] let Result _val iss = parse unjsonEitherIntText json- assertEqual "Problem when mode is missing" [Anchored (Path [PathElemKey "mode"]) "missing key"] iss+ assertEqual "Problem when mode is missing" [Anchored (Path [PathElemKey "mode"])+ "missing key"] iss do let json = Aeson.object [ "mode" .= "something else"@@ -436,7 +435,8 @@ [ "mode" .= "wrong" ] let Result _val iss = parse unjsonEnumAB json- assertEqual "No problems" [Anchored (Path [PathElemKey "mode"]) "value 'wrong' is not one of the allowed for enumeration [A,B]"] iss+ assertEqual "No problems" [Anchored (Path [PathElemKey "mode"])+ "value 'wrong' is not one of the allowed for enumeration [A,B]"] iss data AutoAB = AutoA | AutoB@@ -466,9 +466,10 @@ [ "AutoAB" .= "wrong" ] let Result _val iss = parse unjsonAutoEnumAB json- assertEqual "No problems" [Anchored (Path [PathElemKey "AutoAB"]) "value 'wrong' is not one of the allowed for enumeration [AutoA,AutoB]"] iss- + assertEqual "No problems" [Anchored (Path [PathElemKey "AutoAB"])+ "value 'wrong' is not one of the allowed for enumeration [AutoA,AutoB]"] iss + test_update_from_serialization :: Test test_update_from_serialization = "test_update_from_serialization" ~: do let initial = Konfig@@ -541,7 +542,8 @@ ] let Result _ iss = update initial unjsonKonfig json assertEqual "Cannot reset mandatory field without default"- [Anchored (Path [PathElemKey "hostname"]) "expected Text, encountered Null"] iss+ [Anchored (Path [PathElemKey "hostname"])+ "parsing Text failed, expected String, but encountered Null"] iss return () test_array_modes :: Test@@ -571,7 +573,7 @@ let Result _val0 iss0 = parse p0 json assertEqual "Does not parse value in strict array mode" [Anchored (Path [PathElemKey "hostname"])- "Error in $: expected Vector a, encountered String"] iss0+ "Error in $: parsing Vector failed, expected Array, but encountered String"] iss0 let Result val1 iss1 = parse p1 json assertEqual "No problems" [] iss1 assertEqual "Accepts singel value in ArrayModeParseSingle" ["www.example.com"] val1@@ -730,7 +732,8 @@ ] let Result _val3 iss3 = parse unjsonPlainUnion json3- assertEqual "Cannot parse PlainUnionA" [Anchored (Path [PathElemKey "key1"]) "expected String, encountered Number"] iss3+ assertEqual "Cannot parse PlainUnionA"+ [Anchored (Path [PathElemKey "key1"]) "expected String, but encountered Number"] iss3 -- choose PlainUnionB
unjson.cabal view
@@ -1,6 +1,6 @@ cabal-version: 1.18 name: unjson-version: 0.15.2.1+version: 0.15.3 synopsis: Bidirectional JSON parsing and generation. description: Bidirectional JSON parsing and generation with automatic documentation support.@@ -15,8 +15,7 @@ category: Data build-type: Simple extra-source-files: README.md, CHANGELOG.md-tested-with: GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.2,- GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.2+tested-with: GHC ==8.0.2 || ==8.2.2 || ==8.4.4 || ==8.6.5 || ==8.8.3 || ==8.10.1 source-repository head type: git@@ -31,7 +30,7 @@ exposed-modules: Data.Unjson -- other-modules: -- other-extensions:- build-depends: base >= 4.7 && < 4.13,+ build-depends: base >= 4.9 && < 5, aeson >= 1.0 && < 1.5, attoparsec, bytestring >= 0.10,