@@ -30,6 +30,7 @@ module Data.Aeson.Types
3030 , ToJSON(..)
3131 -- * Constructors and accessors
3232 , (.=)
33+ , (.=?)
3334 , (.:)
3435 , (.:?)
3536 , object
@@ -140,6 +141,7 @@ data Value = Object Object
140141 | Number Number
141142 | Bool !Bool
142143 | Null
144+ | Missing
143145 deriving (Eq, Show, Typeable, Data)
144146
145147instance NFData Value where
@@ -149,6 +151,7 @@ instance NFData Value where
149151 rnf (Number n) = case n of I i -> rnf i; D d -> rnf d
150152 rnf (Bool b) = rnf b
151153 rnf Null = ()
154+ rnf Missing = ()
152155
153156-- | The empty array.
154157emptyArray :: Value
@@ -166,6 +169,14 @@ type Pair = (Text, Value)
166169name .= value = (name, toJSON value)
167170{-# INLINE (.=) #-}
168171
172+-- | Construct an optional 'Pair' from a key and a Maybe value. If
173+-- the value is Nothing, then it is omitted altogether from the
174+-- resulting Object.
175+(.=?) :: ToJSON a => Text -> Maybe a -> Pair
176+name .=? Nothing = (name, Missing)
177+name .=? Just value = (name, toJSON value)
178+{-# INLINE (.=?) #-}
179+
169180-- | Convert a value from JSON, failing if the types do not match.
170181fromJSON :: (FromJSON a) => Value -> Result a
171182fromJSON = parse parseJSON
@@ -205,7 +216,9 @@ obj .:? key = case M.lookup key obj of
205216-- | Create a 'Value' from a list of name\/value 'Pair's. If duplicate
206217-- keys arise, earlier keys and their associated values win.
207218object :: [Pair] -> Value
208−object = Object . M.fromList
219+object = Object . M.fromList . filter (notmissing . snd)
220+ where notmissing Missing = False
221+ notmissing _ = True
209222{-# INLINE object #-}
210223
211224-- | A type that can be converted to JSON.