on master help sign in
Merge pull request #50 from hvr/defaulting-operator

Add `.!=` operator as a ternary-style operator alternative to '.:/'

commiteb11f43b51a6e00b36d5fc7d29e31dcc663e01a9 authorBryan O'Sullivan <bos@serpentine.com> dateWed 30 Nov 2011, 21:42 (15 years ago) parentf62f582d41c1d5
3 files changed+23
Data/Aeson.hs+1 Data/Aeson/Types.hs+1 Data/Aeson/Types/Class.hs+21
Data/Aeson.hs+1
@@ -31,6 +31,7 @@ module Data.Aeson
3131 , (.=)
3232 , (.:)
3333 , (.:?)
34+ , (.!=)
3435 , (.:/)
3536 , object
3637 -- * Parsing
Data/Aeson/Types.hs+1
@@ -35,6 +35,7 @@ module Data.Aeson.Types
3535 , (.=)
3636 , (.:)
3737 , (.:?)
38+ , (.!=)
3839 , (.:/)
3940 , object
4041 ) where
Data/Aeson/Types/Class.hs+21
@@ -33,6 +33,7 @@ module Data.Aeson.Types.Class
3333 , fromJSON
3434 , (.:)
3535 , (.:?)
36+ , (.!=)
3637 , (.:/)
3738 , (.=)
3839 , typeMismatch
@@ -44,6 +45,7 @@ import Data.Aeson.Types.Internal
4445import Data.Attoparsec.Char8 (Number(..))
4546import Data.Hashable (Hashable(..))
4647import Data.Int (Int8, Int16, Int32, Int64)
48+import Data.Maybe (fromMaybe)
4749import Data.Monoid (Dual(..), First(..), Last(..))
4850import Data.Ratio (Ratio)
4951import Data.Text (Text, pack, unpack)
@@ -745,6 +747,22 @@ obj .:? key = case H.lookup key obj of
745747 Just v -> parseJSON v
746748{-# INLINE (.:?) #-}
747749
750+-- | Helper for use in combination with '.:?' to provide default
751+-- values for optional JSON object fields.
752+--
753+-- Example usage:
754+--
755+-- @ v1 <- o '.:?' \"opt_field_with_dfl\" .!= \"default_val\"
756+-- v2 <- o '.:' \"mandatory_field\"
757+-- v3 <- o '.:?' \"opt_field2\"
758+--
759+-- \-- alternative version of v1 using the '.:/' operator
760+-- v1' <- o '.:/' (\"opt_field_with_dfl\", \"default_val\")
761+-- @
762+(.!=) :: Parser (Maybe a) -> a -> Parser a
763+pmval .!= val = fromMaybe val <$> pmval
764+{-# INLINE (.!=) #-}
765+
748766-- | Retrieve the value associated with the given key of an 'Object'.
749767-- The result is a default value if the key is not present, or 'empty'
750768-- if the value cannot be converted to the desired type.
@@ -753,6 +771,9 @@ obj .:? key = case H.lookup key obj of
753771-- from an object without affecting its validity and we know a
754772-- default value to assign in that case. If the key and value
755773-- are mandatory, use '(.:)' instead.
774+--
775+-- See also '.!=' for an alternative way to represent optional fields
776+-- with defaulting.
756777(.:/) :: (FromJSON a) => Object -> (Text, a) -> Parser a
757778obj .:/ (key, val) = case H.lookup key obj of
758779 Nothing -> pure val