packages feed

aeson-lens (empty) → 0.1.0.0

raw patch · 5 files changed

+171/−0 lines, 5 filesdep +aesondep +basedep +bytestringsetup-changed

Dependencies added: aeson, base, bytestring, doctest, lens, text, unordered-containers, vector

Files

+ Data/Aeson/Lens.hs view
@@ -0,0 +1,102 @@+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ViewPatterns      #-}++module Data.Aeson.Lens (+  ValueIx(..),+  valueAt,+  arr, obj,+  ) where++import           Control.Applicative+import           Control.Lens+import           Data.Aeson+import qualified Data.HashMap.Strict as HMS+import           Data.Maybe+import           Data.Monoid+import qualified Data.Text           as T+import qualified Data.Vector         as V++-- $setup+-- >>> 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++-- | Lens of Value+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+  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)]+  go (ArrIx ix) (Just (Array  a)) Nothing  = Just $ Array $ updateV ix Null a+  go (ArrIx ix) (Just (Array  a)) (Just v) = Just $ Array $ updateV ix (toJSON v) a+  go (ArrIx ix) _                 (Just v) = Just $ Array $ updateV ix (toJSON v) mempty+  go _ v _ = v++  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++updateV :: Int -> Value -> V.Vector Value -> V.Vector Value+updateV i v a+  | i >= V.length a =+    updateV i v $ V.generate (i + 1) $ \ii -> fromMaybe Null $ a `V.indexM` ii+  | otherwise =+    a V.// [(i, v)]++fromJSONMaybe :: FromJSON a => Value -> Maybe a+fromJSONMaybe v = case fromJSON v of+  Error   _ -> Nothing+  Success a -> Just a++-- | Lens of Array+--+-- >>> L.unpack $ encode v+-- "{\"bar\":[123,false,null],\"foo\":{\"baz\":3.14}}"+-- >>> v ^. obj (T.pack "bar") . arr 1 :: Maybe Bool+-- Just False+-- >>> v ^. obj (T.pack "bar") . arr 1 :: Maybe String+-- Nothing+-- >>> v ^. obj (T.pack "bar") . arr 3 :: Maybe Value+-- Nothing+-- >>> v ^. arr 0 :: Maybe Value+-- Nothing+-- >>> let x = arr 0 .~ Just 1 $ Nothing+-- >>> L.unpack $ encode x+-- "[1]"+-- >>> let y = arr 1 .~ Just "hoge" $ x+-- >>> L.unpack $ encode y+-- "[1,\"hoge\"]"+-- >>> let z = arr 0 .~ Just False $ y+-- >>> L.unpack $ encode z+-- "[false,\"hoge\"]"+arr :: (ToJSON v, FromJSON v)+       => Int+       -> SimpleIndexedLens ValueIx (Maybe Value) (Maybe v)+arr = valueAt . ArrIx++-- | Lens of Object+--+-- >>> v ^. obj (T.pack "foo") . obj (T.pack "baz") :: Maybe Double+-- Just 3.14+-- >>> v ^. obj (T.pack "foo") . obj (T.pack "baz") :: Maybe Object+-- Nothing+-- >>> v ^. obj (T.pack "foo") . obj (T.pack "hoge") :: Maybe Value+-- Nothing+-- >>> v ^. obj (T.pack "hoge") :: Maybe Value+-- Nothing+-- >>> let w = obj (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+-- >>> L.unpack $ encode x+-- "{\"b\":{\"c\":true},\"a\":2.23}"+obj :: (ToJSON v, FromJSON v)+       => T.Text+       -> SimpleIndexedLens ValueIx (Maybe Value) (Maybe v)+obj = valueAt . ObjIx
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2012, Hideyuki Tanaka++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Hideyuki Tanaka nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ aeson-lens.cabal view
@@ -0,0 +1,33 @@+name:                aeson-lens+version:             0.1.0.0+synopsis:            Lens of Aeson+description:         Lens of Aeson+license:             BSD3+license-file:        LICENSE+author:              Hideyuki Tanaka+maintainer:          tanaka.hideyuki@gmail.com+copyright:           (c) 2012, Hideyuki Tanaka+category:            Data+build-type:          Simple+cabal-version:       >=1.8++source-repository head+  type:                git+  location:            https://github.com/tanakh/aeson-lens.git++library+  exposed-modules:     Data.Aeson.Lens+  build-depends:       base ==4.5.*++                     , aeson >=0.6+                     , lens >=3.0+                     , text >=0.11+                     , bytestring >=0.9+                     , vector >=0.9+                     , unordered-containers >=0.2.2++test-suite doctest+  type:                exitcode-stdio-1.0+  main-is:             doctest.hs+  build-depends:       base+                     , doctest >=0.9
+ doctest.hs view
@@ -0,0 +1,4 @@+import Test.DocTest++main :: IO ()+main = doctest ["Data/Aeson/Lens.hs"]