packages feed

aeson-lens 0.1.0.2 → 0.2.0.0

raw patch · 2 files changed

+74/−26 lines, 2 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Data.Aeson.Lens: ArrIx :: Int -> ValueIx
- Data.Aeson.Lens: ObjIx :: Text -> ValueIx
- Data.Aeson.Lens: arr :: (ToJSON v, FromJSON v) => Int -> SimpleIndexedLens ValueIx (Maybe Value) (Maybe v)
- Data.Aeson.Lens: data ValueIx
- Data.Aeson.Lens: obj :: (ToJSON v, FromJSON v) => Text -> SimpleIndexedLens ValueIx (Maybe Value) (Maybe v)
- Data.Aeson.Lens: valueAt :: (ToJSON v, FromJSON v) => ValueIx -> SimpleIndexedLens ValueIx (Maybe Value) (Maybe v)
+ Data.Aeson.Lens: key :: (ToJSON v, FromJSON v) => Text -> SimpleIndexedLens ValueIx (Maybe Value) (Maybe v)
+ Data.Aeson.Lens: nth :: (ToJSON v, FromJSON v) => Int -> SimpleIndexedLens ValueIx (Maybe Value) (Maybe v)
+ Data.Aeson.Lens: traverseArray :: (ToJSON v, FromJSON v) => SimpleIndexedTraversal Int (Maybe Value) (Maybe v)
+ Data.Aeson.Lens: traverseObject :: (ToJSON v, FromJSON v) => SimpleIndexedTraversal Text (Maybe Value) (Maybe v)

Files

Data/Aeson/Lens.hs view
@@ -1,18 +1,24 @@ {-# LANGUAGE FlexibleContexts  #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE ViewPatterns      #-} {-# LANGUAGE RankNTypes        #-}+{-# LANGUAGE TupleSections     #-}+{-# LANGUAGE ViewPatterns      #-}  module Data.Aeson.Lens (-  ValueIx(..),-  valueAt,-  arr, obj,+  -- * Lenses+  nth,+  key,++  -- * Traversals+  traverseArray,+  traverseObject,   ) where  import           Control.Applicative import           Control.Lens import           Data.Aeson import qualified Data.HashMap.Strict as HMS+import           Data.List.Lens import           Data.Maybe import           Data.Monoid import qualified Data.Text           as T@@ -22,7 +28,6 @@ -- >>> import Data.Maybe -- >>> import qualified Data.ByteString.Lazy.Char8 as L -- >>> import Data.Text ()--- >>> let v = decode (L.pack "{\"foo\": {\"baz\": 3.14}, \"bar\": [123, false, null]}") :: Maybe Value  data ValueIx = ArrIx Int | ObjIx T.Text @@ -30,7 +35,7 @@ valueAt :: (ToJSON v, FromJSON v)            => ValueIx            -> SimpleIndexedLens ValueIx (Maybe Value) (Maybe v)-valueAt k = index $ \f (fmap toJSON -> v) -> (go k v) <$> f k (lu k v) where+valueAt k = index $ \f (fmap toJSON -> v) -> go k v <$> f k (lu k v) where   go (ObjIx ix) (Just (Object o)) Nothing  = Just $ Object $ HMS.delete ix o   go (ObjIx ix) (Just (Object o)) (Just v) = Just $ Object $ HMS.insert ix (toJSON v) o   go (ObjIx ix) _                 (Just v) = Just $ Object $ HMS.fromList [(ix, toJSON v)]@@ -42,6 +47,7 @@   lu (ObjIx ix) (Just (Object o)) = fromJSONMaybe =<< HMS.lookup ix o   lu (ArrIx ix) (Just (Array a)) | ix >= 0 && ix < V.length a = fromJSONMaybe $ a V.! ix   lu _ _ = Nothing+{-# INLINE valueAt #-}  updateV :: Int -> Value -> V.Vector Value -> V.Vector Value updateV i v a@@ -49,55 +55,97 @@     updateV i v $ V.generate (i + 1) $ \ii -> fromMaybe Null $ a `V.indexM` ii   | otherwise =     a V.// [(i, v)]+{-# INLINE updateV #-}  fromJSONMaybe :: FromJSON a => Value -> Maybe a fromJSONMaybe v = case fromJSON v of   Error   _ -> Nothing   Success a -> Just a+{-# INLINE fromJSONMaybe #-}  -- | Lens of Array ----- >>> L.unpack $ encode v--- "{\"bar\":[123,false,null],\"foo\":{\"baz\":3.14}}"--- >>> v ^. obj (T.pack "bar") . arr 1 :: Maybe Bool+-- >>> let v = decode (L.pack "{\"foo\": {\"baz\": 3.14}, \"bar\": [123, false, null]}") :: Maybe Value+-- >>> v ^. key (T.pack "bar") . nth 1 :: Maybe Bool -- Just False--- >>> v ^. obj (T.pack "bar") . arr 1 :: Maybe String+-- >>> v ^. key (T.pack "bar") . nth 1 :: Maybe String -- Nothing--- >>> v ^. obj (T.pack "bar") . arr 3 :: Maybe Value+-- >>> v ^. key (T.pack "bar") . nth 3 :: Maybe Value -- Nothing--- >>> v ^. arr 0 :: Maybe Value+-- >>> v ^. nth 0 :: Maybe Value -- Nothing--- >>> let x = arr 0 .~ Just 1 $ Nothing+-- >>> let x = nth 0 .~ Just 1 $ Nothing -- >>> L.unpack $ encode x -- "[1]"--- >>> let y = arr 1 .~ Just "hoge" $ x+-- >>> let y = nth 1 .~ Just "hoge" $ x -- >>> L.unpack $ encode y -- "[1,\"hoge\"]"--- >>> let z = arr 0 .~ Just False $ y+-- >>> let z = nth 0 .~ Just False $ y -- >>> L.unpack $ encode z -- "[false,\"hoge\"]"-arr :: (ToJSON v, FromJSON v)+nth :: (ToJSON v, FromJSON v)        => Int        -> SimpleIndexedLens ValueIx (Maybe Value) (Maybe v)-arr = valueAt . ArrIx+nth = valueAt . ArrIx+{-# INLINE nth #-}  -- | Lens of Object ----- >>> v ^. obj (T.pack "foo") . obj (T.pack "baz") :: Maybe Double+-- >>> let v = decode (L.pack "{\"foo\": {\"baz\": 3.14}, \"bar\": [123, false, null]}") :: Maybe Value+-- >>> v ^. key (T.pack "foo") . key (T.pack "baz") :: Maybe Double -- Just 3.14--- >>> v ^. obj (T.pack "foo") . obj (T.pack "baz") :: Maybe Object+-- >>> v ^. key (T.pack "foo") . key (T.pack "baz") :: Maybe Object -- Nothing--- >>> v ^. obj (T.pack "foo") . obj (T.pack "hoge") :: Maybe Value+-- >>> v ^. key (T.pack "foo") . key (T.pack "hoge") :: Maybe Value -- Nothing--- >>> v ^. obj (T.pack "hoge") :: Maybe Value+-- >>> v ^. key (T.pack "hoge") :: Maybe Value -- Nothing--- >>> let w = obj (T.pack "a") .~ Just 2.23 $ Nothing+-- >>> let w = key (T.pack "a") .~ Just 2.23 $ Nothing -- >>> L.unpack $ encode w -- "{\"a\":2.23}"--- >>> let x = obj (T.pack "b") . obj (T.pack "c") .~ Just True $ w+-- >>> let x = key (T.pack "b") . key (T.pack "c") .~ Just True $ w -- >>> L.unpack $ encode x -- "{\"b\":{\"c\":true},\"a\":2.23}"-obj :: (ToJSON v, FromJSON v)+key :: (ToJSON v, FromJSON v)        => T.Text        -> SimpleIndexedLens ValueIx (Maybe Value) (Maybe v)-obj = valueAt . ObjIx+key = valueAt . ObjIx+{-# INLINE key #-}++-- | Indexed traversal of Array+--+-- >>> let v = decode (L.pack "[1, true, null]") :: Maybe Value+-- >>> catMaybes . toListOf traverseArray $ v :: [Value]+-- [Number 1,Bool True,Null]+-- >>> let w = decode (L.pack "[{\"name\": \"tanakh\", \"age\": 29}, {\"name\": \"nushio\", \"age\": 28}]") :: Maybe Value+-- >>> catMaybes . toListOf (traverseArray . key (T.pack "name")) $ w :: [T.Text]+-- ["tanakh","nushio"]+traverseArray :: (ToJSON v, FromJSON v)+                 => SimpleIndexedTraversal Int (Maybe Value) (Maybe v)+traverseArray = index $ \f m -> case m of+  Just (Array (map fromJSONMaybe . V.toList -> v)) ->+    Just . Array . V.fromList . map toJSON . catMaybes <$> withIndex traverseList f v+  v -> pure v+{-# INLINE traverseArray #-}++-- | Indexed traversal of Object+--+-- >>> let w = decode (L.pack "[{\"name\": \"tanakh\", \"age\": 29}, {\"name\": \"nushio\", \"age\": 28}]") :: Maybe Value+-- >>> catMaybes . toListOf (traverseArray . traverseObject) $ w :: [Value]+-- [String "tanakh",Number 29,String "nushio",Number 28]+traverseObject :: (ToJSON v, FromJSON v)+                  => SimpleIndexedTraversal T.Text (Maybe Value) (Maybe v)+traverseObject = index $ \f m -> case m of+  Just (Object (expand . HMS.toList -> v)) ->+    Just . Object . HMS.fromList . catMaybes . collapse <$> withIndex traverseAssocList f v+  v -> pure v+  where+  expand = map (_2 %~ fromJSONMaybe)+  collapse = map (\(a, b) -> (a, ) . toJSON <$> b)+{-# INLINE traverseObject #-}++traverseAssocList :: SimpleIndexedTraversal k [(k, v)] v+traverseAssocList = index $ \f m -> go f m where+  go _ [] = pure []+  go f ((k, v): xs) = (\v' ys -> (k, v') : ys) <$> f k v <*> go f xs+{-# INLINE traverseAssocList #-}
aeson-lens.cabal view
@@ -1,5 +1,5 @@ name:                aeson-lens-version:             0.1.0.2+version:             0.2.0.0 synopsis:            Lens of Aeson description:         Lens of Aeson license:             BSD3