Skip to content

Commit

Permalink
Merge pull request #494 from phadej/parseField
Browse files Browse the repository at this point in the history
Add non-infix parseField, also explicit liftParseField
  • Loading branch information
bergmark committed Dec 22, 2016
2 parents f62d492 + f4614c1 commit 56c7432
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 11 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,4 +1,5 @@
dist
dist-newstyle
.cabal-sandbox/
cabal.sandbox.config
.stack-work/
Expand Down
6 changes: 6 additions & 0 deletions Data/Aeson/Types.hs
Expand Up @@ -90,6 +90,12 @@ module Data.Aeson.Types
, (.:!)
, (.!=)
, object
, parseField
, parseFieldMaybe
, parseFieldMaybe'
, explicitParseField
, explicitParseFieldMaybe
, explicitParseFieldMaybe'

, listEncoding
, listValue
Expand Down
9 changes: 8 additions & 1 deletion Data/Aeson/Types/Class.hs
Expand Up @@ -76,11 +76,18 @@ module Data.Aeson.Types.Class
-- * Functions
, fromJSON
, ifromJSON
, typeMismatch
, parseField
, parseFieldMaybe
, parseFieldMaybe'
, explicitParseField
, explicitParseFieldMaybe
, explicitParseFieldMaybe'
-- ** Operators
, (.:)
, (.:?)
, (.:!)
, (.!=)
, typeMismatch
) where

import Prelude ()
Expand Down
59 changes: 49 additions & 10 deletions Data/Aeson/Types/FromJSON.hs
Expand Up @@ -59,11 +59,18 @@ module Data.Aeson.Types.FromJSON
-- * Functions
, fromJSON
, ifromJSON
, typeMismatch
, parseField
, parseFieldMaybe
, parseFieldMaybe'
, explicitParseField
, explicitParseFieldMaybe
, explicitParseFieldMaybe'
-- ** Operators
, (.:)
, (.:?)
, (.:!)
, (.!=)
, typeMismatch

-- * Internal
, parseOptionalFieldWith
Expand Down Expand Up @@ -654,9 +661,7 @@ ifromJSON = iparse parseJSON
-- in an object for it to be valid. If the key and value are
-- optional, use '.:?' instead.
(.:) :: (FromJSON a) => Object -> Text -> Parser a
obj .: key = case H.lookup key obj of
Nothing -> fail $ "key " ++ show key ++ " not present"
Just v -> parseJSON v <?> Key key
(.:) = explicitParseField parseJSON
{-# INLINE (.:) #-}

-- | Retrieve the value associated with the given key of an 'Object'. The
Expand All @@ -667,9 +672,7 @@ obj .: key = case H.lookup key obj of
-- from an object without affecting its validity. If the key and
-- value are mandatory, use '.:' instead.
(.:?) :: (FromJSON a) => Object -> Text -> Parser (Maybe a)
obj .:? key = case H.lookup key obj of
Nothing -> pure Nothing
Just v -> parseJSON v <?> Key key
(.:?) = explicitParseFieldMaybe parseJSON
{-# INLINE (.:?) #-}

-- | Retrieve the value associated with the given key of an 'Object'.
Expand All @@ -679,11 +682,47 @@ obj .:? key = case H.lookup key obj of
-- This differs from '.:?' by attempting to parse 'Null' the same as any
-- other JSON value, instead of interpreting it as 'Nothing'.
(.:!) :: (FromJSON a) => Object -> Text -> Parser (Maybe a)
obj .:! key = case H.lookup key obj of
Nothing -> pure Nothing
Just v -> Just <$> parseJSON v <?> Key key
(.:!) = explicitParseFieldMaybe' parseJSON
{-# INLINE (.:!) #-}

-- | Function variant of '.:'.
parseField :: (FromJSON a) => Object -> Text -> Parser a
parseField = (.:)
{-# INLINE parseField #-}

-- | Function variant of '.:?'.
parseFieldMaybe :: (FromJSON a) => Object -> Text -> Parser (Maybe a)
parseFieldMaybe = (.:?)
{-# INLINE parseFieldMaybe #-}

-- | Function variant of '.:!'.
parseFieldMaybe' :: (FromJSON a) => Object -> Text -> Parser (Maybe a)
parseFieldMaybe' = (.:!)
{-# INLINE parseFieldMaybe' #-}

-- | Variant of '.:' with explicit parser function.
--
-- E.g. @'explicitParseField' 'parseJSON1' :: ('FromJSON1' f, 'FromJSON' a) -> 'Object' -> 'Text' -> 'Parser' (f a)@
explicitParseField :: (Value -> Parser a) -> Object -> Text -> Parser a
explicitParseField p obj key = case H.lookup key obj of
Nothing -> fail $ "key " ++ show key ++ " not present"
Just v -> p v <?> Key key
{-# INLINE explicitParseField #-}

-- | Variant of '.:?' with explicit parser function.
explicitParseFieldMaybe :: (Value -> Parser a) -> Object -> Text -> Parser (Maybe a)
explicitParseFieldMaybe p obj key = case H.lookup key obj of
Nothing -> pure Nothing
Just v -> liftParseJSON p (listParser p) v <?> Key key -- listParser isn't used by maybe instance.
{-# INLINE explicitParseFieldMaybe #-}

-- | Variant of '.:!' with explicit parser function.
explicitParseFieldMaybe' :: (Value -> Parser a) -> Object -> Text -> Parser (Maybe a)
explicitParseFieldMaybe' p obj key = case H.lookup key obj of
Nothing -> pure Nothing
Just v -> Just <$> p v <?> Key key
{-# INLINE explicitParseFieldMaybe' #-}

-- | Helper for use in combination with '.:?' to provide default
-- values for optional JSON object fields.
--
Expand Down

0 comments on commit 56c7432

Please sign in to comment.