| Copyright | (c) Scrive 2011 |
|---|---|
| License | BSD-style (see the LICENSE file in the distribution) |
| Maintainer | mariusz@scrive.com |
| Stability | development |
| Portability | portable |
| Safe Haskell | None |
| Language | Haskell98 |
Text.JSON.FromJSValue
Description
Interface for extracting data from JSValue.
Synopsis
- class FromJSValue a where
- fromJSValue :: JSValue -> Maybe a
- fromJSValueM :: (JSValueContainer c, MonadReader c m) => m (Maybe a)
- class FromJSValueWithUpdate a where
- fromJSValueWithUpdate :: Maybe a -> JSValue -> Maybe a
- fromJSValueWithUpdateM :: (JSValueContainer c, MonadReader c m) => Maybe a -> m (Maybe a)
- class MatchWithJSValue a where
- matchesWithJSValue :: a -> JSValue -> Bool
- matchesWithJSValueM :: (JSValueContainer c, MonadReader c m) => a -> m Bool
- jsValueField :: (JSValueContainer c, MonadReader c m, FromJSValue a) => String -> m (Maybe (Maybe a))
- fromJSValueField :: (JSValueContainer c, MonadReader c m, FromJSValue a) => String -> m (Maybe a)
- fromJSValueFieldBase64 :: (JSValueContainer c, MonadReader c m) => String -> m (Maybe ByteString)
- fromJSValueFieldCustom :: (JSValueContainer c, MonadReader c m) => String -> m (Maybe a) -> m (Maybe a)
- fromJSValueCustomMany :: (JSValueContainer c, MonadReader c m) => m (Maybe a) -> m (Maybe [a])
- fromJSValueCustomList :: (JSValueContainer c, MonadReader c m) => [m (Maybe a)] -> m (Maybe [a])
- fromJSValueManyWithUpdate :: (JSValueContainer c, MonadReader c m, FromJSValueWithUpdate a, MatchWithJSValue a) => [a] -> m (Maybe [a])
- withJSValue :: Monad m => JSValue -> ReaderT JSValue m a -> m a
Basic Parsing
class FromJSValue a where Source #
Structures that can be parsed from JSON. Instances must declare
either fromJSValue (parse directly from JSValue) or
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
Applicative programming style with <$> and <*>.
Note: fromJSValueM is deprecated, in future fromJSValue will be
generalized to work in any MonadReader JSValue.
Minimal complete definition
Nothing
Methods
fromJSValue :: JSValue -> Maybe a Source #
fromJSValueM :: (JSValueContainer c, MonadReader c m) => m (Maybe a) Source #
Instances
class FromJSValueWithUpdate a where Source #
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.
Minimal complete definition
Nothing
Methods
fromJSValueWithUpdate :: Maybe a -> JSValue -> Maybe a Source #
fromJSValueWithUpdateM :: (JSValueContainer c, MonadReader c m) => Maybe a -> m (Maybe a) Source #
class MatchWithJSValue a where Source #
Structures that can be matched with JSValue
Minimal complete definition
Nothing
Methods
matchesWithJSValue :: a -> JSValue -> Bool Source #
matchesWithJSValueM :: (JSValueContainer c, MonadReader c m) => a -> m Bool Source #
Data Extraction
jsValueField :: (JSValueContainer c, MonadReader c m, FromJSValue a) => String -> m (Maybe (Maybe a)) Source #
Reading the value that is on some field. Returns Nothing if
JSON is not an object or field is present but cannot be parsed,
'Just Nothing' if absent, and 'Just (Just a)' otherwise
fromJSValueField :: (JSValueContainer c, MonadReader c m, FromJSValue a) => String -> m (Maybe a) Source #
Reading the value that is on a field. Semantics are a bit involved, example GHCi session should clarify:
Prelude> :set -XNoMonomorphismRestriction
Prelude> let x = withJSValue (JSObject (toJSObject [("key",JSString $ toJSString "value")]))
Prelude> x (fromJSValueField "key") :: IO (Maybe Int)
Nothing
Prelude> x (fromJSValueField "key") :: IO (Maybe (Maybe Int))
Just Nothing
Prelude> x (fromJSValueField "key") :: IO (Maybe (Maybe (Maybe Int)))
Just (Just Nothing)
Prelude> x (fromJSValueField "key") :: IO (Maybe String)
Just "value"
Prelude> x (fromJSValueField "key") :: IO (Maybe (Maybe String))
Just (Just "value")
Prelude> x (fromJSValueField "key") :: IO (Maybe (Maybe (Maybe String)))
Just (Just (Just "value"))
Prelude> let x = withJSValue (JSArray [])
Prelude> x (fromJSValueField "key") :: IO (Maybe String)
Nothing
Prelude> x (fromJSValueField "key") :: IO (Maybe (Maybe String))
Nothing
Prelude> x (fromJSValueField "key") :: IO (Maybe (Maybe (Maybe String)))
Nothing
fromJSValueFieldBase64 :: (JSValueContainer c, MonadReader c m) => String -> m (Maybe ByteString) Source #
Version of fromJSValueField for Base64 encoded data to avoid
memory leak.
fromJSValueFieldCustom :: (JSValueContainer c, MonadReader c m) => String -> m (Maybe a) -> m (Maybe a) Source #
Generalization of fromJSValueField. Does not use FromJSValue
instances.
fromJSValueCustomMany :: (JSValueContainer c, MonadReader c m) => m (Maybe a) -> m (Maybe [a]) Source #
Runs parser on each element of underlaying json. Returns Just iff JSON is array.
fromJSValueCustomList :: (JSValueContainer c, MonadReader c m) => [m (Maybe a)] -> m (Maybe [a]) Source #
Generalization of fromJSValueCustomMany, where each element of
array can have different parser.
fromJSValueManyWithUpdate :: (JSValueContainer c, MonadReader c m, FromJSValueWithUpdate a, MatchWithJSValue a) => [a] -> m (Maybe [a]) Source #
Runs parser on each element of underlying json. Returns Just iff
JSON is an array.
Note: This method has quadratic complexity. It is better to write less general matching algorithms that use Maps.
Running
withJSValue :: Monad m => JSValue -> ReaderT JSValue m a -> m a Source #
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)