on master help sign in
Add Missing Value for non-present values.

If a Maybe a value should only be optionally included in an Object (as opposed to being set as "null"), then use .=? to construct its Pair. This sets the Value to Missing, which causes it to be subsequently excluded from the Object.

commit102d07f7d8365e6eb38a62c6af019a43201296af authorJeremy Fitzhardinge <jeremy@goop.org> dateThu 17 Feb 2011, 17:33 (16 years ago) parent6b40e5d
3 files changed+16−1
Data/Aeson.hs+1 Data/Aeson/Encode.hs+1 Data/Aeson/Types.hs+14−1
Data/Aeson.hs+1
@@ -24,6 +24,7 @@ module Data.Aeson
2424 , ToJSON(..)
2525 -- * Constructors and accessors
2626 , (.=)
27+ , (.=?)
2728 , (.:)
2829 , (.:?)
2930 , object
Data/Aeson/Encode.hs+1
@@ -29,6 +29,7 @@ import qualified Data.Vector as V
2929-- | Encode a JSON value to a 'Builder'.
3030fromValue :: Value -> Builder
3131fromValue Null = fromByteString "null"
32+fromValue Missing = error "Unexpected Missing"
3233fromValue (Bool b) = fromByteString $ if b then "true" else "false"
3334fromValue (Number n) = fromByteString (B.pack (show n))
3435fromValue (String s) = string s
Data/Aeson/Types.hs+14−1
@@ -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.