aeson-extra 0.1.0.0 → 0.2.0.0
raw patch · 5 files changed
+59/−28 lines, 5 filesdep −ListLike
Dependencies removed: ListLike
Files
- CHANGELOG.md +4/−0
- aeson-extra.cabal +4/−3
- src/Data/Aeson/Extra.hs +27/−24
- test/Orphans.hs +14/−0
- test/Tests.hs +10/−1
CHANGELOG.md view
@@ -1,1 +1,5 @@+# 0.2.0.0 (2015-09-29) No ListLike++- Make `CollapsedList` use typeclasses in `base`+ # 0.1.0.0 (2015-09-29) Initial release
aeson-extra.cabal view
@@ -3,11 +3,12 @@ -- see: https://github.com/sol/hpack name: aeson-extra-version: 0.1.0.0+version: 0.2.0.0 synopsis: Extra goodies for aeson description: The package motivation is twofold: . * provide compatibility layer for @aeson@+ . * provide extra combinators category: Web homepage: https://github.com/phadej/aeson-extra#readme@@ -34,7 +35,6 @@ ghc-options: -Wall build-depends: base >=4.7 && <4.9- , ListLike >=4.2 && <4.3 , aeson >=0.8 && <0.11 , attoparsec >=0.12 && <0.14 , bytestring >=0.10 && <0.11@@ -58,7 +58,6 @@ ghc-options: -Wall build-depends: base >=4.7 && <4.9- , ListLike >=4.2 && <4.3 , aeson >=0.8 && <0.11 , attoparsec >=0.12 && <0.14 , bytestring >=0.10 && <0.11@@ -74,4 +73,6 @@ , tasty-hunit >=0.9 && <0.10 , tasty-quickcheck >=0.8 && <0.9 , quickcheck-instances >=0.3 && <0.4+ other-modules:+ Orphans default-language: Haskell2010
src/Data/Aeson/Extra.hs view
@@ -40,18 +40,17 @@ ) where #if !MIN_VERSION_base(4,8,0)-import Control.Applicative import Data.Foldable (Foldable) import Data.Traversable (Traversable, traverse) #endif +import Control.Applicative import Data.Monoid import Data.Aeson.Compat import Data.Aeson.Types hiding ((.:?))+import qualified Data.Foldable as Foldable import qualified Data.HashMap.Strict as H import Data.Hashable (Hashable)-import Data.ListLike (ListLike)-import qualified Data.ListLike as ListLike import qualified Data.Map as Map import Data.Proxy import Data.Text as T@@ -121,13 +120,13 @@ -- | Singleton string encoded and decoded as ifself. ----- > λ> encode (Sym :: Sym "foobar")+-- > λ> encode (SymTag :: SymTag "foobar") -- > "\"foobar\"" ----- > decode "\"foobar\"" :: Maybe (Sym "foobar")+-- > decode "\"foobar\"" :: Maybe (SymTag "foobar") -- > Just Sym ----- > decode "\"foobar\"" :: Maybe (Sym "barfoo")+-- > decode "\"foobar\"" :: Maybe (SymTag "barfoo") -- > Nothing data SymTag (s :: Symbol) = SymTag deriving (Eq, Ord, Show, Read, Enum, Bounded)@@ -135,7 +134,7 @@ instance KnownSymbol s => FromJSON (SymTag s) where parseJSON (String t) | T.unpack t == symbolVal (Proxy :: Proxy s) = pure SymTag- parseJSON v = typeMismatch ("Sym " ++ show (symbolVal (Proxy :: Proxy s))) v+ parseJSON v = typeMismatch ("SymTag " ++ show (symbolVal (Proxy :: Proxy s))) v instance KnownSymbol s => ToJSON (SymTag s) where #if MIN_VERSION_aeson (0,10,0)@@ -189,28 +188,32 @@ -- > "42" -- > λ > encode (CollapsedList ([1, 2, 3] :: [Int])) -- > "[1,2,3]"-newtype CollapsedList full elem = CollapsedList full- deriving (Eq, Ord, Show, Read)+--+-- Documentation rely on @f@ 'Alternative' instance behaving like lists'.+newtype CollapsedList f a = CollapsedList (f a)+ deriving (Eq, Ord, Show, Read, Functor, Foldable, Traversable) -getCollapsedList :: CollapsedList full elem -> full+getCollapsedList :: CollapsedList f a -> f a getCollapsedList (CollapsedList l) = l -instance (FromJSON elem, FromJSON full, ListLike full elem) => FromJSON (CollapsedList full elem) where- parseJSON Null = pure (CollapsedList ListLike.empty)+instance (FromJSON a, FromJSON (f a), Alternative f) => FromJSON (CollapsedList f a) where+ parseJSON Null = pure (CollapsedList Control.Applicative.empty) parseJSON v@(Array _) = CollapsedList <$> parseJSON v- parseJSON v = CollapsedList . ListLike.singleton <$> parseJSON v+ parseJSON v = CollapsedList . pure <$> parseJSON v -instance (ToJSON elem, ToJSON full, ListLike full elem) => ToJSON (CollapsedList full elem) where+instance (ToJSON a, ToJSON (f a), Foldable f) => ToJSON (CollapsedList f a) where #if MIN_VERSION_aeson (0,10,0)- toEncoding (CollapsedList l)- | ListLike.null l = toEncoding Null- | ListLike.null (ListLike.tail l) = toEncoding (ListLike.head l)- | otherwise = toEncoding l+ toEncoding (CollapsedList l) =+ case Foldable.toList l of+ [] -> toEncoding Null+ [x] -> toEncoding x+ _ -> toEncoding l #endif- toJSON (CollapsedList l)- | ListLike.null l = Null- | ListLike.null (ListLike.tail l) = toJSON (ListLike.head l)- | otherwise = toJSON l+ toJSON (CollapsedList l) =+ case Foldable.toList l of+ [] -> toJSON Null+ [x] -> toJSON x+ _ -> toJSON l -- | Parses possibly collapsed array value from the object's field. --@@ -224,10 +227,10 @@ -- > Just (V [42]) -- > λ > decode "{\"value\": [1, 2, 3, 4]}" :: Maybe V -- > Just (V [1,2,3,4])-parseCollapsedList :: (FromJSON elem, FromJSON full, ListLike full elem) => Object -> Text -> Parser full+parseCollapsedList :: (FromJSON a, FromJSON (f a), Alternative f) => Object -> Text -> Parser (f a) parseCollapsedList obj key = case H.lookup key obj of- Nothing -> pure ListLike.empty+ Nothing -> pure Control.Applicative.empty #if MIN_VERSION_aeson(0,10,0) Just v -> modifyFailure addKeyName $ (getCollapsedList <$> parseJSON v) -- <?> Key key where
+ test/Orphans.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+module Orphans where++#if !MIN_VERSION_base(4,8,0)+import Control.Applicative+#endif++import Data.Vector as V+import Test.Tasty.QuickCheck++instance Arbitrary a => Arbitrary (Vector a) where+ arbitrary = V.fromList <$> arbitrary+ shrink = fmap V.fromList . shrink . V.toList
test/Tests.hs view
@@ -12,11 +12,14 @@ import qualified Data.HashMap.Lazy as H import Data.Map (Map) import Data.Proxy+import Data.Vector (Vector) import Test.QuickCheck.Instances () import Test.Tasty import Test.Tasty.HUnit import Test.Tasty.QuickCheck +import Orphans ()+ main :: IO () main = defaultMain $ testGroup "Tests" [ dotColonMark@@ -89,8 +92,14 @@ , testCase "null" $ (decode "{\"value\": null}" :: Maybe V) @?= Just (V []) , testCase "singleton" $ (decode "{\"value\": 42}" :: Maybe V) @?= Just (V [42]) , testCase "array" $ (decode "{\"value\": [1, 2, 3, 4]}" :: Maybe V) @?= Just (V [1,2,3,4])- , testProperty "decode .encode " $+ , testProperty "decode . encode" $ let prop :: [Int] -> Property+ prop l = let rhs = fmap getCollapsedList . decode . encode . CollapsedList $ l+ lhs = Just l+ in lhs === rhs+ in prop+ , testProperty "Vector decode . encode" $+ let prop :: Vector Int -> Property prop l = let rhs = fmap getCollapsedList . decode . encode . CollapsedList $ l lhs = Just l in lhs === rhs