@@ -33,6 +33,7 @@ module Data.Aeson.Types.Class
33 , fromJSON
33 , fromJSON
38 , typeMismatch
39 , typeMismatch
@@ -44,6 +45,7 @@ import Data.Aeson.Types.Internal
44import Data.Attoparsec.Char8 (Number(..))
45import Data.Attoparsec.Char8 (Number(..))
45import Data.Hashable (Hashable(..))
46import Data.Hashable (Hashable(..))
46import Data.Int (Int8, Int16, Int32, Int64)
47import Data.Int (Int8, Int16, Int32, Int64)
48+import Data.Maybe (fromMaybe)
47import Data.Monoid (Dual(..), First(..), Last(..))
49import Data.Monoid (Dual(..), First(..), Last(..))
48import Data.Ratio (Ratio)
50import Data.Ratio (Ratio)
49import Data.Text (Text, pack, unpack)
51import Data.Text (Text, pack, unpack)
@@ -745,6 +747,22 @@ obj .:? key = case H.lookup key obj of
745 Just v -> parseJSON v
747 Just v -> parseJSON v
746{-# INLINE (.:?) #-}
748{-# INLINE (.:?) #-}
750+-- | Helper for use in combination with '.:?' to provide default
751+-- values for optional JSON object fields.
755+-- @ v1 <- o '.:?' \"opt_field_with_dfl\" .!= \"default_val\"
756+-- v2 <- o '.:' \"mandatory_field\"
757+-- v3 <- o '.:?' \"opt_field2\"
759+-- \-- alternative version of v1 using the '.:/' operator
760+-- v1' <- o '.:/' (\"opt_field_with_dfl\", \"default_val\")
762+(.!=) :: Parser (Maybe a) -> a -> Parser a
763+pmval .!= val = fromMaybe val <$> pmval
748-- | Retrieve the value associated with the given key of an 'Object'.
766-- | Retrieve the value associated with the given key of an 'Object'.
749-- The result is a default value if the key is not present, or 'empty'
767-- The result is a default value if the key is not present, or 'empty'
750-- if the value cannot be converted to the desired type.
768-- if the value cannot be converted to the desired type.
@@ -753,6 +771,9 @@ obj .:? key = case H.lookup key obj of
753-- from an object without affecting its validity and we know a
771-- from an object without affecting its validity and we know a
754-- default value to assign in that case. If the key and value
772-- default value to assign in that case. If the key and value
755-- are mandatory, use '(.:)' instead.
773-- are mandatory, use '(.:)' instead.
775+-- See also '.!=' for an alternative way to represent optional fields
756(.:/) :: (FromJSON a) => Object -> (Text, a) -> Parser a
777(.:/) :: (FromJSON a) => Object -> (Text, a) -> Parser a
757obj .:/ (key, val) = case H.lookup key obj of
778obj .:/ (key, val) = case H.lookup key obj of
758 Nothing -> pure val
779 Nothing -> pure val