fields-json 0.2.2.3 → 0.2.2.4
raw patch · 3 files changed
+73/−19 lines, 3 filesnew-uploader
Files
- fields-json.cabal +1/−1
- src/Text/JSON/FromJSValue.hs +54/−5
- src/Text/JSON/Gen.hs +18/−13
fields-json.cabal view
@@ -1,5 +1,5 @@ Name: fields-json-Version: 0.2.2.3+Version: 0.2.2.4 Synopsis: Abusing monadic syntax JSON objects generation.
src/Text/JSON/FromJSValue.hs view
@@ -30,18 +30,37 @@ , withJSValue ) where+ import Text.JSON import Text.JSON.JSValueContainer import Control.Monad import Control.Monad.Reader import qualified Data.ByteString.UTF8 as BS import qualified Data.ByteString.Base64 as BASE64+import Control.Applicative import Control.Monad.Identity+import Data.Int import Data.List -- | Structures that can be 'parsed' from JSON. Instances must declare -- either 'fromJSValue' (parse directly from 'JSValue') or--- 'fromJSValueM' (uses 'MonadReader')+-- 'fromJSValueM' (uses 'MonadReader').+--+-- Example implementation:+--+-- > data D = D String Int+-- >+-- > instance FromJSValue D where+-- > fromJSValue = do+-- > s <- fromJSValue "string_key"+-- > i <- fromJSValue "int_key"+-- > return (D <$> s <*> i)+--+-- Note that we make use of 'MonadReader' instance for "(->)" and of+-- 'Control.Applicative' programming style with 'Control.Applicative.<$>' and 'Control.Applicative.<*>'.+--+-- Note: 'fromJSValueM' is deprecated, in future 'fromJSValue' will be+-- generalized to work in any 'Control.Monad.Reader.MonadReader' 'Text.JSON.JSValue'. class FromJSValue a where fromJSValue :: JSValue -> Maybe a fromJSValue j = runIdentity $ withJSValue j $ liftM fromJSValueM askJSValue@@ -49,8 +68,11 @@ fromJSValueM = liftM fromJSValue askJSValue --- | Structures that can be 'parsed' from JSON if some structure for--- update is provided+-- | Structures that can be 'parsed' from JSON, fields absent in the+-- JSON will be filled in using (optional) original structure.+--+-- By convention JSON null should be treated as a request to reset+-- structure element to default value. class FromJSValueWithUpdate a where fromJSValueWithUpdate :: Maybe a -> JSValue -> Maybe a fromJSValueWithUpdate ma j = runIdentity $ withJSValue j $ liftM (fromJSValueWithUpdateM ma) askJSValue@@ -86,6 +108,15 @@ instance FromJSValue Int where fromJSValue j = liftM fromIntegral (fromJSValue j :: Maybe Integer) +instance FromJSValue Int16 where+ fromJSValue j = fromIntegral <$> (fromJSValue j :: Maybe Integer)++instance FromJSValue Int32 where+ fromJSValue j = fromIntegral <$> (fromJSValue j :: Maybe Integer)++instance FromJSValue Int64 where+ fromJSValue j = fromIntegral <$> (fromJSValue j :: Maybe Integer)+ instance FromJSValue Bool where fromJSValue (JSBool v) = Just $ v fromJSValue _ = Nothing@@ -273,7 +304,25 @@ _ -> return Nothing runFromJSValueAndUpdate [] = return $ Just [] --- ------------------------------------------------------------------- | Simple runner+-- | Simple runner. Example:+--+-- > let (v :: MyStruct) = runIdentity $ withJSValue js (fromJSValueM)+--+-- or inline:+--+-- > let z = runIdentity $ withJSValue js $ do+-- > a <- fromJSValueField "a"+-- > b <- fromJSValueField "b"+-- > c <- fromJSValueField "c"+-- > return ((,,) <$> a <*> b <*> <*> c)+--+-- or using the monad transformer:+--+-- > z <- withJSValue js $ do+-- > a <- fromJSValueField "a"+-- > b <- fromJSValueField "b"+-- > c <- fromJSValueField "c"+-- > return ((,,) <$> a <*> b <*> c)+-- withJSValue :: (Monad m) => JSValue -> ReaderT JSValue m a -> m a withJSValue j a = runReaderT a j
src/Text/JSON/Gen.hs view
@@ -8,32 +8,37 @@ -- Stability : development -- Portability : portable ----- Abusing monadic 'do' notation library for generating JSON object. --- Hard-binded to json package from hackage.+-- Abusing monadic 'do' notation library for generating JSON object.+-- Hard-bound to 'Text.JSON.JSValue' from json package from hackage.+-- -- Main ideas ----- * Overloaded function 'value' to set values in underlying JSON - 'Bool', 'Int', 'String', lists etc.+-- * Overloaded function 'value' to set values in underlying JSON -+-- 'Bool', 'Int', 'String', lists, etc. ----- * JSON generation may not be pure with 'valueM'. You can perform some IO while generating JSON. This is usefull skip useless inner binding.+-- * JSON generation may not be pure with 'valueM'. You can perform+-- some IO while generating JSON. This is usefull skip useless inner+-- binding. ----- * Compositionality - use 'object' to easy create JSON objects+-- * Compositionality - use 'object' to easy create JSON objects. The+-- 'objects' function is there to support arrays of objects. ----- * Monadic notation - it really looks nicer then composition with '.' or some magic combinator+-- * Monadic notation - it really looks nicer then composition with+-- '.' or some magic combinator ----- > -- > runJSONGen $ do -- > value "a" "a" -- > value "b" [1,2,3] -- > object "c" $ do -- > value "x" True -- > value "y" False--- >--- --- Will generate json object --- {a : "a", b: [1,2,3], c: {x: true, y : false}} -+--+-- Will generate json object:+--+-- > {a : "a", b: [1,2,3], c: {x: true, y : false}}+-- - module Text.JSON.Gen (+module Text.JSON.Gen ( module Text.JSON.ToJSValue -- * Basic types , JSONGen