on master help sign in
Move typeMismatch, and improve its docs
commit7c3a686021bc4d2d1c79b6605745c794f0cf8200 authorBryan O'Sullivan <bos@serpentine.com> dateMon 20 Jul 2015, 22:20 (11 years ago) parented85672
2 files changed+43−21
Data/Aeson/Types/Class.hs+43−5 Data/Aeson/Types/Instances.hs−16
Data/Aeson/Types/Class.hs+43−5
@@ -24,6 +24,8 @@ module Data.Aeson.Types.Class
2424 , genericParseJSON
2525 -- * Object key-value pairs
2626 , KeyValue(..)
27+ -- * Functions needed for documentation
28+ , typeMismatch
2729 ) where
2830
2931import Data.Aeson.Types.Internal
@@ -128,9 +130,18 @@ class ToJSON a where
128130-- | A type that can be converted from JSON, with the possibility of
129131-- failure.
130132--
131−-- When writing an instance, use 'empty', 'mzero', or 'fail' to make a
132−-- conversion fail, e.g. if an 'Object' is missing a required key, or
133−-- the value is of the wrong type.
133+-- There are various reasons a conversion could fail. For example, an
134+-- 'Object' could be missing a required key, an 'Array' could be of
135+-- the wrong size, or a value could be of an incompatible type.
136+--
137+-- The basic ways to signal a failed conversion are as follows:
138+--
139+-- * 'empty' and 'mzero' work, but are terse and uninformative
140+--
141+-- * 'fail' produces a custom error message
142+--
143+-- * 'typeMismatch' produces an informative message for cases when the
144+-- value encountered is not of the expected type
134145--
135146-- An example type and instance:
136147--
@@ -144,8 +155,10 @@ class ToJSON a where
144155-- v '.:' \"x\" '<*>'
145156-- v '.:' \"y\"
146157--
147−-- \-- A non-'Object' value is of the wrong type, so use 'mzero' to fail.
148−-- parseJSON _ = 'mzero'
158+-- \-- A non-'Object' value is of the wrong type.
159+-- \-- We could use mzero to fail, but typeMismatch
160+-- \-- gives a much more informative error message.
161+-- parseJSON invalid = 'typeMismatch' \"Coord\" invalid
149162-- @
150163--
151164-- Note the use of the @OverloadedStrings@ language extension which enables
@@ -196,3 +209,28 @@ class FromJSON a where
196209class KeyValue t where
197210 (.=) :: ToJSON v => Text -> v -> t
198211 infixr 8 .=
212+
213+-- | Fail parsing due to a type mismatch, with a descriptive message.
214+--
215+-- Example usage:
216+--
217+-- @
218+--
219+-- instance FromJSON Coord where
220+-- parseJSON ('Object' v) = {- type matches, life is good -}
221+-- parseJSON wat = 'typeMismatch' \"Coord\" wat
222+-- @
223+typeMismatch :: String -- ^ The name of the type you are trying to parse.
224+ -> Value -- ^ The actual value encountered.
225+ -> Parser a
226+typeMismatch expected actual =
227+ fail $ "when expecting a " ++ expected ++ ", encountered " ++ name ++
228+ " instead"
229+ where
230+ name = case actual of
231+ Object _ -> "Object"
232+ Array _ -> "Array"
233+ String _ -> "String"
234+ Number _ -> "Number"
235+ Bool _ -> "Boolean"
236+ Null -> "Null"
Data/Aeson/Types/Instances.hs−16
@@ -1532,22 +1532,6 @@ obj .:? key = case H.lookup key obj of
15321532pmval .!= val = fromMaybe val <$> pmval
15331533{-# INLINE (.!=) #-}
15341534
1535−-- | Fail parsing due to a type mismatch, with a descriptive message.
1536−typeMismatch :: String -- ^ The name of the type you are trying to parse.
1537− -> Value -- ^ The actual value encountered.
1538− -> Parser a
1539−typeMismatch expected actual =
1540− fail $ "when expecting a " ++ expected ++ ", encountered " ++ name ++
1541− " instead"
1542− where
1543− name = case actual of
1544− Object _ -> "Object"
1545− Array _ -> "Array"
1546− String _ -> "String"
1547− Number _ -> "Number"
1548− Bool _ -> "Boolean"
1549− Null -> "Null"
1550−
15511535realFloatToJSON :: RealFloat a => a -> Value
15521536realFloatToJSON d
15531537 | isNaN d || isInfinite d = Null