on master help sign in
Un-orphan instances
commited2162a3e2f4110e8c312d645c029a6c1dea3172 authorOleg Grenrus <oleg.grenrus@iki.fi> dateMon 6 Jun 2016, 18:50 (10 years ago) parent26a4bfb
14 files changed+3798−3763
Data/Aeson.hs+1−1 Data/Aeson/Encode/Functions.hs+1−2 Data/Aeson/Internal.hs+1−1 Data/Aeson/Types.hs+5−3 Data/Aeson/Types/Class.hs+21−515 Data/Aeson/Types/FromJSON.hs+1633 Data/Aeson/Types/Generic.hs+20−738 Data/Aeson/Types/Instances.hs−1438 Data/Aeson/Types/Instances/Tuple.hs−926 Data/Aeson/Types/Internal.hs+1 Data/Aeson/Types/ToJSON.hs+2099 aeson.cabal+5−4 benchmarks/aeson-benchmarks.cabal+11−9 tuple-instances.hs−126
Data/Aeson.hs+1−1
@@ -103,12 +103,12 @@ module Data.Aeson
103103 , json'
104104 ) where
105105
106+import Data.Aeson.Types.FromJSON (ifromJSON)
106107import Data.Aeson.Encode (encode)
107108import Data.Aeson.Parser.Internal (decodeWith, decodeStrictWith,
108109 eitherDecodeWith, eitherDecodeStrictWith,
109110 jsonEOF, json, jsonEOF', json')
110111import Data.Aeson.Types
111−import Data.Aeson.Types.Instances (ifromJSON)
112112import Data.Aeson.Types.Internal (JSONPath, formatError)
113113import qualified Data.ByteString as B
114114import qualified Data.ByteString.Lazy as L
Data/Aeson/Encode/Functions.hs+1−2
@@ -10,6 +10,5 @@ import Data.Aeson.Types.Class
1010import Data.ByteString.Builder (Builder)
1111import Data.Monoid ((<>))
1212
13−builder :: ToJSON a => a -> Builder
14−builder = fromEncoding . toEncoding
13+
1514{-# INLINE builder #-}
Data/Aeson/Internal.hs+1−1
@@ -22,5 +22,5 @@ module Data.Aeson.Internal
2222 , iparse
2323 ) where
2424
25−import Data.Aeson.Types.Instances (ifromJSON)
2625import Data.Aeson.Types.Internal
26+import Data.Aeson.Types.FromJSON (ifromJSON)
Data/Aeson/Types.hs+5−3
@@ -94,12 +94,14 @@ module Data.Aeson.Types
9494 , defaultTaggedObject
9595 ) where
9696
97−import Data.Aeson.Types.Generic ()
98−import Data.Aeson.Types.Instances
97+import Prelude ()
98+import Prelude.Compat
99+
100+import Data.Aeson.Types.Class
99101import Data.Aeson.Types.Internal
100102import Data.Aeson.Encoding (Encoding, unsafeToEncoding, fromEncoding, Series, pairs)
101103
102−import Data.Foldable (Foldable, toList)
104+import Data.Foldable (toList)
103105
104106-- | Encode a 'Foldable' as a JSON array.
105107foldable :: (Foldable t, ToJSON a) => t a -> Encoding
Data/Aeson/Types/Class.hs+21−515
@@ -46,523 +46,29 @@ module Data.Aeson.Types.Class
4646 , mapFromJSONKeyFunction
4747 -- * Object key-value pairs
4848 , KeyValue(..)
49− -- * Functions needed for documentation
50− , typeMismatch
51− -- * Encoding functions
49+
50+ -- * List functions
5251 , listEncoding
5352 , listValue
5453 , listParser
55− ) where
56−
57−import Data.Aeson.Types.Internal
58−import Data.Aeson.Encoding.Internal (Encoding, Series)
59−import Data.Monoid ((<>))
60−import Data.Text (Text)
61−import GHC.Generics (Generic, Rep, from, to)
62−import qualified Data.Aeson.Encoding.Internal as E
63−import qualified Data.Aeson.Encode.Builder as EB
64−import qualified Data.Vector as V
65−
66−#if !MIN_VERSION_base(4,8,0)
67−import Data.Monoid (mempty)
68−#endif
69−
70−-- Coercible derivations aren't as powerful on GHC 7.8, though supported.
71−#define HAS_COERCIBLE (__GLASGOW_HASKELL__ >= 709)
72−
73−#if HAS_COERCIBLE
74−import Data.Coerce (Coercible, coerce)
75−coerce' :: Coercible a b => a -> b
76−coerce' = coerce
77−#else
78−import Unsafe.Coerce (unsafeCoerce)
79−coerce' :: a -> b
80−coerce' = unsafeCoerce
81−#endif
82−
83−-- | Class of generic representation types ('Rep') that can be converted to
84−-- JSON.
85−class GToJSON f where
86− -- | This method (applied to 'defaultOptions') is used as the
87− -- default generic implementation of 'toJSON'.
88− gToJSON :: Options -> f a -> Value
89−
90−-- | Class of generic representation types ('Rep') that can be converted to
91−-- a JSON 'Encoding'.
92−class GToEncoding f where
93− -- | This method (applied to 'defaultOptions') can be used as the
94− -- default generic implementation of 'toEncoding'.
95− gToEncoding :: Options -> f a -> Encoding
96−
97−-- | Class of generic representation types ('Rep') that can be converted from JSON.
98−class GFromJSON f where
99− -- | This method (applied to 'defaultOptions') is used as the
100− -- default generic implementation of 'parseJSON'.
101− gParseJSON :: Options -> Value -> Parser (f a)
102−
103−-- | A configurable generic JSON creator. This function applied to
104−-- 'defaultOptions' is used as the default for 'toJSON' when the type
105−-- is an instance of 'Generic'.
106−genericToJSON :: (Generic a, GToJSON (Rep a)) => Options -> a -> Value
107−genericToJSON opts = gToJSON opts . from
108−
109−-- | A configurable generic JSON encoder. This function applied to
110−-- 'defaultOptions' is used as the default for 'toEncoding' when the type
111−-- is an instance of 'Generic'.
112−genericToEncoding :: (Generic a, GToEncoding (Rep a)) => Options -> a -> Encoding
113−genericToEncoding opts = gToEncoding opts . from
114−
115−-- | A configurable generic JSON decoder. This function applied to
116−-- 'defaultOptions' is used as the default for 'parseJSON' when the
117−-- type is an instance of 'Generic'.
118−genericParseJSON :: (Generic a, GFromJSON (Rep a)) => Options -> Value -> Parser a
119−genericParseJSON opts = fmap to . gParseJSON opts
120−
121−-- | A type that can be converted to JSON.
122−--
123−-- An example type and instance:
124−--
125−-- @
126−-- \-- Allow ourselves to write 'Text' literals.
127−-- {-\# LANGUAGE OverloadedStrings #-}
128−--
129−-- data Coord = Coord { x :: Double, y :: Double }
130−--
131−-- instance ToJSON Coord where
132−-- toJSON (Coord x y) = 'object' [\"x\" '.=' x, \"y\" '.=' y]
133−--
134−-- toEncoding (Coord x y) = 'pairs' (\"x\" '.=' x '<>' \"y\" '.=' y)
135−-- @
136−--
137−-- Instead of manually writing your 'ToJSON' instance, there are two options
138−-- to do it automatically:
139−--
140−-- * "Data.Aeson.TH" provides Template Haskell functions which will derive an
141−-- instance at compile time. The generated instance is optimized for your type
142−-- so will probably be more efficient than the following two options:
143−--
144−-- * The compiler can provide a default generic implementation for
145−-- 'toJSON'.
146−--
147−-- To use the second, simply add a @deriving 'Generic'@ clause to your
148−-- datatype and declare a 'ToJSON' instance for your datatype without giving
149−-- definitions for 'toJSON' or 'toEncoding'.
150−--
151−-- For example, the previous example can be simplified to a more
152−-- minimal instance:
153−--
154−-- @
155−-- {-\# LANGUAGE DeriveGeneric \#-}
156−--
157−-- import "GHC.Generics"
158−--
159−-- data Coord = Coord { x :: Double, y :: Double } deriving 'Generic'
160−--
161−-- instance ToJSON Coord where
162−-- toEncoding = 'genericToEncoding' 'defaultOptions'
163−-- @
164−--
165−-- Why do we provide an implementation for 'toEncoding' here? The
166−-- 'toEncoding' function is a relatively new addition to this class.
167−-- To allow users of older versions of this library to upgrade without
168−-- having to edit all of their instances or encounter surprising
169−-- incompatibilities, the default implementation of 'toEncoding' uses
170−-- 'toJSON'. This produces correct results, but since it performs an
171−-- intermediate conversion to a 'Value', it will be less efficient
172−-- than directly emitting an 'Encoding'. Our one-liner definition of
173−-- 'toEncoding' above bypasses the intermediate 'Value'.
174−--
175−-- If @DefaultSignatures@ doesn't give exactly the results you want,
176−-- you can customize the generic encoding with only a tiny amount of
177−-- effort, using 'genericToJSON' and 'genericToEncoding' with your
178−-- preferred 'Options':
179−--
180−-- @
181−-- instance ToJSON Coord where
182−-- toJSON = 'genericToJSON' 'defaultOptions'
183−-- toEncoding = 'genericToEncoding' 'defaultOptions'
184−-- @
185−class ToJSON a where
186− -- | Convert a Haskell value to a JSON-friendly intermediate type.
187− toJSON :: a -> Value
188−
189− default toJSON :: (Generic a, GToJSON (Rep a)) => a -> Value
190− toJSON = genericToJSON defaultOptions
191−
192− -- | Encode a Haskell value as JSON.
193− --
194− -- The default implementation of this method creates an
195− -- intermediate 'Value' using 'toJSON'. This provides
196− -- source-level compatibility for people upgrading from older
197− -- versions of this library, but obviously offers no performance
198− -- advantage.
199− --
200− -- To benefit from direct encoding, you /must/ provide an
201− -- implementation for this method. The easiest way to do so is by
202− -- having your types implement 'Generic' using the @DeriveGeneric@
203− -- extension, and then have GHC generate a method body as follows.
204− --
205− -- @
206− -- instance ToJSON Coord where
207− -- toEncoding = 'genericToEncoding' 'defaultOptions'
208− -- @
209−
210− toEncoding :: a -> Encoding
211− toEncoding = E.Encoding . EB.encodeToBuilder . toJSON
212− {-# INLINE toEncoding #-}
213−
214− toJSONList :: [a] -> Value
215− toJSONList = listValue toJSON
216− {-# INLINE toJSONList #-}
217−
218− toEncodingList :: [a] -> Encoding
219− toEncodingList = listEncoding toEncoding
220− {-# INLINE toEncodingList #-}
221−
222−-- | A type that can be converted from JSON, with the possibility of
223−-- failure.
224−--
225−-- In many cases, you can get the compiler to generate parsing code
226−-- for you (see below). To begin, let's cover writing an instance by
227−-- hand.
228−--
229−-- There are various reasons a conversion could fail. For example, an
230−-- 'Object' could be missing a required key, an 'Array' could be of
231−-- the wrong size, or a value could be of an incompatible type.
232−--
233−-- The basic ways to signal a failed conversion are as follows:
234−--
235−-- * 'empty' and 'mzero' work, but are terse and uninformative
236−--
237−-- * 'fail' yields a custom error message
238−--
239−-- * 'typeMismatch' produces an informative message for cases when the
240−-- value encountered is not of the expected type
241−--
242−-- An example type and instance:
243−--
244−-- @
245−-- \-- Allow ourselves to write 'Text' literals.
246−-- {-\# LANGUAGE OverloadedStrings #-}
247−--
248−-- data Coord = Coord { x :: Double, y :: Double }
249−--
250−-- instance FromJSON Coord where
251−-- parseJSON ('Object' v) = Coord '<$>'
252−-- v '.:' \"x\" '<*>'
253−-- v '.:' \"y\"
254−--
255−-- \-- We do not expect a non-'Object' value here.
256−-- \-- We could use 'mzero' to fail, but 'typeMismatch'
257−-- \-- gives a much more informative error message.
258−-- parseJSON invalid = 'typeMismatch' \"Coord\" invalid
259−-- @
260−--
261−-- Instead of manually writing your 'FromJSON' instance, there are two options
262−-- to do it automatically:
263−--
264−-- * "Data.Aeson.TH" provides Template Haskell functions which will derive an
265−-- instance at compile time. The generated instance is optimized for your type
266−-- so will probably be more efficient than the following two options:
267−--
268−-- * The compiler can provide a default generic implementation for
269−-- 'parseJSON'.
270−--
271−-- To use the second, simply add a @deriving 'Generic'@ clause to your
272−-- datatype and declare a 'FromJSON' instance for your datatype without giving
273−-- a definition for 'parseJSON'.
274−--
275−-- For example, the previous example can be simplified to just:
276−--
277−-- @
278−-- {-\# LANGUAGE DeriveGeneric \#-}
279−--
280−-- import "GHC.Generics"
281−--
282−-- data Coord = Coord { x :: Double, y :: Double } deriving 'Generic'
283−--
284−-- instance FromJSON Coord
285−-- @
286−--
287−-- If @DefaultSignatures@ doesn't give exactly the results you want,
288−-- you can customize the generic decoding with only a tiny amount of
289−-- effort, using 'genericParseJSON' with your preferred 'Options':
290−--
291−-- @
292−-- instance FromJSON Coord where
293−-- parseJSON = 'genericParseJSON' 'defaultOptions'
294−-- @
295−
296−class FromJSON a where
297− parseJSON :: Value -> Parser a
298−
299− default parseJSON :: (Generic a, GFromJSON (Rep a)) => Value -> Parser a
300− parseJSON = genericParseJSON defaultOptions
301−
302− parseJSONList :: Value -> Parser [a]
303− parseJSONList (Array a)
304− = sequence
305− . zipWith parseIndexedJSON [0..]
306− . V.toList
307− $ a
308− where
309− parseIndexedJSON :: FromJSON a => Int -> Value -> Parser a
310− parseIndexedJSON idx value = parseJSON value <?> Index idx
311−
312− parseJSONList v = typeMismatch "[a]" v
313−
314−-------------------------------------------------------------------------------
315−-- Object key-value pairs
316−-------------------------------------------------------------------------------
317−
318−-- | A key-value pair for encoding a JSON object.
319−class KeyValue kv where
320− (.=) :: ToJSON v => Text -> v -> kv
321− infixr 8 .=
322−
323−instance KeyValue Series where
324− name .= value = E.Value $ E.text name <> E.colon <> toEncoding value
325− {-# INLINE (.=) #-}
326−
327−instance KeyValue Pair where
328− name .= value = (name, toJSON value)
329− {-# INLINE (.=) #-}
330−
331−-------------------------------------------------------------------------------
332−-- Classes and types for map keys
333−-------------------------------------------------------------------------------
334−
335−class ToJSONKey a where
336− toJSONKey :: ToJSONKeyFunction a
337− default toJSONKey :: ToJSON a => ToJSONKeyFunction a
338− toJSONKey = ToJSONKeyValue (toJSON, toEncoding)
339− toJSONKeyList :: ToJSONKeyFunction [a]
340− default toJSONKeyList :: ToJSON a => ToJSONKeyFunction [a]
341− toJSONKeyList = ToJSONKeyValue (toJSON, toEncoding)
34254
343−class FromJSONKey a where
344− fromJSONKey :: FromJSONKeyFunction a
345− default fromJSONKey :: FromJSON a => FromJSONKeyFunction a
346− fromJSONKey = FromJSONKeyValue parseJSON
347− fromJSONKeyList :: FromJSONKeyFunction [a]
348− default fromJSONKeyList :: FromJSON a => FromJSONKeyFunction [a]
349− fromJSONKeyList = FromJSONKeyValue parseJSON
350−
351−data ToJSONKeyFunction a
352− = ToJSONKeyText (a -> Text, a -> Encoding)
353− | ToJSONKeyValue (a -> Value, a -> Encoding)
354−
355−-- | With GHC 7.8 + we carry around 'Coercible Text a' dictionary,
356−-- to have even some amount of safety net.
357−-- Unfortunately we cannot enforce that 'Hashable' instance agree on the type level
358−--
359−-- ATM this type is intentionally not exported. FromJSONKeyFunction can be inspected,
360−-- but cannot be constructed.
361−data CoerceText a where
362−#if HAS_COERCIBLE
363− CoerceText :: Coercible Text a => CoerceText a
364−#else
365− CoerceText :: CoerceText a
366−#endif
367−
368−data FromJSONKeyFunction a
369− = FromJSONKeyCoerce (CoerceText a)
370− | FromJSONKeyText (Text -> a)
371− | FromJSONKeyTextParser (Text -> Parser a)
372− | FromJSONKeyValue (Value -> Parser a)
373−
374−instance Functor FromJSONKeyFunction where
375− fmap h (FromJSONKeyCoerce CoerceText) = FromJSONKeyText (h . coerce')
376− fmap h (FromJSONKeyText f) = FromJSONKeyText (h . f)
377− fmap h (FromJSONKeyTextParser f) = FromJSONKeyTextParser (fmap h . f)
378− fmap h (FromJSONKeyValue f) = FromJSONKeyValue (fmap h . f)
379−
380−-- | Construct 'FromJSONKeyFunction' for types coercible from 'Text'. This
381−-- conversion is still unsafe, as 'Hashable' and 'Eq' instances of @a@ should be
382−-- compatible with 'Text' i.e. hash values be equal for wrapped values as well.
383−fromJSONKeyCoerce ::
384−#if HAS_COERCIBLE
385− Coercible Text a =>
386−#endif
387− FromJSONKeyFunction a
388−fromJSONKeyCoerce = FromJSONKeyCoerce CoerceText
389−
390−coerceFromJSONKeyFunction ::
391−#if HAS_COERCIBLE
392− Coercible a b =>
393−#endif
394− FromJSONKeyFunction a -> FromJSONKeyFunction b
395−coerceFromJSONKeyFunction (FromJSONKeyCoerce CoerceText) = FromJSONKeyCoerce CoerceText
396−coerceFromJSONKeyFunction (FromJSONKeyText f) = FromJSONKeyText (coerce' . f)
397−coerceFromJSONKeyFunction (FromJSONKeyTextParser f) = FromJSONKeyTextParser (fmap coerce' . f)
398−coerceFromJSONKeyFunction (FromJSONKeyValue f) = FromJSONKeyValue (fmap coerce' . f)
399−
400−{-# RULES
401− "FromJSONKeyCoerce: fmap id" forall (x :: FromJSONKeyFunction a).
402− fmap id x = x
403− #-}
404−#if HAS_COERCIBLE
405−{-# RULES
406− "FromJSONKeyCoerce: fmap coerce" forall x .
407− fmap coerce x = coerceFromJSONKeyFunction x
408− #-}
409−#endif
410−
411−contramapToJSONKeyFunction :: (b -> a) -> ToJSONKeyFunction a -> ToJSONKeyFunction b
412−contramapToJSONKeyFunction h x = case x of
413− ToJSONKeyText (f,g) -> ToJSONKeyText (f . h, g . h)
414− ToJSONKeyValue (f,g) -> ToJSONKeyValue (f . h, g . h)
415−
416−mapFromJSONKeyFunction :: (a -> b) -> FromJSONKeyFunction a -> FromJSONKeyFunction b
417−mapFromJSONKeyFunction = fmap
418−
419−-------------------------------------------------------------------------------
420−-- Functions needed for documentation
421−-------------------------------------------------------------------------------
422−
423−-- | Fail parsing due to a type mismatch, with a descriptive message.
424−--
425−-- Example usage:
426−--
427−-- @
428−-- instance FromJSON Coord where
429−-- parseJSON ('Object' v) = {- type matches, life is good -}
430−-- parseJSON wat = 'typeMismatch' \"Coord\" wat
431−-- @
432−typeMismatch :: String -- ^ The name of the type you are trying to parse.
433− -> Value -- ^ The actual value encountered.
434− -> Parser a
435−typeMismatch expected actual =
436− fail $ "expected " ++ expected ++ ", encountered " ++ name
437− where
438− name = case actual of
439− Object _ -> "Object"
440− Array _ -> "Array"
441− String _ -> "String"
442− Number _ -> "Number"
443− Bool _ -> "Boolean"
444− Null -> "Null"
445−
446−-------------------------------------------------------------------------------
447−-- Lifings of FromJSON and ToJSON to unary and binary type constructors
448−-------------------------------------------------------------------------------
449−
450−-- | Lifting of the 'FromJSON' class to unary type constructors.
451−class FromJSON1 f where
452− liftParseJSON :: (Value -> Parser a) -> (Value -> Parser [a]) -> Value -> Parser (f a)
453− liftParseJSONList :: (Value -> Parser a) -> (Value -> Parser [a]) -> Value -> Parser [f a]
454− liftParseJSONList f g v = listParser (liftParseJSON f g) v
455−
456−-- | Lift the standard 'parseJSON' function through the type constructor.
457−parseJSON1 :: (FromJSON1 f, FromJSON a) => Value -> Parser (f a)
458−parseJSON1 = liftParseJSON parseJSON parseJSONList
459−{-# INLINE parseJSON1 #-}
460−
461−-- | Lifting of the 'ToJSON' class to unary type constructors.
462−class ToJSON1 f where
463− liftToJSON :: (a -> Value) -> ([a] -> Value) -> f a -> Value
464− liftToJSONList :: (a -> Value) -> ([a] -> Value) -> [f a] -> Value
465− liftToJSONList f g = listValue (liftToJSON f g)
466−
467− -- | Unfortunately there cannot be a default implementation of 'liftToEncoding'.
468− liftToEncoding :: (a -> Encoding) -> ([a] -> Encoding) -> f a -> Encoding
469− liftToEncodingList :: (a -> Encoding) -> ([a] -> Encoding) -> [f a] -> Encoding
470− liftToEncodingList f g = listEncoding (liftToEncoding f g)
471−
472−-- | Lift the standard 'toJSON' function through the type constructor.
473−toJSON1 :: (ToJSON1 f, ToJSON a) => f a -> Value
474−toJSON1 = liftToJSON toJSON toJSONList
475−{-# INLINE toJSON1 #-}
476−
477−-- | Lift the standard 'toEncoding' function through the type constructor.
478−toEncoding1 :: (ToJSON1 f, ToJSON a) => f a -> Encoding
479−toEncoding1 = liftToEncoding toEncoding toEncodingList
480−{-# INLINE toEncoding1 #-}
481−
482−
483−-- | Lifting of the 'FromJSON' class to binary type constructors.
484−class FromJSON2 f where
485− liftParseJSON2
486− :: (Value -> Parser a)
487− -> (Value -> Parser [a])
488− -> (Value -> Parser b)
489− -> (Value -> Parser [b])
490− -> Value -> Parser (f a b)
491− liftParseJSONList2
492− :: (Value -> Parser a)
493− -> (Value -> Parser [a])
494− -> (Value -> Parser b)
495− -> (Value -> Parser [b])
496− -> Value -> Parser [f a b]
497− liftParseJSONList2 fa ga fb gb v = case v of
498− Array vals -> fmap V.toList (V.mapM (liftParseJSON2 fa ga fb gb) vals)
499− _ -> typeMismatch "[a]" v
500−
501−-- | Lift the standard 'parseJSON' function through the type constructor.
502−parseJSON2 :: (FromJSON2 f, FromJSON a, FromJSON b) => Value -> Parser (f a b)
503−parseJSON2 = liftParseJSON2 parseJSON parseJSONList parseJSON parseJSONList
504−{-# INLINE parseJSON2 #-}
505−
506−-- | Lifting of the 'ToJSON' class to binary type constructors.
507−class ToJSON2 f where
508− liftToJSON2 :: (a -> Value) -> ([a] -> Value) -> (b -> Value) -> ([b] -> Value) -> f a b -> Value
509− liftToJSONList2 :: (a -> Value) -> ([a] -> Value) -> (b -> Value) -> ([b] -> Value) -> [f a b] -> Value
510− liftToJSONList2 fa ga fb gb = listValue (liftToJSON2 fa ga fb gb)
511−
512− liftToEncoding2 :: (a -> Encoding) -> ([a] -> Encoding) -> (b -> Encoding) -> ([b] -> Encoding) -> f a b -> Encoding
513− liftToEncodingList2 :: (a -> Encoding) -> ([a] -> Encoding) -> (b -> Encoding) -> ([b] -> Encoding) -> [f a b] -> Encoding
514− liftToEncodingList2 fa ga fb gb = listEncoding (liftToEncoding2 fa ga fb gb)
515−
516−-- | Lift the standard 'toJSON' function through the type constructor.
517−toJSON2 :: (ToJSON2 f, ToJSON a, ToJSON b) => f a b -> Value
518−toJSON2 = liftToJSON2 toJSON toJSONList toJSON toJSONList
519−{-# INLINE toJSON2 #-}
520−
521−-- | Lift the standard 'toEncoding' function through the type constructor.
522−toEncoding2 :: (ToJSON2 f, ToJSON a, ToJSON b) => f a b -> Encoding
523−toEncoding2 = liftToEncoding2 toEncoding toEncodingList toEncoding toEncodingList
524−{-# INLINE toEncoding2 #-}
525−
526−-------------------------------------------------------------------------------
527−-- Encoding functions
528−-------------------------------------------------------------------------------
529−
530−listEncoding :: (a -> Encoding) -> [a] -> Encoding
531−listEncoding = E.list
532−
533−listValue :: (a -> Value) -> [a] -> Value
534−listValue f = Array . V.fromList . map f
535−{-# INLINE listValue #-}
536−
537−listParser :: (Value -> Parser a) -> Value -> Parser [a]
538−listParser f (Array xs) = fmap V.toList (V.mapM f xs)
539−listParser _ v = typeMismatch "[a]" v
540−{-# INLINE listParser #-}
541−
542−-------------------------------------------------------------------------------
543−-- [] instances
544−-------------------------------------------------------------------------------
545−
546−-- These are needed for key-class default definitions
547−
548−instance ToJSON1 [] where
549− liftToJSON _ to' = to'
550− {-# INLINE liftToJSON #-}
551−
552− liftToEncoding _ to' = to'
553− {-# INLINE liftToEncoding #-}
554−
555−instance (ToJSON a) => ToJSON [a] where
556− toJSON = toJSON1
557− {-# INLINE toJSON #-}
558−
559− toEncoding = toEncoding1
560− {-# INLINE toEncoding #-}
561−
562−instance FromJSON1 [] where
563− liftParseJSON _ p' = p'
564− {-# INLINE liftParseJSON #-}
55+ -- * Inspecting @'Value's@
56+ , withObject
57+ , withText
58+ , withArray
59+ , withNumber
60+ , withScientific
61+ , withBool
62+
63+ -- * Functions
64+ , fromJSON
65+ , ifromJSON
66+ , (.:)
67+ , (.:?)
68+ , (.:!)
69+ , (.!=)
70+ , typeMismatch
71+ ) where
56572
566−instance (FromJSON a) => FromJSON [a] where
567− parseJSON = parseJSON1
568− {-# INLINE parseJSON #-}
73+import Data.Aeson.Types.FromJSON
74+import Data.Aeson.Types.ToJSON
Data/Aeson/Types/FromJSON.hsnew file+1633
@@ -0,0 +1,1633 @@
1+{-# LANGUAGE CPP #-}
2+{-# LANGUAGE DataKinds #-}
3+{-# LANGUAGE DefaultSignatures #-}
4+{-# LANGUAGE FlexibleContexts #-}
5+{-# LANGUAGE FlexibleInstances #-}
6+{-# LANGUAGE GADTs #-}
7+{-# LANGUAGE MultiParamTypeClasses #-}
8+{-# LANGUAGE NamedFieldPuns #-}
9+{-# LANGUAGE OverloadedStrings #-}
10+{-# LANGUAGE RecordWildCards #-}
11+{-# LANGUAGE ScopedTypeVariables #-}
12+{-# LANGUAGE TypeOperators #-}
13+{-# LANGUAGE TypeSynonymInstances #-}
14+{-# LANGUAGE UndecidableInstances #-}
15+{-# LANGUAGE ViewPatterns #-}
16+
17+#if __GLASGOW_HASKELL__ >= 706
18+{-# LANGUAGE PolyKinds #-}
19+#endif
20+
21+#include "overlapping-compat.h"
22+
23+-- TODO: Drop this when we remove support for Data.Attoparsec.Number
24+{-# OPTIONS_GHC -fno-warn-deprecations #-}
25+
26+module Data.Aeson.Types.FromJSON (
27+ -- * Core JSON classes
28+ FromJSON(..)
29+ -- * Liftings to unary and binary type constructors
30+ , FromJSON1(..)
31+ , parseJSON1
32+ , FromJSON2(..)
33+ , parseJSON2
34+ -- * Generic JSON classes
35+ , GFromJSON(..)
36+ , genericParseJSON
37+ -- * Classes and types for map keys
38+ , FromJSONKey(..)
39+ , FromJSONKeyFunction(..)
40+ , fromJSONKeyCoerce
41+ , coerceFromJSONKeyFunction
42+ , mapFromJSONKeyFunction
43+
44+ -- * List functions
45+ , listParser
46+
47+ -- * Inspecting @'Value's@
48+ , withObject
49+ , withText
50+ , withArray
51+ , withNumber
52+ , withScientific
53+ , withBool
54+
55+ -- * Functions
56+ , fromJSON
57+ , ifromJSON
58+ , (.:)
59+ , (.:?)
60+ , (.:!)
61+ , (.!=)
62+ , typeMismatch
63+ ) where
64+
65+import Prelude ()
66+import Prelude.Compat hiding (foldr)
67+
68+import Data.Aeson.Functions (mapKey)
69+import Data.Aeson.Types.Generic
70+import Data.Aeson.Types.Internal
71+
72+import qualified Data.Aeson.Parser.Time as Time
73+
74+import Control.Applicative (Const (..), (<|>))
75+import Control.Monad ((<=<))
76+import Data.Attoparsec.Number (Number (..))
77+import Data.Bits (unsafeShiftR)
78+import Data.Fixed (Fixed, HasResolution)
79+import Data.Functor.Identity (Identity (..))
80+import Data.Hashable (Hashable (..))
81+import Data.Int (Int16, Int32, Int64, Int8)
82+import Data.List.NonEmpty (NonEmpty (..))
83+import Data.Maybe (fromMaybe)
84+import Data.Monoid (Dual (..), First (..), Last (..), (<>))
85+import Data.Proxy (Proxy (..))
86+import Data.Ratio (Ratio, (%))
87+import Data.Scientific (Scientific)
88+import Data.Tagged (Tagged (..))
89+import Data.Text (Text, pack, unpack)
90+import Data.Time (Day, LocalTime, NominalDiffTime, TimeOfDay,
91+ UTCTime, ZonedTime)
92+import Data.Time.Format (parseTime)
93+import Data.Time.Locale.Compat (defaultTimeLocale)
94+import Data.Traversable as Tr (sequence)
95+import Data.Vector (Vector)
96+import Data.Version (Version, parseVersion)
97+import Data.Word (Word16, Word32, Word64, Word8)
98+import Foreign.Storable (Storable)
99+import GHC.Generics
100+import Numeric.Natural (Natural)
101+import Text.ParserCombinators.ReadP (readP_to_S)
102+
103+import qualified Data.HashMap.Strict as H
104+import qualified Data.HashSet as HashSet
105+import qualified Data.IntMap as IntMap
106+import qualified Data.IntSet as IntSet
107+import qualified Data.Map as M
108+import qualified Data.Scientific as Scientific
109+import qualified Data.Sequence as Seq
110+import qualified Data.Set as Set
111+import qualified Data.Text as T
112+import qualified Data.Text.Lazy as LT
113+import qualified Data.Text.Read as TR
114+import qualified Data.Tree as Tree
115+import qualified Data.Vector as V
116+import qualified Data.Vector.Generic as VG
117+import qualified Data.Vector.Primitive as VP
118+import qualified Data.Vector.Storable as VS
119+import qualified Data.Vector.Unboxed as VU
120+
121+import Unsafe.Coerce (unsafeCoerce)
122+
123+-- Coercible derivations aren't as powerful on GHC 7.8, though supported.
124+#ifndef HAS_COERCIBLE
125+#define HAS_COERCIBLE (__GLASGOW_HASKELL__ >= 709)
126+#endif
127+
128+#if HAS_COERCIBLE
129+import Data.Coerce (Coercible, coerce)
130+coerce' :: Coercible a b => a -> b
131+coerce' = coerce
132+#else
133+coerce' :: a -> b
134+coerce' = unsafeCoerce
135+#endif
136+
137+parseIndexedJSON :: (Value -> Parser a) -> Int -> Value -> Parser a
138+parseIndexedJSON p idx value = p value <?> Index idx
139+{-# INLINE parseIndexedJSON #-}
140+
141+parseIndexedJSONPair :: (Value -> Parser a) -> (Value -> Parser b) -> Int -> Value -> Parser (a, b)
142+parseIndexedJSONPair keyParser valParser idx value = p value <?> Index idx
143+ where
144+ p = withArray "(k,v)" $ \ab ->
145+ let n = V.length ab
146+ in if n == 2
147+ then (,) <$> parseJSONElemAtIndex keyParser 0 ab
148+ <*> parseJSONElemAtIndex valParser 1 ab
149+ else fail $ "cannot unpack array of length " ++
150+ show n ++ " into a pair"
151+{-# INLINE parseIndexedJSONPair #-}
152+
153+parseJSONElemAtIndex :: (Value -> Parser a) -> Int -> V.Vector Value -> Parser a
154+parseJSONElemAtIndex p idx ary = p (V.unsafeIndex ary idx) <?> Index idx
155+
156+scientificToNumber :: Scientific -> Number
157+scientificToNumber s
158+ | e < 0 = D $ Scientific.toRealFloat s
159+ | otherwise = I $ c * 10 ^ e
160+ where
161+ e = Scientific.base10Exponent s
162+ c = Scientific.coefficient s
163+{-# INLINE scientificToNumber #-}
164+
165+parseRealFloat :: RealFloat a => String -> Value -> Parser a
166+parseRealFloat _ (Number s) = pure $ Scientific.toRealFloat s
167+parseRealFloat _ Null = pure (0/0)
168+parseRealFloat expected v = typeMismatch expected v
169+{-# INLINE parseRealFloat #-}
170+
171+parseIntegral :: Integral a => String -> Value -> Parser a
172+parseIntegral expected = withScientific expected $ pure . truncate
173+{-# INLINE parseIntegral #-}
174+
175+-------------------------------------------------------------------------------
176+-- Generics
177+-------------------------------------------------------------------------------
178+
179+-- | Class of generic representation types ('Rep') that can be converted from JSON.
180+class GFromJSON f where
181+ -- | This method (applied to 'defaultOptions') is used as the
182+ -- default generic implementation of 'parseJSON'.
183+ gParseJSON :: Options -> Value -> Parser (f a)
184+
185+-- | A configurable generic JSON decoder. This function applied to
186+-- 'defaultOptions' is used as the default for 'parseJSON' when the
187+-- type is an instance of 'Generic'.
188+genericParseJSON :: (Generic a, GFromJSON (Rep a)) => Options -> Value -> Parser a
189+genericParseJSON opts = fmap to . gParseJSON opts
190+
191+-------------------------------------------------------------------------------
192+-- Class
193+-------------------------------------------------------------------------------
194+
195+-- | A type that can be converted from JSON, with the possibility of
196+-- failure.
197+--
198+-- In many cases, you can get the compiler to generate parsing code
199+-- for you (see below). To begin, let's cover writing an instance by
200+-- hand.
201+--
202+-- There are various reasons a conversion could fail. For example, an
203+-- 'Object' could be missing a required key, an 'Array' could be of
204+-- the wrong size, or a value could be of an incompatible type.
205+--
206+-- The basic ways to signal a failed conversion are as follows:
207+--
208+-- * 'empty' and 'mzero' work, but are terse and uninformative
209+--
210+-- * 'fail' yields a custom error message
211+--
212+-- * 'typeMismatch' produces an informative message for cases when the
213+-- value encountered is not of the expected type
214+--
215+-- An example type and instance:
216+--
217+-- @
218+-- \-- Allow ourselves to write 'Text' literals.
219+-- {-\# LANGUAGE OverloadedStrings #-}
220+--
221+-- data Coord = Coord { x :: Double, y :: Double }
222+--
223+-- instance FromJSON Coord where
224+-- parseJSON ('Object' v) = Coord '<$>'
225+-- v '.:' \"x\" '<*>'
226+-- v '.:' \"y\"
227+--
228+-- \-- We do not expect a non-'Object' value here.
229+-- \-- We could use 'mzero' to fail, but 'typeMismatch'
230+-- \-- gives a much more informative error message.
231+-- parseJSON invalid = 'typeMismatch' \"Coord\" invalid
232+-- @
233+--
234+-- Instead of manually writing your 'FromJSON' instance, there are two options
235+-- to do it automatically:
236+--
237+-- * "Data.Aeson.TH" provides Template Haskell functions which will derive an
238+-- instance at compile time. The generated instance is optimized for your type
239+-- so will probably be more efficient than the following two options:
240+--
241+-- * The compiler can provide a default generic implementation for
242+-- 'parseJSON'.
243+--
244+-- To use the second, simply add a @deriving 'Generic'@ clause to your
245+-- datatype and declare a 'FromJSON' instance for your datatype without giving
246+-- a definition for 'parseJSON'.
247+--
248+-- For example, the previous example can be simplified to just:
249+--
250+-- @
251+-- {-\# LANGUAGE DeriveGeneric \#-}
252+--
253+-- import "GHC.Generics"
254+--
255+-- data Coord = Coord { x :: Double, y :: Double } deriving 'Generic'
256+--
257+-- instance FromJSON Coord
258+-- @
259+--
260+-- If @DefaultSignatures@ doesn't give exactly the results you want,
261+-- you can customize the generic decoding with only a tiny amount of
262+-- effort, using 'genericParseJSON' with your preferred 'Options':
263+--
264+-- @
265+-- instance FromJSON Coord where
266+-- parseJSON = 'genericParseJSON' 'defaultOptions'
267+-- @
268+
269+class FromJSON a where
270+ parseJSON :: Value -> Parser a
271+
272+ default parseJSON :: (Generic a, GFromJSON (Rep a)) => Value -> Parser a
273+ parseJSON = genericParseJSON defaultOptions
274+
275+ parseJSONList :: Value -> Parser [a]
276+ parseJSONList (Array a)
277+ = sequence
278+ . zipWith (parseIndexedJSON parseJSON) [0..]
279+ . V.toList
280+ $ a
281+
282+ parseJSONList v = typeMismatch "[a]" v
283+
284+
285+-------------------------------------------------------------------------------
286+-- Classes and types for map keys
287+-------------------------------------------------------------------------------
288+
289+class FromJSONKey a where
290+ fromJSONKey :: FromJSONKeyFunction a
291+ default fromJSONKey :: FromJSON a => FromJSONKeyFunction a
292+ fromJSONKey = FromJSONKeyValue parseJSON
293+ fromJSONKeyList :: FromJSONKeyFunction [a]
294+ default fromJSONKeyList :: FromJSON a => FromJSONKeyFunction [a]
295+ fromJSONKeyList = FromJSONKeyValue parseJSON
296+
297+-- | With GHC 7.8 + we carry around 'Coercible Text a' dictionary,
298+-- to have even some amount of safety net.
299+-- Unfortunately we cannot enforce that 'Hashable' instance agree on the type level
300+--
301+-- ATM this type is intentionally not exported. FromJSONKeyFunction can be inspected,
302+-- but cannot be constructed.
303+data CoerceText a where
304+#if HAS_COERCIBLE
305+ CoerceText :: Coercible Text a => CoerceText a
306+#else
307+ CoerceText :: CoerceText a
308+#endif
309+
310+data FromJSONKeyFunction a
311+ = FromJSONKeyCoerce (CoerceText a)
312+ | FromJSONKeyText (Text -> a)
313+ | FromJSONKeyTextParser (Text -> Parser a)
314+ | FromJSONKeyValue (Value -> Parser a)
315+
316+instance Functor FromJSONKeyFunction where
317+ fmap h (FromJSONKeyCoerce CoerceText) = FromJSONKeyText (h . coerce')
318+ fmap h (FromJSONKeyText f) = FromJSONKeyText (h . f)
319+ fmap h (FromJSONKeyTextParser f) = FromJSONKeyTextParser (fmap h . f)
320+ fmap h (FromJSONKeyValue f) = FromJSONKeyValue (fmap h . f)
321+
322+-- | Construct 'FromJSONKeyFunction' for types coercible from 'Text'. This
323+-- conversion is still unsafe, as 'Hashable' and 'Eq' instances of @a@ should be
324+-- compatible with 'Text' i.e. hash values be equal for wrapped values as well.
325+fromJSONKeyCoerce ::
326+#if HAS_COERCIBLE
327+ Coercible Text a =>
328+#endif
329+ FromJSONKeyFunction a
330+fromJSONKeyCoerce = FromJSONKeyCoerce CoerceText
331+
332+coerceFromJSONKeyFunction ::
333+#if HAS_COERCIBLE
334+ Coercible a b =>
335+#endif
336+ FromJSONKeyFunction a -> FromJSONKeyFunction b
337+coerceFromJSONKeyFunction (FromJSONKeyCoerce CoerceText) = FromJSONKeyCoerce CoerceText
338+coerceFromJSONKeyFunction (FromJSONKeyText f) = FromJSONKeyText (coerce' . f)
339+coerceFromJSONKeyFunction (FromJSONKeyTextParser f) = FromJSONKeyTextParser (fmap coerce' . f)
340+coerceFromJSONKeyFunction (FromJSONKeyValue f) = FromJSONKeyValue (fmap coerce' . f)
341+
342+{-# RULES
343+ "FromJSONKeyCoerce: fmap id" forall (x :: FromJSONKeyFunction a).
344+ fmap id x = x
345+ #-}
346+#if HAS_COERCIBLE
347+{-# RULES
348+ "FromJSONKeyCoerce: fmap coerce" forall x .
349+ fmap coerce x = coerceFromJSONKeyFunction x
350+ #-}
351+#endif
352+
353+mapFromJSONKeyFunction :: (a -> b) -> FromJSONKeyFunction a -> FromJSONKeyFunction b
354+mapFromJSONKeyFunction = fmap
355+
356+-------------------------------------------------------------------------------
357+-- Functions needed for documentation
358+-------------------------------------------------------------------------------
359+
360+-- | Fail parsing due to a type mismatch, with a descriptive message.
361+--
362+-- Example usage:
363+--
364+-- @
365+-- instance FromJSON Coord where
366+-- parseJSON ('Object' v) = {- type matches, life is good -}
367+-- parseJSON wat = 'typeMismatch' \"Coord\" wat
368+-- @
369+typeMismatch :: String -- ^ The name of the type you are trying to parse.
370+ -> Value -- ^ The actual value encountered.
371+ -> Parser a
372+typeMismatch expected actual =
373+ fail $ "expected " ++ expected ++ ", encountered " ++ name
374+ where
375+ name = case actual of
376+ Object _ -> "Object"
377+ Array _ -> "Array"
378+ String _ -> "String"
379+ Number _ -> "Number"
380+ Bool _ -> "Boolean"
381+ Null -> "Null"
382+
383+-------------------------------------------------------------------------------
384+-- Lifings of FromJSON and ToJSON to unary and binary type constructors
385+-------------------------------------------------------------------------------
386+
387+-- | Lifting of the 'FromJSON' class to unary type constructors.
388+class FromJSON1 f where
389+ liftParseJSON :: (Value -> Parser a) -> (Value -> Parser [a]) -> Value -> Parser (f a)
390+ liftParseJSONList :: (Value -> Parser a) -> (Value -> Parser [a]) -> Value -> Parser [f a]
391+ liftParseJSONList f g v = listParser (liftParseJSON f g) v
392+
393+-- | Lift the standard 'parseJSON' function through the type constructor.
394+parseJSON1 :: (FromJSON1 f, FromJSON a) => Value -> Parser (f a)
395+parseJSON1 = liftParseJSON parseJSON parseJSONList
396+{-# INLINE parseJSON1 #-}
397+
398+
399+-- | Lifting of the 'FromJSON' class to binary type constructors.
400+class FromJSON2 f where
401+ liftParseJSON2
402+ :: (Value -> Parser a)
403+ -> (Value -> Parser [a])
404+ -> (Value -> Parser b)
405+ -> (Value -> Parser [b])
406+ -> Value -> Parser (f a b)
407+ liftParseJSONList2
408+ :: (Value -> Parser a)
409+ -> (Value -> Parser [a])
410+ -> (Value -> Parser b)
411+ -> (Value -> Parser [b])
412+ -> Value -> Parser [f a b]
413+ liftParseJSONList2 fa ga fb gb v = case v of
414+ Array vals -> fmap V.toList (V.mapM (liftParseJSON2 fa ga fb gb) vals)
415+ _ -> typeMismatch "[a]" v
416+
417+-- | Lift the standard 'parseJSON' function through the type constructor.
418+parseJSON2 :: (FromJSON2 f, FromJSON a, FromJSON b) => Value -> Parser (f a b)
419+parseJSON2 = liftParseJSON2 parseJSON parseJSONList parseJSON parseJSONList
420+{-# INLINE parseJSON2 #-}
421+
422+-------------------------------------------------------------------------------
423+-- List functions
424+-------------------------------------------------------------------------------
425+
426+listParser :: (Value -> Parser a) -> Value -> Parser [a]
427+listParser f (Array xs) = fmap V.toList (V.mapM f xs)
428+listParser _ v = typeMismatch "[a]" v
429+{-# INLINE listParser #-}
430+
431+-------------------------------------------------------------------------------
432+-- [] instances
433+-------------------------------------------------------------------------------
434+
435+instance FromJSON1 [] where
436+ liftParseJSON _ p' = p'
437+ {-# INLINE liftParseJSON #-}
438+
439+instance (FromJSON a) => FromJSON [a] where
440+ parseJSON = parseJSON1
441+
442+-------------------------------------------------------------------------------
443+-- Functions
444+-------------------------------------------------------------------------------
445+
446+-- | @withObject expected f value@ applies @f@ to the 'Object' when @value@ is an @Object@
447+-- and fails using @'typeMismatch' expected@ otherwise.
448+withObject :: String -> (Object -> Parser a) -> Value -> Parser a
449+withObject _ f (Object obj) = f obj
450+withObject expected _ v = typeMismatch expected v
451+{-# INLINE withObject #-}
452+
453+-- | @withText expected f value@ applies @f@ to the 'Text' when @value@ is a @String@
454+-- and fails using @'typeMismatch' expected@ otherwise.
455+withText :: String -> (Text -> Parser a) -> Value -> Parser a
456+withText _ f (String txt) = f txt
457+withText expected _ v = typeMismatch expected v
458+{-# INLINE withText #-}
459+
460+-- | @withArray expected f value@ applies @f@ to the 'Array' when @value@ is an @Array@
461+-- and fails using @'typeMismatch' expected@ otherwise.
462+withArray :: String -> (Array -> Parser a) -> Value -> Parser a
463+withArray _ f (Array arr) = f arr
464+withArray expected _ v = typeMismatch expected v
465+{-# INLINE withArray #-}
466+
467+-- | @withNumber expected f value@ applies @f@ to the 'Number' when @value@ is a 'Number'.
468+-- and fails using @'typeMismatch' expected@ otherwise.
469+withNumber :: String -> (Number -> Parser a) -> Value -> Parser a
470+withNumber expected f = withScientific expected (f . scientificToNumber)
471+{-# INLINE withNumber #-}
472+{-# DEPRECATED withNumber "Use withScientific instead" #-}
473+
474+-- | @withScientific expected f value@ applies @f@ to the 'Scientific' number when @value@ is a 'Number'.
475+-- and fails using @'typeMismatch' expected@ otherwise.
476+withScientific :: String -> (Scientific -> Parser a) -> Value -> Parser a
477+withScientific _ f (Number scientific) = f scientific
478+withScientific expected _ v = typeMismatch expected v
479+{-# INLINE withScientific #-}
480+
481+-- | @withBool expected f value@ applies @f@ to the 'Bool' when @value@ is a @Bool@
482+-- and fails using @'typeMismatch' expected@ otherwise.
483+withBool :: String -> (Bool -> Parser a) -> Value -> Parser a
484+withBool _ f (Bool arr) = f arr
485+withBool expected _ v = typeMismatch expected v
486+{-# INLINE withBool #-}
487+
488+-- | Convert a value from JSON, failing if the types do not match.
489+fromJSON :: (FromJSON a) => Value -> Result a
490+fromJSON = parse parseJSON
491+{-# INLINE fromJSON #-}
492+
493+-- | Convert a value from JSON, failing if the types do not match.
494+ifromJSON :: (FromJSON a) => Value -> IResult a
495+ifromJSON = iparse parseJSON
496+{-# INLINE ifromJSON #-}
497+
498+-- | Retrieve the value associated with the given key of an 'Object'.
499+-- The result is 'empty' if the key is not present or the value cannot
500+-- be converted to the desired type.
501+--
502+-- This accessor is appropriate if the key and value /must/ be present
503+-- in an object for it to be valid. If the key and value are
504+-- optional, use '.:?' instead.
505+(.:) :: (FromJSON a) => Object -> Text -> Parser a
506+obj .: key = case H.lookup key obj of
507+ Nothing -> fail $ "key " ++ show key ++ " not present"
508+ Just v -> parseJSON v <?> Key key
509+{-# INLINE (.:) #-}
510+
511+-- | Retrieve the value associated with the given key of an 'Object'.
512+-- The result is 'Nothing' if the key is not present, or 'empty' if
513+-- the value cannot be converted to the desired type.
514+--
515+-- This accessor is most useful if the key and value can be absent
516+-- from an object without affecting its validity. If the key and
517+-- value are mandatory, use '.:' instead.
518+(.:?) :: (FromJSON a) => Object -> Text -> Parser (Maybe a)
519+obj .:? key = case H.lookup key obj of
520+ Nothing -> pure Nothing
521+ Just v -> parseJSON v <?> Key key
522+{-# INLINE (.:?) #-}
523+
524+-- | Like '.:?', but the resulting parser will fail,
525+-- if the key is present but is 'Null'.
526+(.:!) :: (FromJSON a) => Object -> Text -> Parser (Maybe a)
527+obj .:! key = case H.lookup key obj of
528+ Nothing -> pure Nothing
529+ Just v -> Just <$> parseJSON v <?> Key key
530+{-# INLINE (.:!) #-}
531+
532+-- | Helper for use in combination with '.:?' to provide default
533+-- values for optional JSON object fields.
534+--
535+-- This combinator is most useful if the key and value can be absent
536+-- from an object without affecting its validity and we know a default
537+-- value to assign in that case. If the key and value are mandatory,
538+-- use '.:' instead.
539+--
540+-- Example usage:
541+--
542+-- @ v1 <- o '.:?' \"opt_field_with_dfl\" .!= \"default_val\"
543+-- v2 <- o '.:' \"mandatory_field\"
544+-- v3 <- o '.:?' \"opt_field2\"
545+-- @
546+(.!=) :: Parser (Maybe a) -> a -> Parser a
547+pmval .!= val = fromMaybe val <$> pmval
548+{-# INLINE (.!=) #-}
549+
550+--------------------------------------------------------------------------------
551+-- Generic parseJSON
552+-------------------------------------------------------------------------------
553+
554+instance OVERLAPPABLE_ (GFromJSON a) => GFromJSON (M1 i c a) where
555+ -- Meta-information, which is not handled elsewhere, is just added to the
556+ -- parsed value:
557+ gParseJSON opts = fmap M1 . gParseJSON opts
558+
559+instance (FromJSON a) => GFromJSON (K1 i a) where
560+ -- Constant values are decoded using their FromJSON instance:
561+ gParseJSON _opts = fmap K1 . parseJSON
562+
563+instance GFromJSON U1 where
564+ -- Empty constructors are expected to be encoded as an empty array:
565+ gParseJSON _opts v
566+ | isEmptyArray v = pure U1
567+ | otherwise = typeMismatch "unit constructor (U1)" v
568+
569+instance (ConsFromJSON a) => GFromJSON (C1 c a) where
570+ -- Constructors need to be decoded differently depending on whether they're
571+ -- a record or not. This distinction is made by consParseJSON:
572+ gParseJSON opts = fmap M1 . consParseJSON opts
573+
574+instance ( FromProduct a, FromProduct b
575+ , ProductSize a, ProductSize b ) => GFromJSON (a :*: b) where
576+ -- Products are expected to be encoded to an array. Here we check whether we
577+ -- got an array of the same size as the product, then parse each of the
578+ -- product's elements using parseProduct:
579+ gParseJSON opts = withArray "product (:*:)" $ \arr ->
580+ let lenArray = V.length arr
581+ lenProduct = (unTagged2 :: Tagged2 (a :*: b) Int -> Int)
582+ productSize in
583+ if lenArray == lenProduct
584+ then parseProduct opts arr 0 lenProduct
585+ else fail $ "When expecting a product of " ++ show lenProduct ++
586+ " values, encountered an Array of " ++ show lenArray ++
587+ " elements instead"
588+
589+instance ( AllNullary (a :+: b) allNullary
590+ , ParseSum (a :+: b) allNullary ) => GFromJSON (a :+: b) where
591+ -- If all constructors of a sum datatype are nullary and the
592+ -- 'allNullaryToStringTag' option is set they are expected to be
593+ -- encoded as strings. This distinction is made by 'parseSum':
594+ gParseJSON opts = (unTagged :: Tagged allNullary (Parser ((a :+: b) d)) ->
595+ (Parser ((a :+: b) d)))
596+ . parseSum opts
597+
598+--------------------------------------------------------------------------------
599+
600+class ParseSum f allNullary where
601+ parseSum :: Options -> Value -> Tagged allNullary (Parser (f a))
602+
603+instance ( SumFromString (a :+: b)
604+ , FromPair (a :+: b)
605+ , FromTaggedObject (a :+: b) ) => ParseSum (a :+: b) True where
606+ parseSum opts
607+ | allNullaryToStringTag opts = Tagged . parseAllNullarySum opts
608+ | otherwise = Tagged . parseNonAllNullarySum opts
609+
610+instance ( FromPair (a :+: b)
611+ , FromTaggedObject (a :+: b) ) => ParseSum (a :+: b) False where
612+ parseSum opts = Tagged . parseNonAllNullarySum opts
613+
614+--------------------------------------------------------------------------------
615+
616+parseAllNullarySum :: SumFromString f => Options -> Value -> Parser (f a)
617+parseAllNullarySum opts = withText "Text" $ \key ->
618+ maybe (notFound key) return $
619+ parseSumFromString opts key
620+
621+class SumFromString f where
622+ parseSumFromString :: Options -> Text -> Maybe (f a)
623+
624+instance (SumFromString a, SumFromString b) => SumFromString (a :+: b) where
625+ parseSumFromString opts key = (L1 <$> parseSumFromString opts key) <|>
626+ (R1 <$> parseSumFromString opts key)
627+
628+instance (Constructor c) => SumFromString (C1 c U1) where
629+ parseSumFromString opts key | key == name = Just $ M1 U1
630+ | otherwise = Nothing
631+ where
632+ name = pack $ constructorTagModifier opts $
633+ conName (undefined :: t c U1 p)
634+
635+--------------------------------------------------------------------------------
636+
637+parseNonAllNullarySum :: ( FromPair (a :+: b)
638+ , FromTaggedObject (a :+: b)
639+ ) => Options -> Value -> Parser ((a :+: b) c)
640+parseNonAllNullarySum opts =
641+ case sumEncoding opts of
642+ TaggedObject{..} ->
643+ withObject "Object" $ \obj -> do
644+ tag <- obj .: pack tagFieldName
645+ fromMaybe (notFound tag) $
646+ parseFromTaggedObject opts contentsFieldName obj tag
647+
648+ ObjectWithSingleField ->
649+ withObject "Object" $ \obj ->
650+ case H.toList obj of
651+ [pair@(tag, _)] -> fromMaybe (notFound tag) $
652+ parsePair opts pair
653+ _ -> fail "Object doesn't have a single field"
654+
655+ TwoElemArray ->
656+ withArray "Array" $ \arr ->
657+ if V.length arr == 2
658+ then case V.unsafeIndex arr 0 of
659+ String tag -> fromMaybe (notFound tag) $
660+ parsePair opts (tag, V.unsafeIndex arr 1)
661+ _ -> fail "First element is not a String"
662+ else fail "Array doesn't have 2 elements"
663+
664+--------------------------------------------------------------------------------
665+
666+class FromTaggedObject f where
667+ parseFromTaggedObject :: Options -> String -> Object -> Text
668+ -> Maybe (Parser (f a))
669+
670+instance (FromTaggedObject a, FromTaggedObject b) =>
671+ FromTaggedObject (a :+: b) where
672+ parseFromTaggedObject opts contentsFieldName obj tag =
673+ (fmap L1 <$> parseFromTaggedObject opts contentsFieldName obj tag) <|>
674+ (fmap R1 <$> parseFromTaggedObject opts contentsFieldName obj tag)
675+
676+instance ( FromTaggedObject' f
677+ , Constructor c ) => FromTaggedObject (C1 c f) where
678+ parseFromTaggedObject opts contentsFieldName obj tag
679+ | tag == name = Just $ M1 <$> parseFromTaggedObject'
680+ opts contentsFieldName obj
681+ | otherwise = Nothing
682+ where
683+ name = pack $ constructorTagModifier opts $
684+ conName (undefined :: t c f p)
685+
686+--------------------------------------------------------------------------------
687+
688+class FromTaggedObject' f where
689+ parseFromTaggedObject' :: Options -> String -> Object -> Parser (f a)
690+
691+class FromTaggedObject'' f isRecord where
692+ parseFromTaggedObject'' :: Options -> String -> Object
693+ -> Tagged isRecord (Parser (f a))
694+
695+instance ( IsRecord f isRecord
696+ , FromTaggedObject'' f isRecord
697+ ) => FromTaggedObject' f where
698+ parseFromTaggedObject' opts contentsFieldName =
699+ (unTagged :: Tagged isRecord (Parser (f a)) -> Parser (f a)) .
700+ parseFromTaggedObject'' opts contentsFieldName
701+
702+instance (FromRecord f) => FromTaggedObject'' f True where
703+ parseFromTaggedObject'' opts _ = Tagged . parseRecord opts Nothing
704+
705+instance (GFromJSON f) => FromTaggedObject'' f False where
706+ parseFromTaggedObject'' opts contentsFieldName = Tagged .
707+ (gParseJSON opts <=< (.: pack contentsFieldName))
708+
709+instance OVERLAPPING_ FromTaggedObject'' U1 False where
710+ parseFromTaggedObject'' _ _ _ = Tagged (pure U1)
711+
712+--------------------------------------------------------------------------------
713+
714+class ConsFromJSON f where
715+ consParseJSON :: Options -> Value -> Parser (f a)
716+
717+class ConsFromJSON' f isRecord where
718+ consParseJSON' :: Options -> (Maybe Text) -- ^ A dummy label
719+ -- (Nothing to use proper label)
720+ -> Value -> Tagged isRecord (Parser (f a))
721+
722+instance ( IsRecord f isRecord
723+ , ConsFromJSON' f isRecord
724+ ) => ConsFromJSON f where
725+ consParseJSON opts v = let
726+ (v2,lab) = case (unwrapUnaryRecords opts,isUnary (undefined :: f a)) of
727+ -- use a dummy object with a dummy label
728+ (True,True) -> ((object [(pack "dummy",v)]),Just $ pack "dummy")
729+ _ ->(v,Nothing)
730+ in (unTagged :: Tagged isRecord (Parser (f a)) -> Parser (f a))
731+ $ consParseJSON' opts lab v2
732+
733+
734+instance (FromRecord f) => ConsFromJSON' f True where
735+ consParseJSON' opts mlab = Tagged . (withObject "record (:*:)"
736+ $ parseRecord opts mlab)
737+
738+instance (GFromJSON f) => ConsFromJSON' f False where
739+ consParseJSON' opts _ = Tagged . gParseJSON opts
740+
741+--------------------------------------------------------------------------------
742+
743+class FromRecord f where
744+ parseRecord :: Options -> (Maybe Text) -- ^ A dummy label
745+ -- (Nothing to use proper label)
746+ -> Object -> Parser (f a)
747+
748+instance (FromRecord a, FromRecord b) => FromRecord (a :*: b) where
749+ parseRecord opts _ obj = (:*:) <$> parseRecord opts Nothing obj
750+ <*> parseRecord opts Nothing obj
751+
752+instance (Selector s, GFromJSON a) => FromRecord (S1 s a) where
753+ parseRecord opts lab = (<?> Key label) . gParseJSON opts <=< (.: label)
754+ where
755+ label = fromMaybe defLabel lab
756+ defLabel = pack . fieldLabelModifier opts $
757+ selName (undefined :: t s a p)
758+
759+instance OVERLAPPING_ (Selector s, FromJSON a) =>
760+ FromRecord (S1 s (K1 i (Maybe a))) where
761+ parseRecord _ (Just lab) obj = (M1 . K1) <$> obj .:? lab
762+ parseRecord opts Nothing obj = (M1 . K1) <$> obj .:? pack label
763+ where
764+ label = fieldLabelModifier opts $
765+ selName (undefined :: t s (K1 i (Maybe a)) p)
766+
767+--------------------------------------------------------------------------------
768+
769+class FromProduct f where
770+ parseProduct :: Options -> Array -> Int -> Int -> Parser (f a)
771+
772+instance (FromProduct a, FromProduct b) => FromProduct (a :*: b) where
773+ parseProduct opts arr ix len =
774+ (:*:) <$> parseProduct opts arr ix lenL
775+ <*> parseProduct opts arr ixR lenR
776+ where
777+ lenL = len `unsafeShiftR` 1
778+ ixR = ix + lenL
779+ lenR = len - lenL
780+
781+instance (GFromJSON a) => FromProduct (S1 s a) where
782+ parseProduct opts arr ix _ = gParseJSON opts $ V.unsafeIndex arr ix
783+
784+--------------------------------------------------------------------------------
785+
786+class FromPair f where
787+ parsePair :: Options -> Pair -> Maybe (Parser (f a))
788+
789+instance (FromPair a, FromPair b) => FromPair (a :+: b) where
790+ parsePair opts pair = (fmap L1 <$> parsePair opts pair) <|>
791+ (fmap R1 <$> parsePair opts pair)
792+
793+instance (Constructor c, GFromJSON a, ConsFromJSON a) => FromPair (C1 c a) where
794+ parsePair opts (tag, value)
795+ | tag == tag' = Just $ gParseJSON opts value
796+ | otherwise = Nothing
797+ where
798+ tag' = pack $ constructorTagModifier opts $
799+ conName (undefined :: t c a p)
800+
801+--------------------------------------------------------------------------------
802+
803+notFound :: Text -> Parser a
804+notFound key = fail $ "The key \"" ++ unpack key ++ "\" was not found"
805+{-# INLINE notFound #-}
806+
807+-------------------------------------------------------------------------------
808+-- Instances
809+-------------------------------------------------------------------------------
810+
811+-------------------------------------------------------------------------------
812+-- base
813+-------------------------------------------------------------------------------
814+
815+instance FromJSON1 Identity where
816+ liftParseJSON p _ a = Identity <$> p a
817+ {-# INLINE liftParseJSON #-}
818+
819+instance (FromJSON a) => FromJSON (Identity a) where
820+ parseJSON = parseJSON1
821+ {-# INLINE parseJSON #-}
822+
823+instance FromJSON2 Const where
824+ liftParseJSON2 p _ _ _ = fmap Const . p
825+ {-# INLINE liftParseJSON2 #-}
826+
827+instance FromJSON a => FromJSON1 (Const a) where
828+ liftParseJSON _ _ = fmap Const . parseJSON
829+ {-# INLINE liftParseJSON #-}
830+
831+instance FromJSON a => FromJSON (Const a b) where
832+ {-# INLINE parseJSON #-}
833+ parseJSON = fmap Const . parseJSON
834+
835+
836+instance FromJSON1 Maybe where
837+ liftParseJSON _ _ Null = pure Nothing
838+ liftParseJSON p _ a = Just <$> p a
839+ {-# INLINE liftParseJSON #-}
840+
841+instance (FromJSON a) => FromJSON (Maybe a) where
842+ parseJSON = parseJSON1
843+ {-# INLINE parseJSON #-}
844+
845+
846+
847+instance FromJSON2 Either where
848+ liftParseJSON2 pA _ pB _ (Object (H.toList -> [(key, value)]))
849+ | key == left = Left <$> pA value <?> Key left
850+ | key == right = Right <$> pB value <?> Key right
851+
852+ liftParseJSON2 _ _ _ _ _ = fail $
853+ "expected an object with a single property " ++
854+ "where the property key should be either " ++
855+ "\"Left\" or \"Right\""
856+ {-# INLINE liftParseJSON2 #-}
857+
858+instance (FromJSON a) => FromJSON1 (Either a) where
859+ liftParseJSON = liftParseJSON2 parseJSON parseJSONList
860+ {-# INLINE liftParseJSON #-}
861+
862+instance (FromJSON a, FromJSON b) => FromJSON (Either a b) where
863+ parseJSON = parseJSON2
864+ {-# INLINE parseJSON #-}
865+
866+left, right :: Text
867+left = "Left"
868+right = "Right"
869+
870+
871+instance FromJSON Bool where
872+ parseJSON = withBool "Bool" pure
873+ {-# INLINE parseJSON #-}
874+
875+instance FromJSON Ordering where
876+ parseJSON = withText "Ordering" $ \s ->
877+ case s of
878+ "LT" -> return LT
879+ "EQ" -> return EQ
880+ "GT" -> return GT
881+ _ -> fail "Parsing Ordering value failed: expected \"LT\", \"EQ\", or \"GT\""
882+
883+instance FromJSON () where
884+ parseJSON = withArray "()" $ \v ->
885+ if V.null v
886+ then pure ()
887+ else fail "Expected an empty array"
888+ {-# INLINE parseJSON #-}
889+
890+instance FromJSON Char where
891+ parseJSON = withText "Char" $ \t ->
892+ if T.compareLength t 1 == EQ
893+ then pure $ T.head t
894+ else fail "Expected a string of length 1"
895+ {-# INLINE parseJSON #-}
896+
897+ parseJSONList = withText "String" $ pure . T.unpack
898+ {-# INLINE parseJSONList #-}
899+
900+instance FromJSON Double where
901+ parseJSON = parseRealFloat "Double"
902+ {-# INLINE parseJSON #-}
903+
904+instance FromJSON Number where
905+ parseJSON (Number s) = pure $ scientificToNumber s
906+ parseJSON Null = pure (D (0/0))
907+ parseJSON v = typeMismatch "Number" v
908+ {-# INLINE parseJSON #-}
909+
910+instance FromJSON Float where
911+ parseJSON = parseRealFloat "Float"
912+ {-# INLINE parseJSON #-}
913+
914+instance FromJSON (Ratio Integer) where
915+ parseJSON = withObject "Rational" $ \obj ->
916+ (%) <$> obj .: "numerator"
917+ <*> obj .: "denominator"
918+ {-# INLINE parseJSON #-}
919+
920+-- | /WARNING:/ Only parse fixed-precision numbers from trusted input
921+-- since an attacker could easily fill up the memory of the target
922+-- system by specifying a scientific number with a big exponent like
923+-- @1e1000000000@.
924+instance HasResolution a => FromJSON (Fixed a) where
925+ parseJSON = withScientific "Fixed" $ pure . realToFrac
926+ {-# INLINE parseJSON #-}
927+
928+instance FromJSON Int where
929+ parseJSON = parseIntegral "Int"
930+ {-# INLINE parseJSON #-}
931+
932+-- | /WARNING:/ Only parse Integers from trusted input since an
933+-- attacker could easily fill up the memory of the target system by
934+-- specifying a scientific number with a big exponent like
935+-- @1e1000000000@.
936+instance FromJSON Integer where
937+ parseJSON = withScientific "Integral" $ pure . truncate
938+ {-# INLINE parseJSON #-}
939+
940+instance FromJSON Natural where
941+ parseJSON = withScientific "Natural" $ \s ->
942+ if Scientific.coefficient s < 0
943+ then fail $ "Expected a Natural number but got the negative number: " <> show s
944+ else pure $ truncate s
945+
946+instance FromJSON Int8 where
947+ parseJSON = parseIntegral "Int8"
948+ {-# INLINE parseJSON #-}
949+
950+instance FromJSON Int16 where
951+ parseJSON = parseIntegral "Int16"
952+ {-# INLINE parseJSON #-}
953+
954+instance FromJSON Int32 where
955+ parseJSON = parseIntegral "Int32"
956+ {-# INLINE parseJSON #-}
957+
958+instance FromJSON Int64 where
959+ parseJSON = parseIntegral "Int64"
960+ {-# INLINE parseJSON #-}
961+
962+instance FromJSON Word where
963+ parseJSON = parseIntegral "Word"
964+ {-# INLINE parseJSON #-}
965+
966+instance FromJSON Word8 where
967+ parseJSON = parseIntegral "Word8"
968+ {-# INLINE parseJSON #-}
969+
970+instance FromJSON Word16 where
971+ parseJSON = parseIntegral "Word16"
972+ {-# INLINE parseJSON #-}
973+
974+instance FromJSON Word32 where
975+ parseJSON = parseIntegral "Word32"
976+ {-# INLINE parseJSON #-}
977+
978+instance FromJSON Word64 where
979+ parseJSON = parseIntegral "Word64"
980+ {-# INLINE parseJSON #-}
981+
982+instance FromJSON Text where
983+ parseJSON = withText "Text" pure
984+ {-# INLINE parseJSON #-}
985+
986+instance FromJSON LT.Text where
987+ parseJSON = withText "Lazy Text" $ pure . LT.fromStrict
988+ {-# INLINE parseJSON #-}
989+
990+instance FromJSON Version where
991+ {-# INLINE parseJSON #-}
992+ parseJSON = withText "Version" $ go . readP_to_S parseVersion . unpack
993+ where
994+ go [(v,[])] = return v
995+ go (_ : xs) = go xs
996+ go _ = fail $ "could not parse Version"
997+
998+-------------------------------------------------------------------------------
999+-- semigroups NonEmpty
1000+-------------------------------------------------------------------------------
1001+
1002+instance FromJSON1 NonEmpty where
1003+ liftParseJSON p _ = withArray "NonEmpty a" $
1004+ (>>= ne) . Tr.sequence . zipWith (parseIndexedJSON p) [0..] . V.toList
1005+ where
1006+ ne [] = fail "Expected a NonEmpty but got an empty list"
1007+ ne (x:xs) = pure (x :| xs)
1008+ {-# INLINE liftParseJSON #-}
1009+
1010+instance (FromJSON a) => FromJSON (NonEmpty a) where
1011+ parseJSON = parseJSON1
1012+ {-# INLINE parseJSON #-}
1013+
1014+-------------------------------------------------------------------------------
1015+-- scientific
1016+-------------------------------------------------------------------------------
1017+
1018+instance FromJSON Scientific where
1019+ parseJSON = withScientific "Scientific" pure
1020+ {-# INLINE parseJSON #-}
1021+
1022+-------------------------------------------------------------------------------
1023+-- containers
1024+-------------------------------------------------------------------------------
1025+
1026+instance FromJSON1 Seq.Seq where
1027+ liftParseJSON p _ = withArray "Seq a" $
1028+ fmap Seq.fromList .
1029+ Tr.sequence . zipWith (parseIndexedJSON p) [0..] . V.toList
1030+ {-# INLINE liftParseJSON #-}
1031+
1032+instance (FromJSON a) => FromJSON (Seq.Seq a) where
1033+ parseJSON = parseJSON1
1034+ {-# INLINE parseJSON #-}
1035+
1036+
1037+instance (Ord a, FromJSON a) => FromJSON (Set.Set a) where
1038+ parseJSON = fmap Set.fromList . parseJSON
1039+ {-# INLINE parseJSON #-}
1040+
1041+
1042+instance FromJSON IntSet.IntSet where
1043+ parseJSON = fmap IntSet.fromList . parseJSON
1044+ {-# INLINE parseJSON #-}
1045+
1046+
1047+instance FromJSON1 IntMap.IntMap where
1048+ liftParseJSON p pl = fmap IntMap.fromList . liftParseJSON p' pl'
1049+ where
1050+ p' = liftParseJSON2 parseJSON parseJSONList p pl
1051+ pl' = liftParseJSONList2 parseJSON parseJSONList p pl
1052+ {-# INLINE liftParseJSON #-}
1053+
1054+instance FromJSON a => FromJSON (IntMap.IntMap a) where
1055+ parseJSON = fmap IntMap.fromList . parseJSON
1056+ {-# INLINE parseJSON #-}
1057+
1058+
1059+instance (FromJSONKey k, Ord k) => FromJSON1 (M.Map k) where
1060+ liftParseJSON p _ = case fromJSONKey of
1061+ FromJSONKeyCoerce _-> withObject "Map k v" $
1062+ fmap (H.foldrWithKey (M.insert . unsafeCoerce) M.empty) . H.traverseWithKey (\k v -> p v <?> Key k)
1063+ FromJSONKeyText f -> withObject "Map k v" $
1064+ fmap (H.foldrWithKey (M.insert . f) M.empty) . H.traverseWithKey (\k v -> p v <?> Key k)
1065+ FromJSONKeyTextParser f -> withObject "Map k v" $
1066+ H.foldrWithKey (\k v m -> M.insert <$> f k <*> (p v <?> Key k) <*> m) (pure M.empty)
1067+ FromJSONKeyValue f -> withArray "Map k v" $ \arr ->
1068+ M.fromList <$> (Tr.sequence .
1069+ zipWith (parseIndexedJSONPair f p) [0..] . V.toList $ arr)
1070+ {-# INLINE liftParseJSON #-}
1071+
1072+instance (FromJSONKey k, Ord k, FromJSON v) => FromJSON (M.Map k v) where
1073+ parseJSON = parseJSON1
1074+ {-# INLINE parseJSON #-}
1075+
1076+
1077+instance FromJSON1 Tree.Tree where
1078+ liftParseJSON p pl = go
1079+ where
1080+ go v = uncurry Tree.Node <$> liftParseJSON2 p pl p' pl' v
1081+
1082+ p' = liftParseJSON go (listParser go)
1083+ pl'= liftParseJSONList go (listParser go)
1084+
1085+instance (FromJSON v) => FromJSON (Tree.Tree v) where
1086+ parseJSON = parseJSON1
1087+ {-# INLINE parseJSON #-}
1088+
1089+-------------------------------------------------------------------------------
1090+-- vector
1091+-------------------------------------------------------------------------------
1092+
1093+instance FromJSON1 Vector where
1094+ liftParseJSON p _ = withArray "Vector a" $
1095+ V.mapM (uncurry $ parseIndexedJSON p) . V.indexed
1096+ {-# INLINE liftParseJSON #-}
1097+
1098+instance (FromJSON a) => FromJSON (Vector a) where
1099+ parseJSON = parseJSON1
1100+ {-# INLINE parseJSON #-}
1101+
1102+
1103+vectorParseJSON :: (FromJSON a, VG.Vector w a) => String -> Value -> Parser (w a)
1104+vectorParseJSON s = withArray s $ fmap V.convert . V.mapM (uncurry $ parseIndexedJSON parseJSON) . V.indexed
1105+{-# INLINE vectorParseJSON #-}
1106+
1107+instance (Storable a, FromJSON a) => FromJSON (VS.Vector a) where
1108+ parseJSON = vectorParseJSON "Data.Vector.Storable.Vector a"
1109+
1110+instance (VP.Prim a, FromJSON a) => FromJSON (VP.Vector a) where
1111+ parseJSON = vectorParseJSON "Data.Vector.Primitive.Vector a"
1112+ {-# INLINE parseJSON #-}
1113+
1114+instance (VG.Vector VU.Vector a, FromJSON a) => FromJSON (VU.Vector a) where
1115+ parseJSON = vectorParseJSON "Data.Vector.Unboxed.Vector a"
1116+ {-# INLINE parseJSON #-}
1117+
1118+-------------------------------------------------------------------------------
1119+-- unordered-containers
1120+-------------------------------------------------------------------------------
1121+
1122+instance (Eq a, Hashable a, FromJSON a) => FromJSON (HashSet.HashSet a) where
1123+ parseJSON = fmap HashSet.fromList . parseJSON
1124+ {-# INLINE parseJSON #-}
1125+
1126+
1127+instance (FromJSONKey k, Eq k, Hashable k) => FromJSON1 (H.HashMap k) where
1128+ liftParseJSON p _ = case fromJSONKey of
1129+ FromJSONKeyCoerce _ -> withObject "HashMap ~Text v" $
1130+ uc . H.traverseWithKey (\k v -> p v <?> Key k)
1131+ FromJSONKeyText f -> withObject "HashMap k v" $
1132+ fmap (mapKey f) . H.traverseWithKey (\k v -> p v <?> Key k)
1133+ FromJSONKeyTextParser f -> withObject "HashMap k v" $
1134+ H.foldrWithKey (\k v m -> H.insert <$> f k <*> (p v <?> Key k) <*> m) (pure H.empty)
1135+ FromJSONKeyValue f -> withArray "Map k v" $ \arr ->
1136+ H.fromList <$> (Tr.sequence .
1137+ zipWith (parseIndexedJSONPair f p) [0..] . V.toList $ arr)
1138+ where
1139+ uc :: Parser (H.HashMap Text v) -> Parser (H.HashMap k v)
1140+ uc = unsafeCoerce
1141+
1142+instance (FromJSON v, FromJSONKey k, Eq k, Hashable k) => FromJSON (H.HashMap k v) where
1143+ parseJSON = parseJSON1
1144+ {-# INLINE parseJSON #-}
1145+
1146+-------------------------------------------------------------------------------
1147+-- aeson
1148+-------------------------------------------------------------------------------
1149+
1150+instance FromJSON Value where
1151+ parseJSON = pure
1152+ {-# INLINE parseJSON #-}
1153+
1154+instance FromJSON DotNetTime where
1155+ parseJSON = withText "DotNetTime" $ \t ->
1156+ let (s,m) = T.splitAt (T.length t - 5) t
1157+ t' = T.concat [s,".",m]
1158+ in case parseTime defaultTimeLocale "/Date(%s%Q)/" (unpack t') of
1159+ Just d -> pure (DotNetTime d)
1160+ _ -> fail "could not parse .NET time"
1161+ {-# INLINE parseJSON #-}
1162+
1163+-------------------------------------------------------------------------------
1164+-- time
1165+-------------------------------------------------------------------------------
1166+
1167+instance FromJSON Day where
1168+ parseJSON = withText "Day" (Time.run Time.day)
1169+
1170+instance FromJSON TimeOfDay where
1171+ parseJSON = withText "TimeOfDay" (Time.run Time.timeOfDay)
1172+
1173+instance FromJSON LocalTime where
1174+ parseJSON = withText "LocalTime" (Time.run Time.localTime)
1175+
1176+instance FromJSON ZonedTime where
1177+ parseJSON = withText "ZonedTime" (Time.run Time.zonedTime)
1178+
1179+instance FromJSON UTCTime where
1180+ parseJSON = withText "UTCTime" (Time.run Time.utcTime)
1181+
1182+-- | /WARNING:/ Only parse lengths of time from trusted input
1183+-- since an attacker could easily fill up the memory of the target
1184+-- system by specifying a scientific number with a big exponent like
1185+-- @1e1000000000@.
1186+instance FromJSON NominalDiffTime where
1187+ parseJSON = withScientific "NominalDiffTime" $ pure . realToFrac
1188+ {-# INLINE parseJSON #-}
1189+
1190+-------------------------------------------------------------------------------
1191+-- base Monoid/Semigroup
1192+-------------------------------------------------------------------------------
1193+
1194+instance FromJSON1 Dual where
1195+ liftParseJSON p _ = fmap Dual . p
1196+ {-# INLINE liftParseJSON #-}
1197+
1198+instance FromJSON a => FromJSON (Dual a) where
1199+ parseJSON = parseJSON1
1200+ {-# INLINE parseJSON #-}
1201+
1202+
1203+instance FromJSON1 First where
1204+ liftParseJSON p p' = fmap First . liftParseJSON p p'
1205+ {-# INLINE liftParseJSON #-}
1206+
1207+instance FromJSON a => FromJSON (First a) where
1208+ parseJSON = parseJSON1
1209+ {-# INLINE parseJSON #-}
1210+
1211+
1212+instance FromJSON1 Last where
1213+ liftParseJSON p p' = fmap Last . liftParseJSON p p'
1214+ {-# INLINE liftParseJSON #-}
1215+
1216+instance FromJSON a => FromJSON (Last a) where
1217+ parseJSON = parseJSON1
1218+ {-# INLINE parseJSON #-}
1219+
1220+-------------------------------------------------------------------------------
1221+-- tagged
1222+-------------------------------------------------------------------------------
1223+
1224+instance FromJSON (Proxy a) where
1225+ {-# INLINE parseJSON #-}
1226+ parseJSON Null = pure Proxy
1227+ parseJSON v = typeMismatch "Proxy" v
1228+
1229+
1230+instance FromJSON1 (Tagged a) where
1231+ liftParseJSON p _ = fmap Tagged . p
1232+ {-# INLINE liftParseJSON #-}
1233+
1234+instance FromJSON b => FromJSON (Tagged a b) where
1235+ parseJSON = parseJSON1
1236+ {-# INLINE parseJSON #-}
1237+
1238+instance FromJSONKey b => FromJSONKey (Tagged a b) where
1239+ fromJSONKey = coerceFromJSONKeyFunction (fromJSONKey :: FromJSONKeyFunction b)
1240+ fromJSONKeyList = (fmap . fmap) Tagged fromJSONKeyList
1241+
1242+-------------------------------------------------------------------------------
1243+-- Instances for converting from map keys
1244+-------------------------------------------------------------------------------
1245+
1246+instance FromJSONKey Text where
1247+ fromJSONKey = fromJSONKeyCoerce
1248+
1249+instance FromJSONKey Int where
1250+ -- not sure if there if there is already a helper in
1251+ -- aeson for doing this.
1252+ fromJSONKey = FromJSONKeyTextParser $ \t -> case TR.decimal t of
1253+ Left err -> fail err
1254+ Right (v,t2) -> if T.null t2
1255+ then return v
1256+ else fail "Was not an integer, had extra stuff."
1257+
1258+instance (FromJSON a, FromJSON b) => FromJSONKey (a,b)
1259+instance (FromJSON a, FromJSON b, FromJSON c) => FromJSONKey (a,b,c)
1260+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d) => FromJSONKey (a,b,c,d)
1261+
1262+instance FromJSONKey Char where
1263+ fromJSONKey = FromJSONKeyTextParser $ \t ->
1264+ if T.length t == 1
1265+ then return (T.index t 0)
1266+ else typeMismatch "Expected Char but String didn't contain exactly one character" (String t)
1267+ fromJSONKeyList = FromJSONKeyText T.unpack
1268+
1269+instance (FromJSONKey a, FromJSON a) => FromJSONKey [a] where
1270+ fromJSONKey = fromJSONKeyList
1271+
1272+instance (FromJSONKey a, FromJSON a) => FromJSONKey (Identity a) where
1273+ fromJSONKey = mapFromJSONKeyFunction Identity fromJSONKey
1274+
1275+-------------------------------------------------------------------------------
1276+-- Tuple instances, see tuple-instances-from.hs
1277+-------------------------------------------------------------------------------
1278+
1279+instance FromJSON2 ((,) ) where
1280+ liftParseJSON2 pA _ pB _ = withArray "(a, b)" $ \t ->
1281+ let n = V.length t
1282+ in if n == 2
1283+ then (,)
1284+ <$> parseJSONElemAtIndex pA 0 t
1285+ <*> parseJSONElemAtIndex pB 1 t
1286+ else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 2"
1287+ {-# INLINE liftParseJSON2 #-}
1288+
1289+instance (FromJSON a) => FromJSON1 ((,) a) where
1290+ liftParseJSON = liftParseJSON2 parseJSON parseJSONList
1291+ {-# INLINE liftParseJSON #-}
1292+
1293+instance (FromJSON a, FromJSON b) => FromJSON (a, b) where
1294+ parseJSON = parseJSON2
1295+ {-# INLINE parseJSON #-}
1296+
1297+
1298+instance (FromJSON a) => FromJSON2 ((,,) a) where
1299+ liftParseJSON2 pB _ pC _ = withArray "(a, b, c)" $ \t ->
1300+ let n = V.length t
1301+ in if n == 3
1302+ then (,,)
1303+ <$> parseJSONElemAtIndex parseJSON 0 t
1304+ <*> parseJSONElemAtIndex pB 1 t
1305+ <*> parseJSONElemAtIndex pC 2 t
1306+ else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 3"
1307+ {-# INLINE liftParseJSON2 #-}
1308+
1309+instance (FromJSON a, FromJSON b) => FromJSON1 ((,,) a b) where
1310+ liftParseJSON = liftParseJSON2 parseJSON parseJSONList
1311+ {-# INLINE liftParseJSON #-}
1312+
1313+instance (FromJSON a, FromJSON b, FromJSON c) => FromJSON (a, b, c) where
1314+ parseJSON = parseJSON2
1315+ {-# INLINE parseJSON #-}
1316+
1317+
1318+instance (FromJSON a, FromJSON b) => FromJSON2 ((,,,) a b) where
1319+ liftParseJSON2 pC _ pD _ = withArray "(a, b, c, d)" $ \t ->
1320+ let n = V.length t
1321+ in if n == 4
1322+ then (,,,)
1323+ <$> parseJSONElemAtIndex parseJSON 0 t
1324+ <*> parseJSONElemAtIndex parseJSON 1 t
1325+ <*> parseJSONElemAtIndex pC 2 t
1326+ <*> parseJSONElemAtIndex pD 3 t
1327+ else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 4"
1328+ {-# INLINE liftParseJSON2 #-}
1329+
1330+instance (FromJSON a, FromJSON b, FromJSON c) => FromJSON1 ((,,,) a b c) where
1331+ liftParseJSON = liftParseJSON2 parseJSON parseJSONList
1332+ {-# INLINE liftParseJSON #-}
1333+
1334+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d) => FromJSON (a, b, c, d) where
1335+ parseJSON = parseJSON2
1336+ {-# INLINE parseJSON #-}
1337+
1338+
1339+instance (FromJSON a, FromJSON b, FromJSON c) => FromJSON2 ((,,,,) a b c) where
1340+ liftParseJSON2 pD _ pE _ = withArray "(a, b, c, d, e)" $ \t ->
1341+ let n = V.length t
1342+ in if n == 5
1343+ then (,,,,)
1344+ <$> parseJSONElemAtIndex parseJSON 0 t
1345+ <*> parseJSONElemAtIndex parseJSON 1 t
1346+ <*> parseJSONElemAtIndex parseJSON 2 t
1347+ <*> parseJSONElemAtIndex pD 3 t
1348+ <*> parseJSONElemAtIndex pE 4 t
1349+ else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 5"
1350+ {-# INLINE liftParseJSON2 #-}
1351+
1352+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d) => FromJSON1 ((,,,,) a b c d) where
1353+ liftParseJSON = liftParseJSON2 parseJSON parseJSONList
1354+ {-# INLINE liftParseJSON #-}
1355+
1356+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e) => FromJSON (a, b, c, d, e) where
1357+ parseJSON = parseJSON2
1358+ {-# INLINE parseJSON #-}
1359+
1360+
1361+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d) => FromJSON2 ((,,,,,) a b c d) where
1362+ liftParseJSON2 pE _ pF _ = withArray "(a, b, c, d, e, f)" $ \t ->
1363+ let n = V.length t
1364+ in if n == 6
1365+ then (,,,,,)
1366+ <$> parseJSONElemAtIndex parseJSON 0 t
1367+ <*> parseJSONElemAtIndex parseJSON 1 t
1368+ <*> parseJSONElemAtIndex parseJSON 2 t
1369+ <*> parseJSONElemAtIndex parseJSON 3 t
1370+ <*> parseJSONElemAtIndex pE 4 t
1371+ <*> parseJSONElemAtIndex pF 5 t
1372+ else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 6"
1373+ {-# INLINE liftParseJSON2 #-}
1374+
1375+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e) => FromJSON1 ((,,,,,) a b c d e) where
1376+ liftParseJSON = liftParseJSON2 parseJSON parseJSONList
1377+ {-# INLINE liftParseJSON #-}
1378+
1379+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f) => FromJSON (a, b, c, d, e, f) where
1380+ parseJSON = parseJSON2
1381+ {-# INLINE parseJSON #-}
1382+
1383+
1384+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e) => FromJSON2 ((,,,,,,) a b c d e) where
1385+ liftParseJSON2 pF _ pG _ = withArray "(a, b, c, d, e, f, g)" $ \t ->
1386+ let n = V.length t
1387+ in if n == 7
1388+ then (,,,,,,)
1389+ <$> parseJSONElemAtIndex parseJSON 0 t
1390+ <*> parseJSONElemAtIndex parseJSON 1 t
1391+ <*> parseJSONElemAtIndex parseJSON 2 t
1392+ <*> parseJSONElemAtIndex parseJSON 3 t
1393+ <*> parseJSONElemAtIndex parseJSON 4 t
1394+ <*> parseJSONElemAtIndex pF 5 t
1395+ <*> parseJSONElemAtIndex pG 6 t
1396+ else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 7"
1397+ {-# INLINE liftParseJSON2 #-}
1398+
1399+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f) => FromJSON1 ((,,,,,,) a b c d e f) where
1400+ liftParseJSON = liftParseJSON2 parseJSON parseJSONList
1401+ {-# INLINE liftParseJSON #-}
1402+
1403+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g) => FromJSON (a, b, c, d, e, f, g) where
1404+ parseJSON = parseJSON2
1405+ {-# INLINE parseJSON #-}
1406+
1407+
1408+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f) => FromJSON2 ((,,,,,,,) a b c d e f) where
1409+ liftParseJSON2 pG _ pH _ = withArray "(a, b, c, d, e, f, g, h)" $ \t ->
1410+ let n = V.length t
1411+ in if n == 8
1412+ then (,,,,,,,)
1413+ <$> parseJSONElemAtIndex parseJSON 0 t
1414+ <*> parseJSONElemAtIndex parseJSON 1 t
1415+ <*> parseJSONElemAtIndex parseJSON 2 t
1416+ <*> parseJSONElemAtIndex parseJSON 3 t
1417+ <*> parseJSONElemAtIndex parseJSON 4 t
1418+ <*> parseJSONElemAtIndex parseJSON 5 t
1419+ <*> parseJSONElemAtIndex pG 6 t
1420+ <*> parseJSONElemAtIndex pH 7 t
1421+ else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 8"
1422+ {-# INLINE liftParseJSON2 #-}
1423+
1424+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g) => FromJSON1 ((,,,,,,,) a b c d e f g) where
1425+ liftParseJSON = liftParseJSON2 parseJSON parseJSONList
1426+ {-# INLINE liftParseJSON #-}
1427+
1428+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h) => FromJSON (a, b, c, d, e, f, g, h) where
1429+ parseJSON = parseJSON2
1430+ {-# INLINE parseJSON #-}
1431+
1432+
1433+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g) => FromJSON2 ((,,,,,,,,) a b c d e f g) where
1434+ liftParseJSON2 pH _ pI _ = withArray "(a, b, c, d, e, f, g, h, i)" $ \t ->
1435+ let n = V.length t
1436+ in if n == 9
1437+ then (,,,,,,,,)
1438+ <$> parseJSONElemAtIndex parseJSON 0 t
1439+ <*> parseJSONElemAtIndex parseJSON 1 t
1440+ <*> parseJSONElemAtIndex parseJSON 2 t
1441+ <*> parseJSONElemAtIndex parseJSON 3 t
1442+ <*> parseJSONElemAtIndex parseJSON 4 t
1443+ <*> parseJSONElemAtIndex parseJSON 5 t
1444+ <*> parseJSONElemAtIndex parseJSON 6 t
1445+ <*> parseJSONElemAtIndex pH 7 t
1446+ <*> parseJSONElemAtIndex pI 8 t
1447+ else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 9"
1448+ {-# INLINE liftParseJSON2 #-}
1449+
1450+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h) => FromJSON1 ((,,,,,,,,) a b c d e f g h) where
1451+ liftParseJSON = liftParseJSON2 parseJSON parseJSONList
1452+ {-# INLINE liftParseJSON #-}
1453+
1454+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i) => FromJSON (a, b, c, d, e, f, g, h, i) where
1455+ parseJSON = parseJSON2
1456+ {-# INLINE parseJSON #-}
1457+
1458+
1459+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h) => FromJSON2 ((,,,,,,,,,) a b c d e f g h) where
1460+ liftParseJSON2 pI _ pJ _ = withArray "(a, b, c, d, e, f, g, h, i, j)" $ \t ->
1461+ let n = V.length t
1462+ in if n == 10
1463+ then (,,,,,,,,,)
1464+ <$> parseJSONElemAtIndex parseJSON 0 t
1465+ <*> parseJSONElemAtIndex parseJSON 1 t
1466+ <*> parseJSONElemAtIndex parseJSON 2 t
1467+ <*> parseJSONElemAtIndex parseJSON 3 t
1468+ <*> parseJSONElemAtIndex parseJSON 4 t
1469+ <*> parseJSONElemAtIndex parseJSON 5 t
1470+ <*> parseJSONElemAtIndex parseJSON 6 t
1471+ <*> parseJSONElemAtIndex parseJSON 7 t
1472+ <*> parseJSONElemAtIndex pI 8 t
1473+ <*> parseJSONElemAtIndex pJ 9 t
1474+ else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 10"
1475+ {-# INLINE liftParseJSON2 #-}
1476+
1477+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i) => FromJSON1 ((,,,,,,,,,) a b c d e f g h i) where
1478+ liftParseJSON = liftParseJSON2 parseJSON parseJSONList
1479+ {-# INLINE liftParseJSON #-}
1480+
1481+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j) => FromJSON (a, b, c, d, e, f, g, h, i, j) where
1482+ parseJSON = parseJSON2
1483+ {-# INLINE parseJSON #-}
1484+
1485+
1486+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i) => FromJSON2 ((,,,,,,,,,,) a b c d e f g h i) where
1487+ liftParseJSON2 pJ _ pK _ = withArray "(a, b, c, d, e, f, g, h, i, j, k)" $ \t ->
1488+ let n = V.length t
1489+ in if n == 11
1490+ then (,,,,,,,,,,)
1491+ <$> parseJSONElemAtIndex parseJSON 0 t
1492+ <*> parseJSONElemAtIndex parseJSON 1 t
1493+ <*> parseJSONElemAtIndex parseJSON 2 t
1494+ <*> parseJSONElemAtIndex parseJSON 3 t
1495+ <*> parseJSONElemAtIndex parseJSON 4 t
1496+ <*> parseJSONElemAtIndex parseJSON 5 t
1497+ <*> parseJSONElemAtIndex parseJSON 6 t
1498+ <*> parseJSONElemAtIndex parseJSON 7 t
1499+ <*> parseJSONElemAtIndex parseJSON 8 t
1500+ <*> parseJSONElemAtIndex pJ 9 t
1501+ <*> parseJSONElemAtIndex pK 10 t
1502+ else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 11"
1503+ {-# INLINE liftParseJSON2 #-}
1504+
1505+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j) => FromJSON1 ((,,,,,,,,,,) a b c d e f g h i j) where
1506+ liftParseJSON = liftParseJSON2 parseJSON parseJSONList
1507+ {-# INLINE liftParseJSON #-}
1508+
1509+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k) => FromJSON (a, b, c, d, e, f, g, h, i, j, k) where
1510+ parseJSON = parseJSON2
1511+ {-# INLINE parseJSON #-}
1512+
1513+
1514+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j) => FromJSON2 ((,,,,,,,,,,,) a b c d e f g h i j) where
1515+ liftParseJSON2 pK _ pL _ = withArray "(a, b, c, d, e, f, g, h, i, j, k, l)" $ \t ->
1516+ let n = V.length t
1517+ in if n == 12
1518+ then (,,,,,,,,,,,)
1519+ <$> parseJSONElemAtIndex parseJSON 0 t
1520+ <*> parseJSONElemAtIndex parseJSON 1 t
1521+ <*> parseJSONElemAtIndex parseJSON 2 t
1522+ <*> parseJSONElemAtIndex parseJSON 3 t
1523+ <*> parseJSONElemAtIndex parseJSON 4 t
1524+ <*> parseJSONElemAtIndex parseJSON 5 t
1525+ <*> parseJSONElemAtIndex parseJSON 6 t
1526+ <*> parseJSONElemAtIndex parseJSON 7 t
1527+ <*> parseJSONElemAtIndex parseJSON 8 t
1528+ <*> parseJSONElemAtIndex parseJSON 9 t
1529+ <*> parseJSONElemAtIndex pK 10 t
1530+ <*> parseJSONElemAtIndex pL 11 t
1531+ else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 12"
1532+ {-# INLINE liftParseJSON2 #-}
1533+
1534+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k) => FromJSON1 ((,,,,,,,,,,,) a b c d e f g h i j k) where
1535+ liftParseJSON = liftParseJSON2 parseJSON parseJSONList
1536+ {-# INLINE liftParseJSON #-}
1537+
1538+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k, FromJSON l) => FromJSON (a, b, c, d, e, f, g, h, i, j, k, l) where
1539+ parseJSON = parseJSON2
1540+ {-# INLINE parseJSON #-}
1541+
1542+
1543+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k) => FromJSON2 ((,,,,,,,,,,,,) a b c d e f g h i j k) where
1544+ liftParseJSON2 pL _ pM _ = withArray "(a, b, c, d, e, f, g, h, i, j, k, l, m)" $ \t ->
1545+ let n = V.length t
1546+ in if n == 13
1547+ then (,,,,,,,,,,,,)
1548+ <$> parseJSONElemAtIndex parseJSON 0 t
1549+ <*> parseJSONElemAtIndex parseJSON 1 t
1550+ <*> parseJSONElemAtIndex parseJSON 2 t
1551+ <*> parseJSONElemAtIndex parseJSON 3 t
1552+ <*> parseJSONElemAtIndex parseJSON 4 t
1553+ <*> parseJSONElemAtIndex parseJSON 5 t
1554+ <*> parseJSONElemAtIndex parseJSON 6 t
1555+ <*> parseJSONElemAtIndex parseJSON 7 t
1556+ <*> parseJSONElemAtIndex parseJSON 8 t
1557+ <*> parseJSONElemAtIndex parseJSON 9 t
1558+ <*> parseJSONElemAtIndex parseJSON 10 t
1559+ <*> parseJSONElemAtIndex pL 11 t
1560+ <*> parseJSONElemAtIndex pM 12 t
1561+ else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 13"
1562+ {-# INLINE liftParseJSON2 #-}
1563+
1564+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k, FromJSON l) => FromJSON1 ((,,,,,,,,,,,,) a b c d e f g h i j k l) where
1565+ liftParseJSON = liftParseJSON2 parseJSON parseJSONList
1566+ {-# INLINE liftParseJSON #-}
1567+
1568+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k, FromJSON l, FromJSON m) => FromJSON (a, b, c, d, e, f, g, h, i, j, k, l, m) where
1569+ parseJSON = parseJSON2
1570+ {-# INLINE parseJSON #-}
1571+
1572+
1573+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k, FromJSON l) => FromJSON2 ((,,,,,,,,,,,,,) a b c d e f g h i j k l) where
1574+ liftParseJSON2 pM _ pN _ = withArray "(a, b, c, d, e, f, g, h, i, j, k, l, m, n)" $ \t ->
1575+ let n = V.length t
1576+ in if n == 14
1577+ then (,,,,,,,,,,,,,)
1578+ <$> parseJSONElemAtIndex parseJSON 0 t
1579+ <*> parseJSONElemAtIndex parseJSON 1 t
1580+ <*> parseJSONElemAtIndex parseJSON 2 t
1581+ <*> parseJSONElemAtIndex parseJSON 3 t
1582+ <*> parseJSONElemAtIndex parseJSON 4 t
1583+ <*> parseJSONElemAtIndex parseJSON 5 t
1584+ <*> parseJSONElemAtIndex parseJSON 6 t
1585+ <*> parseJSONElemAtIndex parseJSON 7 t
1586+ <*> parseJSONElemAtIndex parseJSON 8 t
1587+ <*> parseJSONElemAtIndex parseJSON 9 t
1588+ <*> parseJSONElemAtIndex parseJSON 10 t
1589+ <*> parseJSONElemAtIndex parseJSON 11 t
1590+ <*> parseJSONElemAtIndex pM 12 t
1591+ <*> parseJSONElemAtIndex pN 13 t
1592+ else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 14"
1593+ {-# INLINE liftParseJSON2 #-}
1594+
1595+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k, FromJSON l, FromJSON m) => FromJSON1 ((,,,,,,,,,,,,,) a b c d e f g h i j k l m) where
1596+ liftParseJSON = liftParseJSON2 parseJSON parseJSONList
1597+ {-# INLINE liftParseJSON #-}
1598+
1599+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k, FromJSON l, FromJSON m, FromJSON n) => FromJSON (a, b, c, d, e, f, g, h, i, j, k, l, m, n) where
1600+ parseJSON = parseJSON2
1601+ {-# INLINE parseJSON #-}
1602+
1603+
1604+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k, FromJSON l, FromJSON m) => FromJSON2 ((,,,,,,,,,,,,,,) a b c d e f g h i j k l m) where
1605+ liftParseJSON2 pN _ pO _ = withArray "(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)" $ \t ->
1606+ let n = V.length t
1607+ in if n == 15
1608+ then (,,,,,,,,,,,,,,)
1609+ <$> parseJSONElemAtIndex parseJSON 0 t
1610+ <*> parseJSONElemAtIndex parseJSON 1 t
1611+ <*> parseJSONElemAtIndex parseJSON 2 t
1612+ <*> parseJSONElemAtIndex parseJSON 3 t
1613+ <*> parseJSONElemAtIndex parseJSON 4 t
1614+ <*> parseJSONElemAtIndex parseJSON 5 t
1615+ <*> parseJSONElemAtIndex parseJSON 6 t
1616+ <*> parseJSONElemAtIndex parseJSON 7 t
1617+ <*> parseJSONElemAtIndex parseJSON 8 t
1618+ <*> parseJSONElemAtIndex parseJSON 9 t
1619+ <*> parseJSONElemAtIndex parseJSON 10 t
1620+ <*> parseJSONElemAtIndex parseJSON 11 t
1621+ <*> parseJSONElemAtIndex parseJSON 12 t
1622+ <*> parseJSONElemAtIndex pN 13 t
1623+ <*> parseJSONElemAtIndex pO 14 t
1624+ else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 15"
1625+ {-# INLINE liftParseJSON2 #-}
1626+
1627+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k, FromJSON l, FromJSON m, FromJSON n) => FromJSON1 ((,,,,,,,,,,,,,,) a b c d e f g h i j k l m n) where
1628+ liftParseJSON = liftParseJSON2 parseJSON parseJSONList
1629+ {-# INLINE liftParseJSON #-}
1630+
1631+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k, FromJSON l, FromJSON m, FromJSON n, FromJSON o) => FromJSON (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) where
1632+ parseJSON = parseJSON2
1633+ {-# INLINE parseJSON #-}
Data/Aeson/Types/Generic.hs+20−738
@@ -1,9 +1,13 @@
1−{-# LANGUAGE CPP, DefaultSignatures, EmptyDataDecls, FlexibleInstances,
2− FunctionalDependencies, KindSignatures,
3− ScopedTypeVariables, TypeOperators, UndecidableInstances,
4− ViewPatterns, NamedFieldPuns, FlexibleContexts, PatternGuards,
5− RecordWildCards, DataKinds #-}
6−{-# OPTIONS_GHC -fno-warn-orphans #-}
1+{-# LANGUAGE CPP #-}
2+{-# LANGUAGE DataKinds #-}
3+{-# LANGUAGE EmptyDataDecls #-}
4+{-# LANGUAGE FlexibleInstances #-}
5+{-# LANGUAGE FunctionalDependencies #-}
6+{-# LANGUAGE KindSignatures #-}
7+{-# LANGUAGE MultiParamTypeClasses #-}
8+{-# LANGUAGE ScopedTypeVariables #-}
9+{-# LANGUAGE TypeOperators #-}
10+{-# LANGUAGE UndecidableInstances #-}
711
812#include "overlapping-compat.h"
913
@@ -17,733 +21,11 @@
1721-- Stability: experimental
1822-- Portability: portable
1923--
20−-- Types for working with JSON data.
24+-- Helpers for generic derivations.
2125
22−module Data.Aeson.Types.Generic ( ) where
26+module Data.Aeson.Types.Generic where
2327
24−import Control.Applicative ((<|>))
25−import Control.Monad ((<=<))
26−import Control.Monad.ST (ST)
27−import Data.Aeson.Encoding.Internal (Encoding, (>*<))
28−import qualified Data.Aeson.Encoding.Internal as E
29−import Data.Aeson.Types.Instances
30−import Data.Aeson.Types.Internal
31−import Data.Bits (unsafeShiftR)
32−import Data.DList (DList, toList, empty)
33−import Data.Maybe (fromMaybe)
34−import Data.Monoid ((<>))
35−import Data.List (intersperse)
36−import Data.Text (Text, pack, unpack)
3728import GHC.Generics
38−import qualified Data.HashMap.Strict as H
39−import qualified Data.Vector as V
40−import qualified Data.Vector.Mutable as VM
41−
42−#if !MIN_VERSION_base(4,8,0)
43−import Control.Applicative ((<*>), (<$>), pure)
44−import Data.Monoid (mempty, mconcat)
45−#endif
46−
47−--------------------------------------------------------------------------------
48−-- Generic toJSON
49−
50−instance OVERLAPPABLE_ (GToJSON a) => GToJSON (M1 i c a) where
51− -- Meta-information, which is not handled elsewhere, is ignored:
52− gToJSON opts = gToJSON opts . unM1
53−
54−instance (ToJSON a) => GToJSON (K1 i a) where
55− -- Constant values are encoded using their ToJSON instance:
56− gToJSON _opts = toJSON . unK1
57−
58−instance GToJSON U1 where
59− -- Empty constructors are encoded to an empty array:
60− gToJSON _opts _ = emptyArray
61−
62−instance (ConsToJSON a) => GToJSON (C1 c a) where
63− -- Constructors need to be encoded differently depending on whether they're
64− -- a record or not. This distinction is made by 'consToJSON':
65− gToJSON opts = consToJSON opts . unM1
66−
67−instance ( WriteProduct a, WriteProduct b
68− , ProductSize a, ProductSize b ) => GToJSON (a :*: b) where
69− -- Products are encoded to an array. Here we allocate a mutable vector of
70− -- the same size as the product and write the product's elements to it using
71− -- 'writeProduct':
72− gToJSON opts p =
73− Array $ V.create $ do
74− mv <- VM.unsafeNew lenProduct
75− writeProduct opts mv 0 lenProduct p
76− return mv
77− where
78− lenProduct = (unTagged2 :: Tagged2 (a :*: b) Int -> Int)
79− productSize
80−
81−instance ( AllNullary (a :+: b) allNullary
82− , SumToJSON (a :+: b) allNullary ) => GToJSON (a :+: b) where
83− -- If all constructors of a sum datatype are nullary and the
84− -- 'allNullaryToStringTag' option is set they are encoded to
85− -- strings. This distinction is made by 'sumToJSON':
86− gToJSON opts = (unTagged :: Tagged allNullary Value -> Value)
87− . sumToJSON opts
88−
89−--------------------------------------------------------------------------------
90−-- Generic toEncoding
91−
92−instance OVERLAPPABLE_ (GToEncoding a) => GToEncoding (M1 i c a) where
93− -- Meta-information, which is not handled elsewhere, is ignored:
94− gToEncoding opts = gToEncoding opts . unM1
95−
96−instance (ToJSON a) => GToEncoding (K1 i a) where
97− -- Constant values are encoded using their ToJSON instance:
98− gToEncoding _opts = toEncoding . unK1
99−
100−instance GToEncoding U1 where
101− -- Empty constructors are encoded to an empty array:
102− gToEncoding _opts _ = E.emptyArray_
103−
104−instance (ConsToEncoding a) => GToEncoding (C1 c a) where
105− -- Constructors need to be encoded differently depending on whether they're
106− -- a record or not. This distinction is made by 'consToEncoding':
107− gToEncoding opts = consToEncoding opts . unM1
108−
109−instance ( EncodeProduct a, EncodeProduct b ) => GToEncoding (a :*: b) where
110− -- Products are encoded to an array. Here we allocate a mutable vector of
111− -- the same size as the product and write the product's elements to it using
112− -- 'encodeProduct':
113− gToEncoding opts p = E.tuple $ encodeProduct opts p
114−
115−instance ( AllNullary (a :+: b) allNullary
116− , SumToEncoding (a :+: b) allNullary ) => GToEncoding (a :+: b) where
117− -- If all constructors of a sum datatype are nullary and the
118− -- 'allNullaryToStringTag' option is set they are encoded to
119− -- strings. This distinction is made by 'sumToEncoding':
120− gToEncoding opts
121− = (unTagged :: Tagged allNullary Encoding -> Encoding)
122− . sumToEncoding opts
123−
124−--------------------------------------------------------------------------------
125−
126−class SumToJSON f allNullary where
127− sumToJSON :: Options -> f a -> Tagged allNullary Value
128−
129−instance ( GetConName f
130− , TaggedObjectPairs f
131− , ObjectWithSingleFieldObj f
132− , TwoElemArrayObj f ) => SumToJSON f True where
133− sumToJSON opts
134− | allNullaryToStringTag opts = Tagged . String . pack
135− . constructorTagModifier opts . getConName
136− | otherwise = Tagged . nonAllNullarySumToJSON opts
137−
138−instance ( TwoElemArrayObj f
139− , TaggedObjectPairs f
140− , ObjectWithSingleFieldObj f ) => SumToJSON f False where
141− sumToJSON opts = Tagged . nonAllNullarySumToJSON opts
142−
143−nonAllNullarySumToJSON :: ( TwoElemArrayObj f
144− , TaggedObjectPairs f
145− , ObjectWithSingleFieldObj f
146− ) => Options -> f a -> Value
147−nonAllNullarySumToJSON opts =
148− case sumEncoding opts of
149− TaggedObject{..} ->
150− object . taggedObjectPairs opts tagFieldName contentsFieldName
151− ObjectWithSingleField -> Object . objectWithSingleFieldObj opts
152− TwoElemArray -> Array . twoElemArrayObj opts
153−
154−--------------------------------------------------------------------------------
155−
156−class SumToEncoding f allNullary where
157− sumToEncoding :: Options -> f a -> Tagged allNullary Encoding
158−
159−instance ( GetConName f
160− , TaggedObjectEnc f
161− , ObjectWithSingleFieldEnc f
162− , TwoElemArrayEnc f ) => SumToEncoding f True where
163− sumToEncoding opts
164− | allNullaryToStringTag opts = Tagged . toEncoding .
165− constructorTagModifier opts . getConName
166− | otherwise = Tagged . nonAllNullarySumToEncoding opts
167−
168−instance ( TwoElemArrayEnc f
169− , TaggedObjectEnc f
170− , ObjectWithSingleFieldEnc f ) => SumToEncoding f False where
171− sumToEncoding opts = Tagged . nonAllNullarySumToEncoding opts
172−
173−nonAllNullarySumToEncoding :: ( TwoElemArrayEnc f
174− , TaggedObjectEnc f
175− , ObjectWithSingleFieldEnc f
176− ) => Options -> f a -> Encoding
177−nonAllNullarySumToEncoding opts =
178− case sumEncoding opts of
179− TaggedObject{..} ->
180− taggedObjectEnc opts tagFieldName contentsFieldName
181− ObjectWithSingleField -> objectWithSingleFieldEnc opts
182− TwoElemArray -> twoElemArrayEnc opts
183−
184−--------------------------------------------------------------------------------
185−
186−class TaggedObjectPairs f where
187− taggedObjectPairs :: Options -> String -> String -> f a -> [Pair]
188−
189−instance ( TaggedObjectPairs a
190− , TaggedObjectPairs b ) => TaggedObjectPairs (a :+: b) where
191− taggedObjectPairs opts tagFieldName contentsFieldName (L1 x) =
192− taggedObjectPairs opts tagFieldName contentsFieldName x
193− taggedObjectPairs opts tagFieldName contentsFieldName (R1 x) =
194− taggedObjectPairs opts tagFieldName contentsFieldName x
195−
196−instance ( IsRecord a isRecord
197− , TaggedObjectPairs' a isRecord
198− , Constructor c ) => TaggedObjectPairs (C1 c a) where
199− taggedObjectPairs opts tagFieldName contentsFieldName =
200− (pack tagFieldName .= constructorTagModifier opts
201− (conName (undefined :: t c a p)) :) .
202− (unTagged :: Tagged isRecord [Pair] -> [Pair]) .
203− taggedObjectPairs' opts contentsFieldName . unM1
204−
205−class TaggedObjectPairs' f isRecord where
206− taggedObjectPairs' :: Options -> String -> f a -> Tagged isRecord [Pair]
207−
208−instance OVERLAPPING_ TaggedObjectPairs' U1 False where
209− taggedObjectPairs' _ _ _ = Tagged []
210−
211−instance (RecordToPairs f) => TaggedObjectPairs' f True where
212− taggedObjectPairs' opts _ = Tagged . toList . recordToPairs opts
213−
214−instance (GToJSON f) => TaggedObjectPairs' f False where
215− taggedObjectPairs' opts contentsFieldName =
216− Tagged . (:[]) . (pack contentsFieldName .=) . gToJSON opts
217−
218−--------------------------------------------------------------------------------
219−
220−class TaggedObjectEnc f where
221− taggedObjectEnc :: Options -> String -> String -> f a -> Encoding
222−
223−instance ( TaggedObjectEnc a
224− , TaggedObjectEnc b ) => TaggedObjectEnc (a :+: b) where
225− taggedObjectEnc opts tagFieldName contentsFieldName (L1 x) =
226− taggedObjectEnc opts tagFieldName contentsFieldName x
227− taggedObjectEnc opts tagFieldName contentsFieldName (R1 x) =
228− taggedObjectEnc opts tagFieldName contentsFieldName x
229−
230−instance ( IsRecord a isRecord
231− , TaggedObjectEnc' a isRecord
232− , Constructor c ) => TaggedObjectEnc (C1 c a) where
233− taggedObjectEnc opts tagFieldName contentsFieldName v =
234− E.openCurly <>
235− (toEncoding tagFieldName <>
236− E.colon <>
237− toEncoding (constructorTagModifier opts (conName (undefined :: t c a p)))) <>
238− ((unTagged :: Tagged isRecord Encoding -> Encoding) .
239− taggedObjectEnc' opts contentsFieldName . unM1 $ v) <>
240− E.closeCurly
241−
242−class TaggedObjectEnc' f isRecord where
243− taggedObjectEnc' :: Options -> String -> f a -> Tagged isRecord Encoding
244−
245−instance OVERLAPPING_ TaggedObjectEnc' U1 False where
246− taggedObjectEnc' _ _ _ = Tagged mempty
247−
248−instance (RecordToEncoding f) => TaggedObjectEnc' f True where
249− taggedObjectEnc' opts _ = Tagged . (E.comma <>) . fst . recordToEncoding opts
250−
251−instance (GToEncoding f) => TaggedObjectEnc' f False where
252− taggedObjectEnc' opts contentsFieldName =
253− Tagged . (\z -> E.comma <> toEncoding contentsFieldName <> E.colon <> z) .
254− gToEncoding opts
255−
256−--------------------------------------------------------------------------------
257−
258−-- | Get the name of the constructor of a sum datatype.
259−class GetConName f where
260− getConName :: f a -> String
261−
262−instance (GetConName a, GetConName b) => GetConName (a :+: b) where
263− getConName (L1 x) = getConName x
264− getConName (R1 x) = getConName x
265−
266−instance (Constructor c) => GetConName (C1 c a) where
267− getConName = conName
268−
269−--------------------------------------------------------------------------------
270−
271−class TwoElemArrayObj f where
272− twoElemArrayObj :: Options -> f a -> V.Vector Value
273−
274−instance (TwoElemArrayObj a, TwoElemArrayObj b) => TwoElemArrayObj (a :+: b) where
275− twoElemArrayObj opts (L1 x) = twoElemArrayObj opts x
276− twoElemArrayObj opts (R1 x) = twoElemArrayObj opts x
277−
278−instance ( GToJSON a, ConsToJSON a
279− , Constructor c ) => TwoElemArrayObj (C1 c a) where
280− twoElemArrayObj opts x = V.create $ do
281− mv <- VM.unsafeNew 2
282− VM.unsafeWrite mv 0 $ String $ pack $ constructorTagModifier opts
283− $ conName (undefined :: t c a p)
284− VM.unsafeWrite mv 1 $ gToJSON opts x
285− return mv
286−
287−--------------------------------------------------------------------------------
288−
289−class TwoElemArrayEnc f where
290− twoElemArrayEnc :: Options -> f a -> Encoding
291−
292−instance (TwoElemArrayEnc a, TwoElemArrayEnc b) => TwoElemArrayEnc (a :+: b) where
293− twoElemArrayEnc opts (L1 x) = twoElemArrayEnc opts x
294− twoElemArrayEnc opts (R1 x) = twoElemArrayEnc opts x
295−
296−instance ( GToEncoding a, ConsToEncoding a
297− , Constructor c ) => TwoElemArrayEnc (C1 c a) where
298− twoElemArrayEnc opts x = E.tuple $
299− toEncoding (constructorTagModifier opts (conName (undefined :: t c a p))) >*<
300− gToEncoding opts x
301−
302−--------------------------------------------------------------------------------
303−
304−class ConsToJSON f where
305− consToJSON :: Options -> f a -> Value
306−
307−class ConsToJSON' f isRecord where
308− consToJSON' :: Options -> Bool -- ^ Are we a record with one field?
309− -> f a -> Tagged isRecord Value
310−
311−instance ( IsRecord f isRecord
312− , ConsToJSON' f isRecord ) => ConsToJSON f where
313− consToJSON opts = (unTagged :: Tagged isRecord Value -> Value)
314− . consToJSON' opts (isUnary (undefined :: f a))
315−
316−instance (RecordToPairs f) => ConsToJSON' f True where
317− consToJSON' opts isUn f = let
318− vals = toList $ recordToPairs opts f
319− in case (unwrapUnaryRecords opts,isUn,vals) of
320− (True,True,[(_,val)]) -> Tagged val
321− _ -> Tagged $ object vals
322−
323−instance GToJSON f => ConsToJSON' f False where
324− consToJSON' opts _ = Tagged . gToJSON opts
325−
326−--------------------------------------------------------------------------------
327−
328−class ConsToEncoding f where
329− consToEncoding :: Options -> f a -> Encoding
330−
331−class ConsToEncoding' f isRecord where
332− consToEncoding' :: Options -> Bool -- ^ Are we a record with one field?
333− -> f a -> Tagged isRecord Encoding
334−
335−instance ( IsRecord f isRecord
336− , ConsToEncoding' f isRecord ) => ConsToEncoding f where
337− consToEncoding opts = (unTagged :: Tagged isRecord Encoding -> Encoding)
338− . consToEncoding' opts (isUnary (undefined :: f a))
339−
340−instance (RecordToEncoding f) => ConsToEncoding' f True where
341− consToEncoding' opts isUn x =
342− let (enc, mbVal) = recordToEncoding opts x
343− in case (unwrapUnaryRecords opts, isUn, mbVal) of
344− (True, True, Just val) -> Tagged val
345− _ -> Tagged $ E.wrapObject enc
346−
347−instance GToEncoding f => ConsToEncoding' f False where
348− consToEncoding' opts _ = Tagged . gToEncoding opts
349−
350−--------------------------------------------------------------------------------
351−
352−class RecordToPairs f where
353− recordToPairs :: Options -> f a -> DList Pair
354−
355−instance (RecordToPairs a, RecordToPairs b) => RecordToPairs (a :*: b) where
356− recordToPairs opts (a :*: b) = recordToPairs opts a <>
357− recordToPairs opts b
358−
359−instance (Selector s, GToJSON a) => RecordToPairs (S1 s a) where
360− recordToPairs = fieldToPair
361−
362−instance OVERLAPPING_ (Selector s, ToJSON a) =>
363− RecordToPairs (S1 s (K1 i (Maybe a))) where
364− recordToPairs opts (M1 k1) | omitNothingFields opts
365− , K1 Nothing <- k1 = empty
366− recordToPairs opts m1 = fieldToPair opts m1
367−
368−fieldToPair :: (Selector s, GToJSON a) => Options -> S1 s a p -> DList Pair
369−fieldToPair opts m1 = pure ( pack $ fieldLabelModifier opts $ selName m1
370− , gToJSON opts (unM1 m1)
371− )
372−
373−--------------------------------------------------------------------------------
374−
375−class RecordToEncoding f where
376− -- 1st element: whole thing
377− -- 2nd element: in case the record has only 1 field, just the value
378− -- of the field (without the key); 'Nothing' otherwise
379− recordToEncoding :: Options -> f a -> (Encoding, Maybe Encoding)
380−
381−instance (RecordToEncoding a, RecordToEncoding b) => RecordToEncoding (a :*: b) where
382− recordToEncoding opts (a :*: b) | omitNothingFields opts =
383− (mconcat $ intersperse E.comma $
384− filter (not . E.nullEncoding)
385− [fst (recordToEncoding opts a), fst (recordToEncoding opts b)]
386− , Nothing)
387− recordToEncoding opts (a :*: b) =
388− (fst (recordToEncoding opts a) <> E.comma <>
389− fst (recordToEncoding opts b),
390− Nothing)
391−
392−instance (Selector s, GToEncoding a) => RecordToEncoding (S1 s a) where
393− recordToEncoding = fieldToEncoding
394−
395−instance OVERLAPPING_ (Selector s, ToJSON a) =>
396− RecordToEncoding (S1 s (K1 i (Maybe a))) where
397− recordToEncoding opts (M1 k1) | omitNothingFields opts
398− , K1 Nothing <- k1 = (mempty, Nothing)
399− recordToEncoding opts m1 = fieldToEncoding opts m1
400−
401−fieldToEncoding :: (Selector s, GToEncoding a) => Options -> S1 s a p -> (Encoding, Maybe Encoding)
402−fieldToEncoding opts m1 =
403− let keyBuilder = toEncoding (fieldLabelModifier opts $ selName m1)
404− valueBuilder = gToEncoding opts (unM1 m1)
405− in (keyBuilder <> E.colon <> valueBuilder, Just valueBuilder)
406−
407−--------------------------------------------------------------------------------
408−
409−class WriteProduct f where
410− writeProduct :: Options
411− -> VM.MVector s Value
412− -> Int -- ^ index
413− -> Int -- ^ length
414− -> f a
415− -> ST s ()
416−
417−instance ( WriteProduct a
418− , WriteProduct b ) => WriteProduct (a :*: b) where
419− writeProduct opts mv ix len (a :*: b) = do
420− writeProduct opts mv ix lenL a
421− writeProduct opts mv ixR lenR b
422− where
423− lenL = len `unsafeShiftR` 1
424− lenR = len - lenL
425− ixR = ix + lenL
426−
427−instance OVERLAPPABLE_ (GToJSON a) => WriteProduct a where
428− writeProduct opts mv ix _ = VM.unsafeWrite mv ix . gToJSON opts
429−
430−--------------------------------------------------------------------------------
431−
432−class EncodeProduct f where
433− encodeProduct :: Options -> f a -> Encoding
434−
435−instance ( EncodeProduct a
436− , EncodeProduct b ) => EncodeProduct (a :*: b) where
437− encodeProduct opts (a :*: b) | omitNothingFields opts =
438− mconcat $ intersperse E.comma $
439− filter (not . E.nullEncoding)
440− [encodeProduct opts a, encodeProduct opts b]
441− encodeProduct opts (a :*: b) = encodeProduct opts a <>
442− E.comma <>
443− encodeProduct opts b
444−
445−instance OVERLAPPABLE_ (GToEncoding a) => EncodeProduct a where
446− encodeProduct opts = gToEncoding opts
447−
448−--------------------------------------------------------------------------------
449−
450−class ObjectWithSingleFieldObj f where
451− objectWithSingleFieldObj :: Options -> f a -> Object
452−
453−instance ( ObjectWithSingleFieldObj a
454− , ObjectWithSingleFieldObj b ) => ObjectWithSingleFieldObj (a :+: b) where
455− objectWithSingleFieldObj opts (L1 x) = objectWithSingleFieldObj opts x
456− objectWithSingleFieldObj opts (R1 x) = objectWithSingleFieldObj opts x
457−
458−instance ( GToJSON a, ConsToJSON a
459− , Constructor c ) => ObjectWithSingleFieldObj (C1 c a) where
460− objectWithSingleFieldObj opts = H.singleton typ . gToJSON opts
461− where
462− typ = pack $ constructorTagModifier opts $
463− conName (undefined :: t c a p)
464−
465−--------------------------------------------------------------------------------
466−
467−class ObjectWithSingleFieldEnc f where
468− objectWithSingleFieldEnc :: Options -> f a -> Encoding
469−
470−instance ( ObjectWithSingleFieldEnc a
471− , ObjectWithSingleFieldEnc b ) => ObjectWithSingleFieldEnc (a :+: b) where
472− objectWithSingleFieldEnc opts (L1 x) = objectWithSingleFieldEnc opts x
473− objectWithSingleFieldEnc opts (R1 x) = objectWithSingleFieldEnc opts x
474−
475−instance ( GToEncoding a, ConsToEncoding a
476− , Constructor c ) => ObjectWithSingleFieldEnc (C1 c a) where
477− objectWithSingleFieldEnc opts v =
478− E.openCurly <>
479− toEncoding
480− (constructorTagModifier opts
481− (conName (undefined :: t c a p))) <>
482− E.colon <>
483− gToEncoding opts v <>
484− E.closeCurly
485−
486−--------------------------------------------------------------------------------
487−-- Generic parseJSON
488−
489−instance OVERLAPPABLE_ (GFromJSON a) => GFromJSON (M1 i c a) where
490− -- Meta-information, which is not handled elsewhere, is just added to the
491− -- parsed value:
492− gParseJSON opts = fmap M1 . gParseJSON opts
493−
494−instance (FromJSON a) => GFromJSON (K1 i a) where
495− -- Constant values are decoded using their FromJSON instance:
496− gParseJSON _opts = fmap K1 . parseJSON
497−
498−instance GFromJSON U1 where
499− -- Empty constructors are expected to be encoded as an empty array:
500− gParseJSON _opts v
501− | isEmptyArray v = pure U1
502− | otherwise = typeMismatch "unit constructor (U1)" v
503−
504−instance (ConsFromJSON a) => GFromJSON (C1 c a) where
505− -- Constructors need to be decoded differently depending on whether they're
506− -- a record or not. This distinction is made by consParseJSON:
507− gParseJSON opts = fmap M1 . consParseJSON opts
508−
509−instance ( FromProduct a, FromProduct b
510− , ProductSize a, ProductSize b ) => GFromJSON (a :*: b) where
511− -- Products are expected to be encoded to an array. Here we check whether we
512− -- got an array of the same size as the product, then parse each of the
513− -- product's elements using parseProduct:
514− gParseJSON opts = withArray "product (:*:)" $ \arr ->
515− let lenArray = V.length arr
516− lenProduct = (unTagged2 :: Tagged2 (a :*: b) Int -> Int)
517− productSize in
518− if lenArray == lenProduct
519− then parseProduct opts arr 0 lenProduct
520− else fail $ "When expecting a product of " ++ show lenProduct ++
521− " values, encountered an Array of " ++ show lenArray ++
522− " elements instead"
523−
524−instance ( AllNullary (a :+: b) allNullary
525− , ParseSum (a :+: b) allNullary ) => GFromJSON (a :+: b) where
526− -- If all constructors of a sum datatype are nullary and the
527− -- 'allNullaryToStringTag' option is set they are expected to be
528− -- encoded as strings. This distinction is made by 'parseSum':
529− gParseJSON opts = (unTagged :: Tagged allNullary (Parser ((a :+: b) d)) ->
530− (Parser ((a :+: b) d)))
531− . parseSum opts
532−
533−--------------------------------------------------------------------------------
534−
535−class ParseSum f allNullary where
536− parseSum :: Options -> Value -> Tagged allNullary (Parser (f a))
537−
538−instance ( SumFromString (a :+: b)
539− , FromPair (a :+: b)
540− , FromTaggedObject (a :+: b) ) => ParseSum (a :+: b) True where
541− parseSum opts
542− | allNullaryToStringTag opts = Tagged . parseAllNullarySum opts
543− | otherwise = Tagged . parseNonAllNullarySum opts
544−
545−instance ( FromPair (a :+: b)
546− , FromTaggedObject (a :+: b) ) => ParseSum (a :+: b) False where
547− parseSum opts = Tagged . parseNonAllNullarySum opts
548−
549−--------------------------------------------------------------------------------
550−
551−parseAllNullarySum :: SumFromString f => Options -> Value -> Parser (f a)
552−parseAllNullarySum opts = withText "Text" $ \key ->
553− maybe (notFound key) return $
554− parseSumFromString opts key
555−
556−class SumFromString f where
557− parseSumFromString :: Options -> Text -> Maybe (f a)
558−
559−instance (SumFromString a, SumFromString b) => SumFromString (a :+: b) where
560− parseSumFromString opts key = (L1 <$> parseSumFromString opts key) <|>
561− (R1 <$> parseSumFromString opts key)
562−
563−instance (Constructor c) => SumFromString (C1 c U1) where
564− parseSumFromString opts key | key == name = Just $ M1 U1
565− | otherwise = Nothing
566− where
567− name = pack $ constructorTagModifier opts $
568− conName (undefined :: t c U1 p)
569−
570−--------------------------------------------------------------------------------
571−
572−parseNonAllNullarySum :: ( FromPair (a :+: b)
573− , FromTaggedObject (a :+: b)
574− ) => Options -> Value -> Parser ((a :+: b) c)
575−parseNonAllNullarySum opts =
576− case sumEncoding opts of
577− TaggedObject{..} ->
578− withObject "Object" $ \obj -> do
579− tag <- obj .: pack tagFieldName
580− fromMaybe (notFound tag) $
581− parseFromTaggedObject opts contentsFieldName obj tag
582−
583− ObjectWithSingleField ->
584− withObject "Object" $ \obj ->
585− case H.toList obj of
586− [pair@(tag, _)] -> fromMaybe (notFound tag) $
587− parsePair opts pair
588− _ -> fail "Object doesn't have a single field"
589−
590− TwoElemArray ->
591− withArray "Array" $ \arr ->
592− if V.length arr == 2
593− then case V.unsafeIndex arr 0 of
594− String tag -> fromMaybe (notFound tag) $
595− parsePair opts (tag, V.unsafeIndex arr 1)
596− _ -> fail "First element is not a String"
597− else fail "Array doesn't have 2 elements"
598−
599−--------------------------------------------------------------------------------
600−
601−class FromTaggedObject f where
602− parseFromTaggedObject :: Options -> String -> Object -> Text
603− -> Maybe (Parser (f a))
604−
605−instance (FromTaggedObject a, FromTaggedObject b) =>
606− FromTaggedObject (a :+: b) where
607− parseFromTaggedObject opts contentsFieldName obj tag =
608− (fmap L1 <$> parseFromTaggedObject opts contentsFieldName obj tag) <|>
609− (fmap R1 <$> parseFromTaggedObject opts contentsFieldName obj tag)
610−
611−instance ( FromTaggedObject' f
612− , Constructor c ) => FromTaggedObject (C1 c f) where
613− parseFromTaggedObject opts contentsFieldName obj tag
614− | tag == name = Just $ M1 <$> parseFromTaggedObject'
615− opts contentsFieldName obj
616− | otherwise = Nothing
617− where
618− name = pack $ constructorTagModifier opts $
619− conName (undefined :: t c f p)
620−
621−--------------------------------------------------------------------------------
622−
623−class FromTaggedObject' f where
624− parseFromTaggedObject' :: Options -> String -> Object -> Parser (f a)
625−
626−class FromTaggedObject'' f isRecord where
627− parseFromTaggedObject'' :: Options -> String -> Object
628− -> Tagged isRecord (Parser (f a))
629−
630−instance ( IsRecord f isRecord
631− , FromTaggedObject'' f isRecord
632− ) => FromTaggedObject' f where
633− parseFromTaggedObject' opts contentsFieldName =
634− (unTagged :: Tagged isRecord (Parser (f a)) -> Parser (f a)) .
635− parseFromTaggedObject'' opts contentsFieldName
636−
637−instance (FromRecord f) => FromTaggedObject'' f True where
638− parseFromTaggedObject'' opts _ = Tagged . parseRecord opts Nothing
639−
640−instance (GFromJSON f) => FromTaggedObject'' f False where
641− parseFromTaggedObject'' opts contentsFieldName = Tagged .
642− (gParseJSON opts <=< (.: pack contentsFieldName))
643−
644−instance OVERLAPPING_ FromTaggedObject'' U1 False where
645− parseFromTaggedObject'' _ _ _ = Tagged (pure U1)
646−
647−--------------------------------------------------------------------------------
648−
649−class ConsFromJSON f where
650− consParseJSON :: Options -> Value -> Parser (f a)
651−
652−class ConsFromJSON' f isRecord where
653− consParseJSON' :: Options -> (Maybe Text) -- ^ A dummy label
654− -- (Nothing to use proper label)
655− -> Value -> Tagged isRecord (Parser (f a))
656−
657−instance ( IsRecord f isRecord
658− , ConsFromJSON' f isRecord
659− ) => ConsFromJSON f where
660− consParseJSON opts v = let
661− (v2,lab) = case (unwrapUnaryRecords opts,isUnary (undefined :: f a)) of
662− -- use a dummy object with a dummy label
663− (True,True) -> ((object [(pack "dummy",v)]),Just $ pack "dummy")
664− _ ->(v,Nothing)
665− in (unTagged :: Tagged isRecord (Parser (f a)) -> Parser (f a))
666− $ consParseJSON' opts lab v2
667−
668−
669−instance (FromRecord f) => ConsFromJSON' f True where
670− consParseJSON' opts mlab = Tagged . (withObject "record (:*:)"
671− $ parseRecord opts mlab)
672−
673−instance (GFromJSON f) => ConsFromJSON' f False where
674− consParseJSON' opts _ = Tagged . gParseJSON opts
675−
676−--------------------------------------------------------------------------------
677−
678−class FromRecord f where
679− parseRecord :: Options -> (Maybe Text) -- ^ A dummy label
680− -- (Nothing to use proper label)
681− -> Object -> Parser (f a)
682−
683−instance (FromRecord a, FromRecord b) => FromRecord (a :*: b) where
684− parseRecord opts _ obj = (:*:) <$> parseRecord opts Nothing obj
685− <*> parseRecord opts Nothing obj
686−
687−instance (Selector s, GFromJSON a) => FromRecord (S1 s a) where
688− parseRecord opts lab = (<?> Key label) . gParseJSON opts <=< (.: label)
689− where
690− label = fromMaybe defLabel lab
691− defLabel = pack . fieldLabelModifier opts $
692− selName (undefined :: t s a p)
693−
694−instance OVERLAPPING_ (Selector s, FromJSON a) =>
695− FromRecord (S1 s (K1 i (Maybe a))) where
696− parseRecord _ (Just lab) obj = (M1 . K1) <$> obj .:? lab
697− parseRecord opts Nothing obj = (M1 . K1) <$> obj .:? pack label
698− where
699− label = fieldLabelModifier opts $
700− selName (undefined :: t s (K1 i (Maybe a)) p)
701−
702−--------------------------------------------------------------------------------
703−
704−class ProductSize f where
705− productSize :: Tagged2 f Int
706−
707−instance (ProductSize a, ProductSize b) => ProductSize (a :*: b) where
708− productSize = Tagged2 $ unTagged2 (productSize :: Tagged2 a Int) +
709− unTagged2 (productSize :: Tagged2 b Int)
710−
711−instance ProductSize (S1 s a) where
712− productSize = Tagged2 1
713−
714−--------------------------------------------------------------------------------
715−
716−class FromProduct f where
717− parseProduct :: Options -> Array -> Int -> Int -> Parser (f a)
718−
719−instance (FromProduct a, FromProduct b) => FromProduct (a :*: b) where
720− parseProduct opts arr ix len =
721− (:*:) <$> parseProduct opts arr ix lenL
722− <*> parseProduct opts arr ixR lenR
723− where
724− lenL = len `unsafeShiftR` 1
725− ixR = ix + lenL
726− lenR = len - lenL
727−
728−instance (GFromJSON a) => FromProduct (S1 s a) where
729− parseProduct opts arr ix _ = gParseJSON opts $ V.unsafeIndex arr ix
730−
731−--------------------------------------------------------------------------------
732−
733−class FromPair f where
734− parsePair :: Options -> Pair -> Maybe (Parser (f a))
735−
736−instance (FromPair a, FromPair b) => FromPair (a :+: b) where
737− parsePair opts pair = (fmap L1 <$> parsePair opts pair) <|>
738− (fmap R1 <$> parsePair opts pair)
739−
740−instance (Constructor c, GFromJSON a, ConsFromJSON a) => FromPair (C1 c a) where
741− parsePair opts (tag, value)
742− | tag == tag' = Just $ gParseJSON opts value
743− | otherwise = Nothing
744− where
745− tag' = pack $ constructorTagModifier opts $
746− conName (undefined :: t c a p)
74729
74830--------------------------------------------------------------------------------
74931
@@ -767,7 +49,6 @@ instance IsRecord U1 False
76749--------------------------------------------------------------------------------
76850
76951class AllNullary (f :: * -> *) allNullary | f -> allNullary
770−
77152instance ( AllNullary a allNullaryL
77253 , AllNullary b allNullaryR
77354 , And allNullaryL allNullaryR allNullary
@@ -777,6 +58,7 @@ instance AllNullary (a :*: b) False
77758instance AllNullary (K1 i c) False
77859instance AllNullary U1 True
77960
61+newtype Tagged2 (s :: * -> *) b = Tagged2 {unTagged2 :: b}
78062--------------------------------------------------------------------------------
78163
78264data True
@@ -791,12 +73,12 @@ instance And True False False
79173
79274--------------------------------------------------------------------------------
79375
794−newtype Tagged s b = Tagged {unTagged :: b}
795−
796−newtype Tagged2 (s :: * -> *) b = Tagged2 {unTagged2 :: b}
76+class ProductSize f where
77+ productSize :: Tagged2 f Int
79778
798−--------------------------------------------------------------------------------
79+instance (ProductSize a, ProductSize b) => ProductSize (a :*: b) where
80+ productSize = Tagged2 $ unTagged2 (productSize :: Tagged2 a Int) +
81+ unTagged2 (productSize :: Tagged2 b Int)
79982
800−notFound :: Text -> Parser a
801−notFound key = fail $ "The key \"" ++ unpack key ++ "\" was not found"
802−{-# INLINE notFound #-}
83+instance ProductSize (S1 s a) where
84+ productSize = Tagged2 1
Data/Aeson/Types/Instances.hsdeleted−1438
@@ -1,1438 +0,0 @@
1−{-# LANGUAGE CPP, BangPatterns, DeriveDataTypeable, FlexibleContexts,
2− FlexibleInstances, GeneralizedNewtypeDeriving,
3− OverloadedStrings, UndecidableInstances, ScopedTypeVariables,
4− ViewPatterns #-}
5−{-# LANGUAGE DefaultSignatures #-}
6−
7−-- Needed for Tagged, Const and Proxy instances
8−#if __GLASGOW_HASKELL__ >= 706
9−{-# LANGUAGE PolyKinds #-}
10−#endif
11−
12−{-# OPTIONS_GHC -fno-warn-orphans #-}
13−
14−-- TODO: Drop this when we remove support for Data.Attoparsec.Number
15−{-# OPTIONS_GHC -fno-warn-deprecations #-}
16−
17−-- |
18−-- Module: Data.Aeson.Types.Instances
19−-- Copyright: (c) 2011-2016 Bryan O'Sullivan
20−-- (c) 2011 MailRank, Inc.
21−-- License: BSD3
22−-- Maintainer: Bryan O'Sullivan <bos@serpentine.com>
23−-- Stability: experimental
24−-- Portability: portable
25−--
26−-- Types for working with JSON data.
27−
28−module Data.Aeson.Types.Instances
29− (
30− -- * Type classes
31− -- ** Core JSON classes
32− FromJSON(..)
33− , ToJSON(..)
34− , KeyValue(..)
35− -- ** Keys for maps
36− , ToJSONKey(..)
37− , ToJSONKeyFunction(..)
38− , contramapToJSONKeyFunction
39− , FromJSONKey(..)
40− , FromJSONKeyFunction(..)
41− , fromJSONKeyCoerce
42− , coerceFromJSONKeyFunction
43− , mapFromJSONKeyFunction
44− -- ** Liftings to unary and binary type constructors
45− , FromJSON1(..)
46− , parseJSON1
47− , FromJSON2(..)
48− , parseJSON2
49− , ToJSON1(..)
50− , toJSON1
51− , toEncoding1
52− , ToJSON2(..)
53− , toJSON2
54− , toEncoding2
55− -- ** Generic JSON classes
56− , GFromJSON(..)
57− , GToJSON(..)
58− , GToEncoding(..)
59− , genericToJSON
60− , genericToEncoding
61− , genericParseJSON
62−
63− -- * Types
64− , DotNetTime(..)
65−
66− -- * Inspecting @'Value's@
67− , withObject
68− , withText
69− , withArray
70− , withNumber
71− , withScientific
72− , withBool
73−
74− -- * Functions
75− , fromJSON
76− , ifromJSON
77− , (.:)
78− , (.:?)
79− , (.:!)
80− , (.!=)
81− , typeMismatch
82−
83− , listEncoding
84− , listValue
85− , listParser
86− ) where
87−
88−import Data.Aeson.Types.Instances.Tuple ()
89−
90−import Data.Aeson.Encoding.Internal (Encoding (..), emptyArray_, dict, tuple, (>*<))
91−
92−import Control.Applicative (Const(..))
93−import Data.Aeson.Encode.Functions (builder)
94−import Data.Aeson.Functions (mapHashKeyVal, mapKey, mapKeyVal)
95−import Data.Aeson.Types.Class
96−import Data.Aeson.Types.Internal
97−import Data.Attoparsec.Number (Number(..))
98−import Data.Fixed (Fixed, HasResolution)
99−import Data.Foldable (toList)
100−import Data.Functor.Identity (Identity(..))
101−import Data.Hashable (Hashable(..))
102−import Data.Int (Int8, Int16, Int32, Int64)
103−import Data.List.NonEmpty (NonEmpty(..))
104−import Data.Maybe (fromMaybe)
105−import Data.Monoid ((<>))
106−import Data.Monoid (Dual(..), First(..), Last(..))
107−import Data.Proxy (Proxy(..))
108−import Data.Ratio (Ratio, (%), numerator, denominator)
109−import Data.Scientific (Scientific)
110−import Data.Tagged (Tagged(..))
111−import Data.Text (Text, unpack)
112−import Data.Time (Day, LocalTime, NominalDiffTime, TimeOfDay, UTCTime,
113− ZonedTime)
114−import Data.Time.Format (FormatTime, formatTime, parseTime)
115−import Data.Traversable as Tr (sequence)
116−import Data.Vector (Vector)
117−import Data.Word (Word8, Word16, Word32, Word64)
118−import Data.Version (Version, showVersion, parseVersion)
119−import Text.ParserCombinators.ReadP (readP_to_S)
120−import Foreign.Storable (Storable)
121−import Numeric.Natural (Natural)
122−import Prelude hiding (foldr)
123−import qualified Data.Aeson.Encode.Builder as EB
124−import qualified Data.Aeson.Parser.Time as Time
125−import qualified Data.ByteString.Builder as B
126−import qualified Data.ByteString.Lazy as L
127−import qualified Data.HashMap.Strict as H
128−import qualified Data.HashSet as HashSet
129−import qualified Data.IntMap as IntMap
130−import qualified Data.IntSet as IntSet
131−import qualified Data.List.NonEmpty as NE
132−import qualified Data.Map as M
133−import qualified Data.Scientific as Scientific
134−import qualified Data.Sequence as Seq
135−import qualified Data.Set as Set
136−import qualified Data.Text as T
137−import qualified Data.Text.Encoding as T
138−import qualified Data.Text.Read as TR
139−import qualified Data.Text.Lazy as LT
140−import qualified Data.Text.Lazy.Builder as LTB
141−import qualified Data.Text.Lazy.Builder.Int as LTBI
142−import qualified Data.Tree as Tree
143−import qualified Data.Vector as V
144−import qualified Data.Vector.Generic as VG
145−import qualified Data.Vector.Primitive as VP
146−import qualified Data.Vector.Storable as VS
147−import qualified Data.Vector.Unboxed as VU
148−import qualified Data.Vector.Mutable as VM
149−
150−import Unsafe.Coerce (unsafeCoerce)
151−
152−#if MIN_VERSION_base(4,8,0)
153−#else
154−import Control.Applicative ((<$>), (<*>), pure)
155−import Data.Monoid (mempty)
156−import Data.Word (Word)
157−#endif
158−
159−#if MIN_VERSION_time(1,5,0)
160−import Data.Time.Format (defaultTimeLocale)
161−#else
162−import System.Locale (defaultTimeLocale)
163−#endif
164−
165−-------------------------------------------------------------------------------
166−-- Helpers
167−-------------------------------------------------------------------------------
168−
169−parseIndexedJSON :: (Value -> Parser a) -> Int -> Value -> Parser a
170−parseIndexedJSON p idx value = p value <?> Index idx
171−{-# INLINE parseIndexedJSON #-}
172−
173−parseIndexedJSONPair :: (Value -> Parser a) -> (Value -> Parser b) -> Int -> Value -> Parser (a, b)
174−parseIndexedJSONPair keyParser valParser idx value = p value <?> Index idx
175− where
176− p = withArray "(k,v)" $ \ab ->
177− let n = V.length ab
178− in if n == 2
179− then (,) <$> parseJSONElemAtIndex keyParser 0 ab
180− <*> parseJSONElemAtIndex valParser 1 ab
181− else fail $ "cannot unpack array of length " ++
182− show n ++ " into a pair"
183−
184− parseJSONElemAtIndex :: (Value -> Parser a) -> Int -> Vector Value -> Parser a
185− parseJSONElemAtIndex p' idx' ary = p' (V.unsafeIndex ary idx') <?> Index idx'
186−{-# INLINE parseIndexedJSONPair #-}
187−
188−toJSONPair :: (a -> Value) -> (b -> Value) -> (a, b) -> Value
189−toJSONPair keySerialiser valSerializer (a, b) = Array $ V.create $ do
190− mv <- VM.unsafeNew 2
191− VM.unsafeWrite mv 0 (keySerialiser a)
192− VM.unsafeWrite mv 1 (valSerializer b)
193− return mv
194−{-# INLINE toJSONPair #-}
195−
196−realFloatToJSON :: RealFloat a => a -> Value
197−realFloatToJSON d
198− | isNaN d || isInfinite d = Null
199− | otherwise = Number $ Scientific.fromFloatDigits d
200−{-# INLINE realFloatToJSON #-}
201−
202−realFloatToEncoding :: RealFloat a => a -> Encoding
203−realFloatToEncoding d
204− | isNaN d || isInfinite d = Encoding EB.null_
205− | otherwise = toEncoding (Scientific.fromFloatDigits d)
206−{-# INLINE realFloatToEncoding #-}
207−
208−scientificToNumber :: Scientific -> Number
209−scientificToNumber s
210− | e < 0 = D $ Scientific.toRealFloat s
211− | otherwise = I $ c * 10 ^ e
212− where
213− e = Scientific.base10Exponent s
214− c = Scientific.coefficient s
215−{-# INLINE scientificToNumber #-}
216−
217−parseRealFloat :: RealFloat a => String -> Value -> Parser a
218−parseRealFloat _ (Number s) = pure $ Scientific.toRealFloat s
219−parseRealFloat _ Null = pure (0/0)
220−parseRealFloat expected v = typeMismatch expected v
221−{-# INLINE parseRealFloat #-}
222−
223−parseIntegral :: Integral a => String -> Value -> Parser a
224−parseIntegral expected = withScientific expected $ pure . truncate
225−{-# INLINE parseIntegral #-}
226−
227−-------------------------------------------------------------------------------
228−-- base
229−-------------------------------------------------------------------------------
230−
231−instance ToJSON1 Identity where
232− liftToJSON to _ (Identity a) = to a
233− {-# INLINE liftToJSON #-}
234−
235− liftToEncoding to _ (Identity a) = to a
236− {-# INLINE liftToEncoding #-}
237−
238−instance (ToJSON a) => ToJSON (Identity a) where
239− toJSON = toJSON1
240− {-# INLINE toJSON #-}
241−
242− toEncoding = toEncoding1
243− {-# INLINE toEncoding #-}
244−
245−instance FromJSON1 Identity where
246− liftParseJSON p _ a = Identity <$> p a
247− {-# INLINE liftParseJSON #-}
248−
249−instance (FromJSON a) => FromJSON (Identity a) where
250− parseJSON = parseJSON1
251− {-# INLINE parseJSON #-}
252−
253−
254−instance ToJSON2 Const where
255− liftToJSON2 to _ _ _ (Const x) = to x
256− {-# INLINE liftToJSON2 #-}
257−
258− liftToEncoding2 to _ _ _ (Const x) = to x
259− {-# INLINE liftToEncoding2 #-}
260−
261−instance FromJSON2 Const where
262− liftParseJSON2 p _ _ _ = fmap Const . p
263− {-# INLINE liftParseJSON2 #-}
264−
265−instance ToJSON a => ToJSON1 (Const a) where
266− liftToJSON _ _ (Const x) = toJSON x
267− {-# INLINE liftToJSON #-}
268−
269− liftToEncoding _ _ (Const x) = toEncoding x
270− {-# INLINE liftToEncoding #-}
271−
272−instance FromJSON a => FromJSON1 (Const a) where
273− liftParseJSON _ _ = fmap Const . parseJSON
274− {-# INLINE liftParseJSON #-}
275−
276−instance ToJSON a => ToJSON (Const a b) where
277− toJSON (Const x) = toJSON x
278− {-# INLINE toJSON #-}
279−
280− toEncoding (Const x) = toEncoding x
281− {-# INLINE toEncoding #-}
282−
283−instance FromJSON a => FromJSON (Const a b) where
284− {-# INLINE parseJSON #-}
285− parseJSON = fmap Const . parseJSON
286−
287−
288−instance ToJSON1 Maybe where
289− liftToJSON to _ (Just a) = to a
290− liftToJSON _ _ Nothing = Null
291− {-# INLINE liftToJSON #-}
292−
293− liftToEncoding to _ (Just a) = to a
294− liftToEncoding _ _ Nothing = Encoding EB.null_
295− {-# INLINE liftToEncoding #-}
296−
297−instance (ToJSON a) => ToJSON (Maybe a) where
298− toJSON = toJSON1
299− {-# INLINE toJSON #-}
300−
301− toEncoding = toEncoding1
302− {-# INLINE toEncoding #-}
303−
304−instance FromJSON1 Maybe where
305− liftParseJSON _ _ Null = pure Nothing
306− liftParseJSON p _ a = Just <$> p a
307− {-# INLINE liftParseJSON #-}
308−
309−instance (FromJSON a) => FromJSON (Maybe a) where
310− parseJSON = parseJSON1
311− {-# INLINE parseJSON #-}
312−
313−
314−instance ToJSON2 Either where
315− liftToJSON2 toA _ _toB _ (Left a) = Object $ H.singleton left (toA a)
316− liftToJSON2 _toA _ toB _ (Right b) = Object $ H.singleton right (toB b)
317− {-# INLINE liftToJSON2 #-}
318−
319− liftToEncoding2 toA _ _toB _ (Left a) =
320− Encoding (B.shortByteString "{\"Left\":")
321− <> toA a
322− <> Encoding (B.char7 '}')
323−
324− liftToEncoding2 _toA _ toB _ (Right b) =
325− Encoding (B.shortByteString "{\"Right\":")
326− <> toB b
327− <> Encoding (B.char7 '}')
328− {-# INLINE liftToEncoding2 #-}
329−
330−instance (ToJSON a) => ToJSON1 (Either a) where
331− liftToJSON = liftToJSON2 toJSON toJSONList
332− {-# INLINE liftToJSON #-}
333−
334− liftToEncoding = liftToEncoding2 toEncoding toEncodingList
335− {-# INLINE liftToEncoding #-}
336−
337−instance (ToJSON a, ToJSON b) => ToJSON (Either a b) where
338− toJSON = toJSON2
339− {-# INLINE toJSON #-}
340−
341− toEncoding = toEncoding2
342− {-# INLINE toEncoding #-}
343−
344−instance FromJSON2 Either where
345− liftParseJSON2 pA _ pB _ (Object (H.toList -> [(key, value)]))
346− | key == left = Left <$> pA value <?> Key left
347− | key == right = Right <$> pB value <?> Key right
348−
349− liftParseJSON2 _ _ _ _ _ = fail $
350− "expected an object with a single property " ++
351− "where the property key should be either " ++
352− "\"Left\" or \"Right\""
353− {-# INLINE liftParseJSON2 #-}
354−
355−instance (FromJSON a) => FromJSON1 (Either a) where
356− liftParseJSON = liftParseJSON2 parseJSON parseJSONList
357− {-# INLINE liftParseJSON #-}
358−
359−instance (FromJSON a, FromJSON b) => FromJSON (Either a b) where
360− parseJSON = parseJSON2
361− {-# INLINE parseJSON #-}
362−
363−left, right :: Text
364−left = "Left"
365−right = "Right"
366−
367−
368−instance ToJSON Bool where
369− toJSON = Bool
370− {-# INLINE toJSON #-}
371−
372− toEncoding = Encoding . EB.bool
373− {-# INLINE toEncoding #-}
374−
375−instance FromJSON Bool where
376− parseJSON = withBool "Bool" pure
377− {-# INLINE parseJSON #-}
378−
379−instance ToJSON Ordering where
380− toJSON = toJSON . orderingToText
381− toEncoding = toEncoding . orderingToText
382−
383−orderingToText :: Ordering -> T.Text
384−orderingToText o = case o of
385− LT -> "LT"
386− EQ -> "EQ"
387− GT -> "GT"
388−
389−instance FromJSON Ordering where
390− parseJSON = withText "Ordering" $ \s ->
391− case s of
392− "LT" -> return LT
393− "EQ" -> return EQ
394− "GT" -> return GT
395− _ -> fail "Parsing Ordering value failed: expected \"LT\", \"EQ\", or \"GT\""
396−
397−instance ToJSON () where
398− toJSON _ = emptyArray
399− {-# INLINE toJSON #-}
400−
401− toEncoding _ = emptyArray_
402− {-# INLINE toEncoding #-}
403−
404−instance FromJSON () where
405− parseJSON = withArray "()" $ \v ->
406− if V.null v
407− then pure ()
408− else fail "Expected an empty array"
409− {-# INLINE parseJSON #-}
410−
411−instance ToJSON Char where
412− toJSON = String . T.singleton
413− {-# INLINE toJSON #-}
414−
415− toJSONList = String . T.pack
416− {-# INLINE toJSONList #-}
417−
418− toEncoding = Encoding . EB.string . (:[])
419− {-# INLINE toEncoding #-}
420−
421− toEncodingList = Encoding . EB.string
422− {-# INLINE toEncodingList #-}
423−
424−instance FromJSON Char where
425− parseJSON = withText "Char" $ \t ->
426− if T.compareLength t 1 == EQ
427− then pure $ T.head t
428− else fail "Expected a string of length 1"
429− {-# INLINE parseJSON #-}
430−
431− parseJSONList = withText "String" $ pure . T.unpack
432− {-# INLINE parseJSONList #-}
433−
434−instance ToJSON Double where
435− toJSON = realFloatToJSON
436− {-# INLINE toJSON #-}
437−
438− toEncoding = realFloatToEncoding
439− {-# INLINE toEncoding #-}
440−
441−instance FromJSON Double where
442− parseJSON = parseRealFloat "Double"
443− {-# INLINE parseJSON #-}
444−
445−instance ToJSON Number where
446− toJSON (D d) = toJSON d
447− toJSON (I i) = toJSON i
448− {-# INLINE toJSON #-}
449−
450− toEncoding (D d) = toEncoding d
451− toEncoding (I i) = toEncoding i
452− {-# INLINE toEncoding #-}
453−
454−instance FromJSON Number where
455− parseJSON (Number s) = pure $ scientificToNumber s
456− parseJSON Null = pure (D (0/0))
457− parseJSON v = typeMismatch "Number" v
458− {-# INLINE parseJSON #-}
459−
460−instance ToJSON Float where
461− toJSON = realFloatToJSON
462− {-# INLINE toJSON #-}
463−
464− toEncoding = realFloatToEncoding
465− {-# INLINE toEncoding #-}
466−
467−instance FromJSON Float where
468− parseJSON = parseRealFloat "Float"
469− {-# INLINE parseJSON #-}
470−
471−instance ToJSON (Ratio Integer) where
472− toJSON r = object [ "numerator" .= numerator r
473− , "denominator" .= denominator r
474− ]
475− {-# INLINE toJSON #-}
476−
477− toEncoding r = Encoding $
478− B.shortByteString "{\"numerator\":" <> builder (numerator r) <>
479− B.shortByteString ",\"denominator\":" <> builder (denominator r) <>
480− B.char7 '}'
481− {-# INLINE toEncoding #-}
482−
483−instance FromJSON (Ratio Integer) where
484− parseJSON = withObject "Rational" $ \obj ->
485− (%) <$> obj .: "numerator"
486− <*> obj .: "denominator"
487− {-# INLINE parseJSON #-}
488−
489−instance HasResolution a => ToJSON (Fixed a) where
490− toJSON = Number . realToFrac
491− {-# INLINE toJSON #-}
492−
493− toEncoding = Encoding . EB.number . realToFrac
494− {-# INLINE toEncoding #-}
495−
496−-- | /WARNING:/ Only parse fixed-precision numbers from trusted input
497−-- since an attacker could easily fill up the memory of the target
498−-- system by specifying a scientific number with a big exponent like
499−-- @1e1000000000@.
500−instance HasResolution a => FromJSON (Fixed a) where
501− parseJSON = withScientific "Fixed" $ pure . realToFrac
502− {-# INLINE parseJSON #-}
503−
504−instance ToJSON Int where
505− toJSON = Number . fromIntegral
506− {-# INLINE toJSON #-}
507−
508− toEncoding = Encoding . B.intDec
509− {-# INLINE toEncoding #-}
510−
511−instance FromJSON Int where
512− parseJSON = parseIntegral "Int"
513− {-# INLINE parseJSON #-}
514−
515−instance ToJSON Integer where
516− toJSON = Number . fromInteger
517− {-# INLINE toJSON #-}
518−
519− toEncoding = Encoding . B.integerDec
520− {-# INLINE toEncoding #-}
521−
522−-- | /WARNING:/ Only parse Integers from trusted input since an
523−-- attacker could easily fill up the memory of the target system by
524−-- specifying a scientific number with a big exponent like
525−-- @1e1000000000@.
526−instance FromJSON Integer where
527− parseJSON = withScientific "Integral" $ pure . truncate
528− {-# INLINE parseJSON #-}
529−
530−instance ToJSON Natural where
531− toJSON = toJSON . toInteger
532− {-# INLINE toJSON #-}
533−
534− toEncoding = toEncoding . toInteger
535− {-# INLINE toEncoding #-}
536−
537−instance FromJSON Natural where
538− parseJSON = withScientific "Natural" $ \s ->
539− if Scientific.coefficient s < 0
540− then fail $ "Expected a Natural number but got the negative number: " <> show s
541− else pure $ truncate s
542−
543−instance ToJSON Int8 where
544− toJSON = Number . fromIntegral
545− {-# INLINE toJSON #-}
546−
547− toEncoding = Encoding . B.int8Dec
548− {-# INLINE toEncoding #-}
549−
550−instance FromJSON Int8 where
551− parseJSON = parseIntegral "Int8"
552− {-# INLINE parseJSON #-}
553−
554−instance ToJSON Int16 where
555− toJSON = Number . fromIntegral
556− {-# INLINE toJSON #-}
557−
558− toEncoding = Encoding . B.int16Dec
559− {-# INLINE toEncoding #-}
560−
561−instance FromJSON Int16 where
562− parseJSON = parseIntegral "Int16"
563− {-# INLINE parseJSON #-}
564−
565−instance ToJSON Int32 where
566− toJSON = Number . fromIntegral
567− {-# INLINE toJSON #-}
568−
569− toEncoding = Encoding . B.int32Dec
570− {-# INLINE toEncoding #-}
571−
572−instance FromJSON Int32 where
573− parseJSON = parseIntegral "Int32"
574− {-# INLINE parseJSON #-}
575−
576−instance ToJSON Int64 where
577− toJSON = Number . fromIntegral
578− {-# INLINE toJSON #-}
579−
580− toEncoding = Encoding . B.int64Dec
581− {-# INLINE toEncoding #-}
582−
583−instance FromJSON Int64 where
584− parseJSON = parseIntegral "Int64"
585− {-# INLINE parseJSON #-}
586−
587−instance ToJSON Word where
588− toJSON = Number . fromIntegral
589− {-# INLINE toJSON #-}
590−
591− toEncoding = Encoding . B.wordDec
592− {-# INLINE toEncoding #-}
593−
594−instance FromJSON Word where
595− parseJSON = parseIntegral "Word"
596− {-# INLINE parseJSON #-}
597−
598−instance ToJSON Word8 where
599− toJSON = Number . fromIntegral
600− {-# INLINE toJSON #-}
601−
602− toEncoding = Encoding . B.word8Dec
603− {-# INLINE toEncoding #-}
604−
605−instance FromJSON Word8 where
606− parseJSON = parseIntegral "Word8"
607− {-# INLINE parseJSON #-}
608−
609−instance ToJSON Word16 where
610− toJSON = Number . fromIntegral
611− {-# INLINE toJSON #-}
612−
613− toEncoding = Encoding . B.word16Dec
614− {-# INLINE toEncoding #-}
615−
616−instance FromJSON Word16 where
617− parseJSON = parseIntegral "Word16"
618− {-# INLINE parseJSON #-}
619−
620−instance ToJSON Word32 where
621− toJSON = Number . fromIntegral
622− {-# INLINE toJSON #-}
623−
624− toEncoding = Encoding . B.word32Dec
625− {-# INLINE toEncoding #-}
626−
627−instance FromJSON Word32 where
628− parseJSON = parseIntegral "Word32"
629− {-# INLINE parseJSON #-}
630−
631−instance ToJSON Word64 where
632− toJSON = Number . fromIntegral
633− {-# INLINE toJSON #-}
634−
635− toEncoding = Encoding . B.word64Dec
636− {-# INLINE toEncoding #-}
637−
638−instance FromJSON Word64 where
639− parseJSON = parseIntegral "Word64"
640− {-# INLINE parseJSON #-}
641−
642−instance ToJSON Text where
643− toJSON = String
644− {-# INLINE toJSON #-}
645−
646− toEncoding = Encoding . EB.text
647− {-# INLINE toEncoding #-}
648−
649−instance FromJSON Text where
650− parseJSON = withText "Text" pure
651− {-# INLINE parseJSON #-}
652−
653−instance ToJSON LT.Text where
654− toJSON = String . LT.toStrict
655− {-# INLINE toJSON #-}
656−
657− toEncoding t = Encoding $
658− B.char7 '"' <>
659− LT.foldrChunks (\x xs -> EB.unquoted x <> xs) (B.char7 '"') t
660− {-# INLINE toEncoding #-}
661−
662−instance FromJSON LT.Text where
663− parseJSON = withText "Lazy Text" $ pure . LT.fromStrict
664− {-# INLINE parseJSON #-}
665−
666−instance ToJSON Version where
667− toJSON = toJSON . showVersion
668− {-# INLINE toJSON #-}
669−
670− toEncoding = toEncoding . showVersion
671− {-# INLINE toEncoding #-}
672−
673−instance FromJSON Version where
674− {-# INLINE parseJSON #-}
675− parseJSON = withText "Version" $ go . readP_to_S parseVersion . unpack
676− where
677− go [(v,[])] = return v
678− go (_ : xs) = go xs
679− go _ = fail $ "could not parse Version"
680−
681−-------------------------------------------------------------------------------
682−-- semigroups NonEmpty
683−-------------------------------------------------------------------------------
684−
685−instance ToJSON1 NonEmpty where
686− liftToJSON to _ = listValue to . NE.toList
687− {-# INLINE liftToJSON #-}
688−
689− liftToEncoding to _ = listEncoding to . NE.toList
690− {-# INLINE liftToEncoding #-}
691−
692−instance (ToJSON a) => ToJSON (NonEmpty a) where
693− toJSON = toJSON1
694− {-# INLINE toJSON #-}
695−
696− toEncoding = toEncoding1
697− {-# INLINE toEncoding #-}
698−
699−instance FromJSON1 NonEmpty where
700− liftParseJSON p _ = withArray "NonEmpty a" $
701− (>>= ne) . Tr.sequence . zipWith (parseIndexedJSON p) [0..] . V.toList
702− where
703− ne [] = fail "Expected a NonEmpty but got an empty list"
704− ne (x:xs) = pure (x :| xs)
705− {-# INLINE liftParseJSON #-}
706−
707−instance (FromJSON a) => FromJSON (NonEmpty a) where
708− parseJSON = parseJSON1
709− {-# INLINE parseJSON #-}
710−
711−-------------------------------------------------------------------------------
712−-- scientific
713−-------------------------------------------------------------------------------
714−
715−instance ToJSON Scientific where
716− toJSON = Number
717− {-# INLINE toJSON #-}
718−
719− toEncoding = Encoding . EB.number
720− {-# INLINE toEncoding #-}
721−
722−instance FromJSON Scientific where
723− parseJSON = withScientific "Scientific" pure
724− {-# INLINE parseJSON #-}
725−
726−-------------------------------------------------------------------------------
727−-- containers
728−-------------------------------------------------------------------------------
729−
730−instance ToJSON1 Seq.Seq where
731− liftToJSON to _ = listValue to . toList
732− {-# INLINE liftToJSON #-}
733−
734− liftToEncoding to _ = listEncoding to . toList
735− {-# INLINE liftToEncoding #-}
736−
737−instance (ToJSON a) => ToJSON (Seq.Seq a) where
738− toJSON = toJSON1
739− {-# INLINE toJSON #-}
740−
741− toEncoding = toEncoding1
742− {-# INLINE toEncoding #-}
743−
744−instance FromJSON1 Seq.Seq where
745− liftParseJSON p _ = withArray "Seq a" $
746− fmap Seq.fromList .
747− Tr.sequence . zipWith (parseIndexedJSON p) [0..] . V.toList
748− {-# INLINE liftParseJSON #-}
749−
750−instance (FromJSON a) => FromJSON (Seq.Seq a) where
751− parseJSON = parseJSON1
752− {-# INLINE parseJSON #-}
753−
754−
755−instance ToJSON1 Set.Set where
756− liftToJSON to _ = listValue to . Set.toList
757− {-# INLINE liftToJSON #-}
758−
759− liftToEncoding to _ = listEncoding to . Set.toList
760− {-# INLINE liftToEncoding #-}
761−
762−instance (ToJSON a) => ToJSON (Set.Set a) where
763− toJSON = toJSON1
764− {-# INLINE toJSON #-}
765−
766− toEncoding = toEncoding1
767− {-# INLINE toEncoding #-}
768−
769−instance (Ord a, FromJSON a) => FromJSON (Set.Set a) where
770− parseJSON = fmap Set.fromList . parseJSON
771− {-# INLINE parseJSON #-}
772−
773−
774−instance FromJSON IntSet.IntSet where
775− parseJSON = fmap IntSet.fromList . parseJSON
776− {-# INLINE parseJSON #-}
777−
778−instance ToJSON IntSet.IntSet where
779− toJSON = toJSON . IntSet.toList
780− {-# INLINE toJSON #-}
781−
782− toEncoding = toEncoding . IntSet.toList
783− {-# INLINE toEncoding #-}
784−
785−
786−instance ToJSON1 IntMap.IntMap where
787− liftToJSON to tol = liftToJSON to' tol' . IntMap.toList
788− where
789− to' = liftToJSON2 toJSON toJSONList to tol
790− tol' = liftToJSONList2 toJSON toJSONList to tol
791− {-# INLINE liftToJSON #-}
792−
793− liftToEncoding to tol = liftToEncoding to' tol' . IntMap.toList
794− where
795− to' = liftToEncoding2 toEncoding toEncodingList to tol
796− tol' = liftToEncodingList2 toEncoding toEncodingList to tol
797− {-# INLINE liftToEncoding #-}
798−
799−instance ToJSON a => ToJSON (IntMap.IntMap a) where
800− toJSON = toJSON1
801− {-# INLINE toJSON #-}
802−
803− toEncoding = toEncoding1
804− {-# INLINE toEncoding #-}
805−
806−instance FromJSON1 IntMap.IntMap where
807− liftParseJSON p pl = fmap IntMap.fromList . liftParseJSON p' pl'
808− where
809− p' = liftParseJSON2 parseJSON parseJSONList p pl
810− pl' = liftParseJSONList2 parseJSON parseJSONList p pl
811− {-# INLINE liftParseJSON #-}
812−
813−instance FromJSON a => FromJSON (IntMap.IntMap a) where
814− parseJSON = fmap IntMap.fromList . parseJSON
815− {-# INLINE parseJSON #-}
816−
817−
818−instance ToJSONKey k => ToJSON1 (M.Map k) where
819− liftToJSON g _ = case toJSONKey of
820− ToJSONKeyText (f,_) -> Object . mapHashKeyVal f g
821− ToJSONKeyValue (f,_) -> Array . V.fromList . map (toJSONPair f g) . M.toList
822− {-# INLINE liftToJSON #-}
823−
824− -- liftToEncoding :: forall a. (a -> Encoding) -> ([a] -> Encoding) -> M.Map k a -> Encoding
825− liftToEncoding g _ = case toJSONKey of
826− ToJSONKeyText (_,f) -> dict f g M.foldrWithKey
827− ToJSONKeyValue (_,f) -> listEncoding (pairEncoding f) . M.toList
828− where
829− -- pairEncoding :: (k -> Encoding) -> (k, a) -> Encoding
830− pairEncoding f (a, b) = tuple $ f a >*< g b
831− {-# INLINE liftToEncoding #-}
832−
833−instance (FromJSONKey k, Ord k) => FromJSON1 (M.Map k) where
834− liftParseJSON p _ = case fromJSONKey of
835− FromJSONKeyCoerce _-> withObject "Map k v" $
836− fmap (H.foldrWithKey (M.insert . unsafeCoerce) M.empty) . H.traverseWithKey (\k v -> p v <?> Key k)
837− FromJSONKeyText f -> withObject "Map k v" $
838− fmap (H.foldrWithKey (M.insert . f) M.empty) . H.traverseWithKey (\k v -> p v <?> Key k)
839− FromJSONKeyTextParser f -> withObject "Map k v" $
840− H.foldrWithKey (\k v m -> M.insert <$> f k <*> (p v <?> Key k) <*> m) (pure M.empty)
841− FromJSONKeyValue f -> withArray "Map k v" $ \arr ->
842− M.fromList <$> (Tr.sequence .
843− zipWith (parseIndexedJSONPair f p) [0..] . V.toList $ arr)
844− {-# INLINE liftParseJSON #-}
845−
846−instance (ToJSON v, ToJSONKey k) => ToJSON (M.Map k v) where
847− toJSON = toJSON1
848− {-# INLINE toJSON #-}
849−
850− toEncoding = toEncoding1
851− {-# INLINE toEncoding #-}
852−
853−instance (FromJSON v, FromJSONKey k, Ord k) => FromJSON (M.Map k v) where
854− parseJSON = parseJSON1
855− {-# INLINE parseJSON #-}
856−
857−
858−instance ToJSON1 Tree.Tree where
859− liftToJSON to tol = go
860− where
861− go (Tree.Node root branches) =
862− liftToJSON2 to tol to' tol' (root, branches)
863−
864− to' = liftToJSON go (listValue go)
865− tol' = liftToJSONList go (listValue go)
866− {-# INLINE liftToJSON #-}
867−
868− liftToEncoding to tol = go
869− where
870− go (Tree.Node root branches) =
871− liftToEncoding2 to tol to' tol' (root, branches)
872−
873− to' = liftToEncoding go (listEncoding go)
874− tol' = liftToEncodingList go (listEncoding go)
875− {-# INLINE liftToEncoding #-}
876−
877−instance (ToJSON v) => ToJSON (Tree.Tree v) where
878− toJSON = toJSON1
879− {-# INLINE toJSON #-}
880−
881− toEncoding = toEncoding1
882− {-# INLINE toEncoding #-}
883−
884−instance FromJSON1 Tree.Tree where
885− liftParseJSON p pl = go
886− where
887− go v = uncurry Tree.Node <$> liftParseJSON2 p pl p' pl' v
888−
889− p' = liftParseJSON go (listParser go)
890− pl'= liftParseJSONList go (listParser go)
891−
892−instance (FromJSON v) => FromJSON (Tree.Tree v) where
893− parseJSON = parseJSON1
894− {-# INLINE parseJSON #-}
895−
896−-------------------------------------------------------------------------------
897−-- vector
898−-------------------------------------------------------------------------------
899−
900−instance ToJSON1 Vector where
901− liftToJSON to _ = Array . V.map to
902− {-# INLINE liftToJSON #-}
903−
904− liftToEncoding to _ xs
905− | V.null xs = emptyArray_
906− | otherwise = Encoding $
907− B.char7 '[' <> fromEncoding (to (V.unsafeHead xs)) <>
908− V.foldr go (B.char7 ']') (V.unsafeTail xs)
909− where
910− go v b = B.char7 ',' <> fromEncoding (to v) <> b
911− {-# INLINE liftToEncoding #-}
912−
913−instance (ToJSON a) => ToJSON (Vector a) where
914− toJSON = Array . V.map toJSON
915− {-# INLINE toJSON #-}
916−
917− toEncoding = encodeVector
918− {-# INLINE toEncoding #-}
919−
920−encodeVector :: (ToJSON a, VG.Vector v a) => v a -> Encoding
921−encodeVector xs
922− | VG.null xs = emptyArray_
923− | otherwise = Encoding $
924− B.char7 '[' <> builder (VG.unsafeHead xs) <>
925− VG.foldr go (B.char7 ']') (VG.unsafeTail xs)
926− where go v b = B.char7 ',' <> builder v <> b
927−{-# INLINE encodeVector #-}
928−
929−instance FromJSON1 Vector where
930− liftParseJSON p _ = withArray "Vector a" $
931− V.mapM (uncurry $ parseIndexedJSON p) . V.indexed
932− {-# INLINE liftParseJSON #-}
933−
934−instance (FromJSON a) => FromJSON (Vector a) where
935− parseJSON = parseJSON1
936− {-# INLINE parseJSON #-}
937−
938−vectorToJSON :: (VG.Vector v a, ToJSON a) => v a -> Value
939−vectorToJSON = Array . V.map toJSON . V.convert
940−{-# INLINE vectorToJSON #-}
941−
942−vectorParseJSON :: (FromJSON a, VG.Vector w a) => String -> Value -> Parser (w a)
943−vectorParseJSON s = withArray s $ fmap V.convert . V.mapM (uncurry $ parseIndexedJSON parseJSON) . V.indexed
944−{-# INLINE vectorParseJSON #-}
945−
946−instance (Storable a, ToJSON a) => ToJSON (VS.Vector a) where
947− toJSON = vectorToJSON
948− {-# INLINE toJSON #-}
949−
950− toEncoding = encodeVector
951− {-# INLINE toEncoding #-}
952−
953−instance (Storable a, FromJSON a) => FromJSON (VS.Vector a) where
954− parseJSON = vectorParseJSON "Data.Vector.Storable.Vector a"
955−
956−instance (VP.Prim a, ToJSON a) => ToJSON (VP.Vector a) where
957− toJSON = vectorToJSON
958− {-# INLINE toJSON #-}
959−
960− toEncoding = encodeVector
961− {-# INLINE toEncoding #-}
962−
963−instance (VP.Prim a, FromJSON a) => FromJSON (VP.Vector a) where
964− parseJSON = vectorParseJSON "Data.Vector.Primitive.Vector a"
965− {-# INLINE parseJSON #-}
966−
967−instance (VG.Vector VU.Vector a, ToJSON a) => ToJSON (VU.Vector a) where
968− toJSON = vectorToJSON
969− {-# INLINE toJSON #-}
970−
971− toEncoding = encodeVector
972− {-# INLINE toEncoding #-}
973−
974−instance (VG.Vector VU.Vector a, FromJSON a) => FromJSON (VU.Vector a) where
975− parseJSON = vectorParseJSON "Data.Vector.Unboxed.Vector a"
976− {-# INLINE parseJSON #-}
977−
978−-------------------------------------------------------------------------------
979−-- unordered-containers
980−-------------------------------------------------------------------------------
981−
982−instance ToJSON1 HashSet.HashSet where
983− liftToJSON to _ = listValue to . HashSet.toList
984− {-# INLINE liftToJSON #-}
985−
986− liftToEncoding to _ = listEncoding to . HashSet.toList
987− {-# INLINE liftToEncoding #-}
988−
989−instance (ToJSON a) => ToJSON (HashSet.HashSet a) where
990− toJSON = toJSON1
991− {-# INLINE toJSON #-}
992−
993− toEncoding = toEncoding1
994− {-# INLINE toEncoding #-}
995−
996−instance (Eq a, Hashable a, FromJSON a) => FromJSON (HashSet.HashSet a) where
997− parseJSON = fmap HashSet.fromList . parseJSON
998− {-# INLINE parseJSON #-}
999−
1000−
1001−instance ToJSONKey k => ToJSON1 (H.HashMap k) where
1002− liftToJSON g _ = case toJSONKey of
1003− ToJSONKeyText (f,_) -> Object . mapKeyVal f g
1004− ToJSONKeyValue (f,_) -> Array . V.fromList . map (toJSONPair f g) . H.toList
1005− {-# INLINE liftToJSON #-}
1006−
1007− -- liftToEncoding :: forall a. (a -> Encoding) -> ([a] -> Encoding) -> H.HashMap k a -> Encoding
1008− liftToEncoding g _ = case toJSONKey of
1009− ToJSONKeyText (_,f) -> dict f g H.foldrWithKey
1010− ToJSONKeyValue (_,f) -> listEncoding (pairEncoding f) . H.toList
1011− where
1012− -- pairEncoding :: (k -> Encoding) -> (k, a) -> Encoding
1013− pairEncoding f (a, b) = tuple $ f a >*< g b
1014− {-# INLINE liftToEncoding #-}
1015−
1016−instance (ToJSON v, ToJSONKey k) => ToJSON (H.HashMap k v) where
1017− toJSON = toJSON1
1018− {-# INLINE toJSON #-}
1019−
1020− toEncoding = toEncoding1
1021− {-# INLINE toEncoding #-}
1022−
1023−instance (FromJSONKey k, Eq k, Hashable k) => FromJSON1 (H.HashMap k) where
1024− liftParseJSON p _ = case fromJSONKey of
1025− FromJSONKeyCoerce _ -> withObject "HashMap ~Text v" $
1026− uc . H.traverseWithKey (\k v -> p v <?> Key k)
1027− FromJSONKeyText f -> withObject "HashMap k v" $
1028− fmap (mapKey f) . H.traverseWithKey (\k v -> p v <?> Key k)
1029− FromJSONKeyTextParser f -> withObject "HashMap k v" $
1030− H.foldrWithKey (\k v m -> H.insert <$> f k <*> (p v <?> Key k) <*> m) (pure H.empty)
1031− FromJSONKeyValue f -> withArray "Map k v" $ \arr ->
1032− H.fromList <$> (Tr.sequence .
1033− zipWith (parseIndexedJSONPair f p) [0..] . V.toList $ arr)
1034− where
1035− uc :: Parser (H.HashMap Text v) -> Parser (H.HashMap k v)
1036− uc = unsafeCoerce
1037−
1038−instance (FromJSON v, FromJSONKey k, Eq k, Hashable k) => FromJSON (H.HashMap k v) where
1039− parseJSON = parseJSON1
1040− {-# INLINE parseJSON #-}
1041−
1042−-------------------------------------------------------------------------------
1043−-- aeson
1044−-------------------------------------------------------------------------------
1045−
1046−instance ToJSON Value where
1047− toJSON a = a
1048− {-# INLINE toJSON #-}
1049−
1050− toEncoding = Encoding . EB.encodeToBuilder
1051− {-# INLINE toEncoding #-}
1052−
1053−instance FromJSON Value where
1054− parseJSON = pure
1055− {-# INLINE parseJSON #-}
1056−
1057−instance ToJSON DotNetTime where
1058− toJSON = toJSON . dotNetTime
1059−
1060− toEncoding = toEncoding . dotNetTime
1061−
1062−dotNetTime :: DotNetTime -> String
1063−dotNetTime (DotNetTime t) = secs ++ formatMillis t ++ ")/"
1064− where secs = formatTime defaultTimeLocale "/Date(%s" t
1065−
1066−instance FromJSON DotNetTime where
1067− parseJSON = withText "DotNetTime" $ \t ->
1068− let (s,m) = T.splitAt (T.length t - 5) t
1069− t' = T.concat [s,".",m]
1070− in case parseTime defaultTimeLocale "/Date(%s%Q)/" (unpack t') of
1071− Just d -> pure (DotNetTime d)
1072− _ -> fail "could not parse .NET time"
1073− {-# INLINE parseJSON #-}
1074−
1075−-------------------------------------------------------------------------------
1076−-- time
1077−-------------------------------------------------------------------------------
1078−
1079−instance ToJSON Day where
1080− toJSON = stringEncoding
1081− toEncoding z = Encoding (EB.quote $ EB.day z)
1082−
1083−instance FromJSON Day where
1084− parseJSON = withText "Day" (Time.run Time.day)
1085−
1086−instance ToJSON TimeOfDay where
1087− toJSON = stringEncoding
1088− toEncoding z = Encoding (EB.quote $ EB.timeOfDay z)
1089−
1090−instance FromJSON TimeOfDay where
1091− parseJSON = withText "TimeOfDay" (Time.run Time.timeOfDay)
1092−
1093−instance ToJSON LocalTime where
1094− toJSON = stringEncoding
1095− toEncoding z = Encoding (EB.quote $ EB.localTime z)
1096−
1097−instance FromJSON LocalTime where
1098− parseJSON = withText "LocalTime" (Time.run Time.localTime)
1099−
1100−instance ToJSON ZonedTime where
1101− toJSON = stringEncoding
1102−
1103− toEncoding z = Encoding (EB.quote $ EB.zonedTime z)
1104−
1105−formatMillis :: (FormatTime t) => t -> String
1106−formatMillis = take 3 . formatTime defaultTimeLocale "%q"
1107−
1108−instance FromJSON ZonedTime where
1109− parseJSON = withText "ZonedTime" (Time.run Time.zonedTime)
1110−
1111−instance ToJSON UTCTime where
1112− toJSON = stringEncoding
1113−
1114− toEncoding t = Encoding (EB.quote $ EB.utcTime t)
1115−
1116−-- | Encode something to a JSON string.
1117−--
1118−-- TODO: remove me, this is a hack
1119−stringEncoding :: (ToJSON a) => a -> Value
1120−stringEncoding = String
1121− . T.dropAround (== '"')
1122− . T.decodeLatin1
1123− . L.toStrict
1124− . B.toLazyByteString
1125− . fromEncoding
1126− . toEncoding
1127−{-# INLINE stringEncoding #-}
1128−
1129−instance FromJSON UTCTime where
1130− parseJSON = withText "UTCTime" (Time.run Time.utcTime)
1131−
1132−instance ToJSON NominalDiffTime where
1133− toJSON = Number . realToFrac
1134− {-# INLINE toJSON #-}
1135−
1136− toEncoding = Encoding . EB.number . realToFrac
1137− {-# INLINE toEncoding #-}
1138−
1139−-- | /WARNING:/ Only parse lengths of time from trusted input
1140−-- since an attacker could easily fill up the memory of the target
1141−-- system by specifying a scientific number with a big exponent like
1142−-- @1e1000000000@.
1143−instance FromJSON NominalDiffTime where
1144− parseJSON = withScientific "NominalDiffTime" $ pure . realToFrac
1145− {-# INLINE parseJSON #-}
1146−
1147−-------------------------------------------------------------------------------
1148−-- base Monoid/Semigroup
1149−-------------------------------------------------------------------------------
1150−
1151−instance ToJSON1 Dual where
1152− liftToJSON to _ = to . getDual
1153− {-# INLINE liftToJSON #-}
1154−
1155− liftToEncoding to _ = to . getDual
1156− {-# INLINE liftToEncoding #-}
1157−
1158−instance ToJSON a => ToJSON (Dual a) where
1159− toJSON = toJSON1
1160− {-# INLINE toJSON #-}
1161−
1162− toEncoding = toEncoding1
1163− {-# INLINE toEncoding #-}
1164−
1165−instance FromJSON1 Dual where
1166− liftParseJSON p _ = fmap Dual . p
1167− {-# INLINE liftParseJSON #-}
1168−
1169−instance FromJSON a => FromJSON (Dual a) where
1170− parseJSON = parseJSON1
1171− {-# INLINE parseJSON #-}
1172−
1173−
1174−instance ToJSON1 First where
1175− liftToJSON to to' = liftToJSON to to' . getFirst
1176− {-# INLINE liftToJSON #-}
1177−
1178− liftToEncoding to to' = liftToEncoding to to' . getFirst
1179− {-# INLINE liftToEncoding #-}
1180−
1181−instance ToJSON a => ToJSON (First a) where
1182− toJSON = toJSON1
1183− {-# INLINE toJSON #-}
1184−
1185− toEncoding = toEncoding1
1186− {-# INLINE toEncoding #-}
1187−
1188−instance FromJSON1 First where
1189− liftParseJSON p p' = fmap First . liftParseJSON p p'
1190− {-# INLINE liftParseJSON #-}
1191−
1192−instance FromJSON a => FromJSON (First a) where
1193− parseJSON = parseJSON1
1194− {-# INLINE parseJSON #-}
1195−
1196−
1197−instance ToJSON1 Last where
1198− liftToJSON to to' = liftToJSON to to' . getLast
1199− {-# INLINE liftToJSON #-}
1200−
1201− liftToEncoding to to' = liftToEncoding to to' . getLast
1202− {-# INLINE liftToEncoding #-}
1203−
1204−instance ToJSON a => ToJSON (Last a) where
1205− toJSON = toJSON1
1206− {-# INLINE toJSON #-}
1207−
1208− toEncoding = toEncoding1
1209− {-# INLINE toEncoding #-}
1210−
1211−instance FromJSON1 Last where
1212− liftParseJSON p p' = fmap Last . liftParseJSON p p'
1213− {-# INLINE liftParseJSON #-}
1214−
1215−instance FromJSON a => FromJSON (Last a) where
1216− parseJSON = parseJSON1
1217− {-# INLINE parseJSON #-}
1218−
1219−-------------------------------------------------------------------------------
1220−-- tagged
1221−-------------------------------------------------------------------------------
1222−
1223−instance ToJSON (Proxy a) where
1224− toJSON _ = Null
1225− {-# INLINE toJSON #-}
1226−
1227− toEncoding _ = Encoding EB.null_
1228− {-# INLINE toEncoding #-}
1229−
1230−instance FromJSON (Proxy a) where
1231− {-# INLINE parseJSON #-}
1232− parseJSON Null = pure Proxy
1233− parseJSON v = typeMismatch "Proxy" v
1234−
1235−
1236−instance ToJSON1 (Tagged a) where
1237− liftToJSON to _ (Tagged x) = to x
1238− {-# INLINE liftToJSON #-}
1239−
1240− liftToEncoding to _ (Tagged x) = to x
1241− {-# INLINE liftToEncoding #-}
1242−
1243−instance ToJSON b => ToJSON (Tagged a b) where
1244− toJSON = toJSON1
1245− {-# INLINE toJSON #-}
1246−
1247− toEncoding = toEncoding1
1248− {-# INLINE toEncoding #-}
1249−
1250−instance FromJSON1 (Tagged a) where
1251− liftParseJSON p _ = fmap Tagged . p
1252− {-# INLINE liftParseJSON #-}
1253−
1254−instance FromJSON b => FromJSON (Tagged a b) where
1255− parseJSON = parseJSON1
1256− {-# INLINE parseJSON #-}
1257−
1258−instance FromJSONKey b => FromJSONKey (Tagged a b) where
1259− fromJSONKey = coerceFromJSONKeyFunction (fromJSONKey :: FromJSONKeyFunction b)
1260− fromJSONKeyList = (fmap . fmap) Tagged fromJSONKeyList
1261−
1262−instance ToJSONKey b => ToJSONKey (Tagged a b) where
1263− toJSONKey = contramapToJSONKeyFunction unTagged toJSONKey
1264− toJSONKeyList = contramapToJSONKeyFunction (fmap unTagged) toJSONKeyList
1265−
1266−-------------------------------------------------------------------------------
1267−-- Instances for converting to/from map keys
1268−-------------------------------------------------------------------------------
1269−
1270−
1271−
1272−instance ToJSONKey Text where
1273− toJSONKey = ToJSONKeyText (id,toEncoding)
1274−
1275−instance FromJSONKey Text where
1276− fromJSONKey = fromJSONKeyCoerce
1277−
1278−
1279−
1280−instance ToJSONKey Bool where
1281− toJSONKey = ToJSONKeyText
1282− ( (\x -> if x then "true" else "false")
1283− , (\x -> Encoding $ if x then "\"true\"" else "\"false\"")
1284− )
1285−
1286−instance ToJSONKey Int where
1287− toJSONKey = ToJSONKeyText
1288− ( LT.toStrict . LTB.toLazyText . LTBI.decimal
1289− , \x -> Encoding $ B.char7 '"' <> fromEncoding (toEncoding x) <> B.char7 '"'
1290− )
1291−
1292−instance FromJSONKey Int where
1293− -- not sure if there if there is already a helper in
1294− -- aeson for doing this.
1295− fromJSONKey = FromJSONKeyTextParser $ \t -> case TR.decimal t of
1296− Left err -> fail err
1297− Right (v,t2) -> if T.null t2
1298− then return v
1299− else fail "Was not an integer, had extra stuff."
1300−
1301−instance (ToJSON a, ToJSON b) => ToJSONKey (a,b)
1302−instance (ToJSON a, ToJSON b, ToJSON c) => ToJSONKey (a,b,c)
1303−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d) => ToJSONKey (a,b,c,d)
1304−
1305−instance (FromJSON a, FromJSON b) => FromJSONKey (a,b)
1306−instance (FromJSON a, FromJSON b, FromJSON c) => FromJSONKey (a,b,c)
1307−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d) => FromJSONKey (a,b,c,d)
1308−
1309−instance ToJSONKey Char where
1310− toJSONKey = ToJSONKeyText (T.singleton, toEncoding)
1311− toJSONKeyList = ToJSONKeyText (T.pack, toEncoding . T.pack)
1312−
1313−instance FromJSONKey Char where
1314− fromJSONKey = FromJSONKeyTextParser $ \t ->
1315− if T.length t == 1
1316− then return (T.index t 0)
1317− else typeMismatch "Expected Char but String didn't contain exactly one character" (String t)
1318− fromJSONKeyList = FromJSONKeyText T.unpack
1319−
1320−instance (ToJSONKey a, ToJSON a) => ToJSONKey [a] where
1321− toJSONKey = toJSONKeyList
1322−
1323−instance (FromJSONKey a, FromJSON a) => FromJSONKey [a] where
1324− fromJSONKey = fromJSONKeyList
1325−
1326−instance (ToJSONKey a, ToJSON a) => ToJSONKey (Identity a) where
1327− toJSONKey = contramapToJSONKeyFunction runIdentity toJSONKey
1328−
1329−instance (FromJSONKey a, FromJSON a) => FromJSONKey (Identity a) where
1330− fromJSONKey = mapFromJSONKeyFunction Identity fromJSONKey
1331−
1332−-------------------------------------------------------------------------------
1333−-- Functions
1334−-------------------------------------------------------------------------------
1335−
1336−-- | @withObject expected f value@ applies @f@ to the 'Object' when @value@ is an @Object@
1337−-- and fails using @'typeMismatch' expected@ otherwise.
1338−withObject :: String -> (Object -> Parser a) -> Value -> Parser a
1339−withObject _ f (Object obj) = f obj
1340−withObject expected _ v = typeMismatch expected v
1341−{-# INLINE withObject #-}
1342−
1343−-- | @withText expected f value@ applies @f@ to the 'Text' when @value@ is a @String@
1344−-- and fails using @'typeMismatch' expected@ otherwise.
1345−withText :: String -> (Text -> Parser a) -> Value -> Parser a
1346−withText _ f (String txt) = f txt
1347−withText expected _ v = typeMismatch expected v
1348−{-# INLINE withText #-}
1349−
1350−-- | @withArray expected f value@ applies @f@ to the 'Array' when @value@ is an @Array@
1351−-- and fails using @'typeMismatch' expected@ otherwise.
1352−withArray :: String -> (Array -> Parser a) -> Value -> Parser a
1353−withArray _ f (Array arr) = f arr
1354−withArray expected _ v = typeMismatch expected v
1355−{-# INLINE withArray #-}
1356−
1357−-- | @withNumber expected f value@ applies @f@ to the 'Number' when @value@ is a 'Number'.
1358−-- and fails using @'typeMismatch' expected@ otherwise.
1359−withNumber :: String -> (Number -> Parser a) -> Value -> Parser a
1360−withNumber expected f = withScientific expected (f . scientificToNumber)
1361−{-# INLINE withNumber #-}
1362−{-# DEPRECATED withNumber "Use withScientific instead" #-}
1363−
1364−-- | @withScientific expected f value@ applies @f@ to the 'Scientific' number when @value@ is a 'Number'.
1365−-- and fails using @'typeMismatch' expected@ otherwise.
1366−withScientific :: String -> (Scientific -> Parser a) -> Value -> Parser a
1367−withScientific _ f (Number scientific) = f scientific
1368−withScientific expected _ v = typeMismatch expected v
1369−{-# INLINE withScientific #-}
1370−
1371−-- | @withBool expected f value@ applies @f@ to the 'Bool' when @value@ is a @Bool@
1372−-- and fails using @'typeMismatch' expected@ otherwise.
1373−withBool :: String -> (Bool -> Parser a) -> Value -> Parser a
1374−withBool _ f (Bool arr) = f arr
1375−withBool expected _ v = typeMismatch expected v
1376−{-# INLINE withBool #-}
1377−
1378−-- | Convert a value from JSON, failing if the types do not match.
1379−fromJSON :: (FromJSON a) => Value -> Result a
1380−fromJSON = parse parseJSON
1381−{-# INLINE fromJSON #-}
1382−
1383−-- | Convert a value from JSON, failing if the types do not match.
1384−ifromJSON :: (FromJSON a) => Value -> IResult a
1385−ifromJSON = iparse parseJSON
1386−{-# INLINE ifromJSON #-}
1387−
1388−-- | Retrieve the value associated with the given key of an 'Object'.
1389−-- The result is 'empty' if the key is not present or the value cannot
1390−-- be converted to the desired type.
1391−--
1392−-- This accessor is appropriate if the key and value /must/ be present
1393−-- in an object for it to be valid. If the key and value are
1394−-- optional, use '.:?' instead.
1395−(.:) :: (FromJSON a) => Object -> Text -> Parser a
1396−obj .: key = case H.lookup key obj of
1397− Nothing -> fail $ "key " ++ show key ++ " not present"
1398− Just v -> parseJSON v <?> Key key
1399−{-# INLINE (.:) #-}
1400−
1401−-- | Retrieve the value associated with the given key of an 'Object'.
1402−-- The result is 'Nothing' if the key is not present, or 'empty' if
1403−-- the value cannot be converted to the desired type.
1404−--
1405−-- This accessor is most useful if the key and value can be absent
1406−-- from an object without affecting its validity. If the key and
1407−-- value are mandatory, use '.:' instead.
1408−(.:?) :: (FromJSON a) => Object -> Text -> Parser (Maybe a)
1409−obj .:? key = case H.lookup key obj of
1410− Nothing -> pure Nothing
1411− Just v -> parseJSON v <?> Key key
1412−{-# INLINE (.:?) #-}
1413−
1414−-- | Like '.:?', but the resulting parser will fail,
1415−-- if the key is present but is 'Null'.
1416−(.:!) :: (FromJSON a) => Object -> Text -> Parser (Maybe a)
1417−obj .:! key = case H.lookup key obj of
1418− Nothing -> pure Nothing
1419− Just v -> Just <$> parseJSON v <?> Key key
1420−{-# INLINE (.:!) #-}
1421−
1422−-- | Helper for use in combination with '.:?' to provide default
1423−-- values for optional JSON object fields.
1424−--
1425−-- This combinator is most useful if the key and value can be absent
1426−-- from an object without affecting its validity and we know a default
1427−-- value to assign in that case. If the key and value are mandatory,
1428−-- use '.:' instead.
1429−--
1430−-- Example usage:
1431−--
1432−-- @ v1 <- o '.:?' \"opt_field_with_dfl\" .!= \"default_val\"
1433−-- v2 <- o '.:' \"mandatory_field\"
1434−-- v3 <- o '.:?' \"opt_field2\"
1435−-- @
1436−(.!=) :: Parser (Maybe a) -> a -> Parser a
1437−pmval .!= val = fromMaybe val <$> pmval
1438−{-# INLINE (.!=) #-}
Data/Aeson/Types/Instances/Tuple.hsdeleted−926
@@ -1,926 +0,0 @@
1−{-# LANGUAGE CPP #-}
2−{-# OPTIONS_GHC -fno-warn-orphans #-}
3−-- |
4−-- Module: Data.Aeson.Types.Instances
5−-- Copyright: (c) 2011-2016 Bryan O'Sullivan
6−-- (c) 2011 MailRank, Inc.
7−-- License: BSD3
8−-- Maintainer: Bryan O'Sullivan <bos@serpentine.com>
9−-- Stability: experimental
10−-- Portability: portable
11−--
12−-- Tuple instances
13−module Data.Aeson.Types.Instances.Tuple () where
14−
15−import Data.Aeson.Encoding.Internal (tuple, (>*<))
16−import Data.Aeson.Types.Class
17−import Data.Aeson.Types.Internal
18−
19−import qualified Data.Vector as V
20−import qualified Data.Vector.Mutable as VM (unsafeNew, unsafeWrite)
21−
22−#if MIN_VERSION_base(4,8,0)
23−#else
24−import Control.Applicative ((<$>), (<*>))
25−#endif
26−
27−parseJSONElemAtIndex :: (Value -> Parser a) -> Int -> V.Vector Value -> Parser a
28−parseJSONElemAtIndex p idx ary = p (V.unsafeIndex ary idx) <?> Index idx
29−
30−-- Local copy of withArray
31−withArray :: String -> (Array -> Parser a) -> Value -> Parser a
32−withArray _ f (Array arr) = f arr
33−withArray expected _ v = typeMismatch expected v
34−{-# INLINE withArray #-}
35−
36−-------------------------------------------------------------------------------
37−-- Generated, see tuple-instances.hs
38−-------------------------------------------------------------------------------
39−
40−instance ToJSON2 ((,) ) where
41− liftToJSON2 toA _ toB _ (a, b) = Array $ V.create $ do
42− mv <- VM.unsafeNew 2
43− VM.unsafeWrite mv 0 (toA a)
44− VM.unsafeWrite mv 1 (toB b)
45− return mv
46− {-# INLINE liftToJSON2 #-}
47−
48− liftToEncoding2 toA _ toB _ (a, b) = tuple $
49− toA a >*<
50− toB b
51− {-# INLINE liftToEncoding2 #-}
52−
53−instance (ToJSON a) => ToJSON1 ((,) a) where
54− liftToJSON = liftToJSON2 toJSON toJSONList
55− {-# INLINE liftToJSON #-}
56− liftToEncoding = liftToEncoding2 toEncoding toEncodingList
57− {-# INLINE liftToEncoding #-}
58−
59−instance (ToJSON a, ToJSON b) => ToJSON (a, b) where
60− toJSON = toJSON2
61− {-# INLINE toJSON #-}
62− toEncoding = toEncoding2
63− {-# INLINE toEncoding #-}
64−
65−instance FromJSON2 ((,) ) where
66− liftParseJSON2 pA _ pB _ = withArray "(a, b)" $ \t ->
67− let n = V.length t
68− in if n == 2
69− then (,)
70− <$> parseJSONElemAtIndex pA 0 t
71− <*> parseJSONElemAtIndex pB 1 t
72− else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 2"
73− {-# INLINE liftParseJSON2 #-}
74−
75−instance (FromJSON a) => FromJSON1 ((,) a) where
76− liftParseJSON = liftParseJSON2 parseJSON parseJSONList
77− {-# INLINE liftParseJSON #-}
78−
79−instance (FromJSON a, FromJSON b) => FromJSON (a, b) where
80− parseJSON = parseJSON2
81− {-# INLINE parseJSON #-}
82−
83−
84−instance (ToJSON a) => ToJSON2 ((,,) a) where
85− liftToJSON2 toB _ toC _ (a, b, c) = Array $ V.create $ do
86− mv <- VM.unsafeNew 3
87− VM.unsafeWrite mv 0 (toJSON a)
88− VM.unsafeWrite mv 1 (toB b)
89− VM.unsafeWrite mv 2 (toC c)
90− return mv
91− {-# INLINE liftToJSON2 #-}
92−
93− liftToEncoding2 toB _ toC _ (a, b, c) = tuple $
94− toEncoding a >*<
95− toB b >*<
96− toC c
97− {-# INLINE liftToEncoding2 #-}
98−
99−instance (ToJSON a, ToJSON b) => ToJSON1 ((,,) a b) where
100− liftToJSON = liftToJSON2 toJSON toJSONList
101− {-# INLINE liftToJSON #-}
102− liftToEncoding = liftToEncoding2 toEncoding toEncodingList
103− {-# INLINE liftToEncoding #-}
104−
105−instance (ToJSON a, ToJSON b, ToJSON c) => ToJSON (a, b, c) where
106− toJSON = toJSON2
107− {-# INLINE toJSON #-}
108− toEncoding = toEncoding2
109− {-# INLINE toEncoding #-}
110−
111−instance (FromJSON a) => FromJSON2 ((,,) a) where
112− liftParseJSON2 pB _ pC _ = withArray "(a, b, c)" $ \t ->
113− let n = V.length t
114− in if n == 3
115− then (,,)
116− <$> parseJSONElemAtIndex parseJSON 0 t
117− <*> parseJSONElemAtIndex pB 1 t
118− <*> parseJSONElemAtIndex pC 2 t
119− else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 3"
120− {-# INLINE liftParseJSON2 #-}
121−
122−instance (FromJSON a, FromJSON b) => FromJSON1 ((,,) a b) where
123− liftParseJSON = liftParseJSON2 parseJSON parseJSONList
124− {-# INLINE liftParseJSON #-}
125−
126−instance (FromJSON a, FromJSON b, FromJSON c) => FromJSON (a, b, c) where
127− parseJSON = parseJSON2
128− {-# INLINE parseJSON #-}
129−
130−
131−instance (ToJSON a, ToJSON b) => ToJSON2 ((,,,) a b) where
132− liftToJSON2 toC _ toD _ (a, b, c, d) = Array $ V.create $ do
133− mv <- VM.unsafeNew 4
134− VM.unsafeWrite mv 0 (toJSON a)
135− VM.unsafeWrite mv 1 (toJSON b)
136− VM.unsafeWrite mv 2 (toC c)
137− VM.unsafeWrite mv 3 (toD d)
138− return mv
139− {-# INLINE liftToJSON2 #-}
140−
141− liftToEncoding2 toC _ toD _ (a, b, c, d) = tuple $
142− toEncoding a >*<
143− toEncoding b >*<
144− toC c >*<
145− toD d
146− {-# INLINE liftToEncoding2 #-}
147−
148−instance (ToJSON a, ToJSON b, ToJSON c) => ToJSON1 ((,,,) a b c) where
149− liftToJSON = liftToJSON2 toJSON toJSONList
150− {-# INLINE liftToJSON #-}
151− liftToEncoding = liftToEncoding2 toEncoding toEncodingList
152− {-# INLINE liftToEncoding #-}
153−
154−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d) => ToJSON (a, b, c, d) where
155− toJSON = toJSON2
156− {-# INLINE toJSON #-}
157− toEncoding = toEncoding2
158− {-# INLINE toEncoding #-}
159−
160−instance (FromJSON a, FromJSON b) => FromJSON2 ((,,,) a b) where
161− liftParseJSON2 pC _ pD _ = withArray "(a, b, c, d)" $ \t ->
162− let n = V.length t
163− in if n == 4
164− then (,,,)
165− <$> parseJSONElemAtIndex parseJSON 0 t
166− <*> parseJSONElemAtIndex parseJSON 1 t
167− <*> parseJSONElemAtIndex pC 2 t
168− <*> parseJSONElemAtIndex pD 3 t
169− else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 4"
170− {-# INLINE liftParseJSON2 #-}
171−
172−instance (FromJSON a, FromJSON b, FromJSON c) => FromJSON1 ((,,,) a b c) where
173− liftParseJSON = liftParseJSON2 parseJSON parseJSONList
174− {-# INLINE liftParseJSON #-}
175−
176−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d) => FromJSON (a, b, c, d) where
177− parseJSON = parseJSON2
178− {-# INLINE parseJSON #-}
179−
180−
181−instance (ToJSON a, ToJSON b, ToJSON c) => ToJSON2 ((,,,,) a b c) where
182− liftToJSON2 toD _ toE _ (a, b, c, d, e) = Array $ V.create $ do
183− mv <- VM.unsafeNew 5
184− VM.unsafeWrite mv 0 (toJSON a)
185− VM.unsafeWrite mv 1 (toJSON b)
186− VM.unsafeWrite mv 2 (toJSON c)
187− VM.unsafeWrite mv 3 (toD d)
188− VM.unsafeWrite mv 4 (toE e)
189− return mv
190− {-# INLINE liftToJSON2 #-}
191−
192− liftToEncoding2 toD _ toE _ (a, b, c, d, e) = tuple $
193− toEncoding a >*<
194− toEncoding b >*<
195− toEncoding c >*<
196− toD d >*<
197− toE e
198− {-# INLINE liftToEncoding2 #-}
199−
200−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d) => ToJSON1 ((,,,,) a b c d) where
201− liftToJSON = liftToJSON2 toJSON toJSONList
202− {-# INLINE liftToJSON #-}
203− liftToEncoding = liftToEncoding2 toEncoding toEncodingList
204− {-# INLINE liftToEncoding #-}
205−
206−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e) => ToJSON (a, b, c, d, e) where
207− toJSON = toJSON2
208− {-# INLINE toJSON #-}
209− toEncoding = toEncoding2
210− {-# INLINE toEncoding #-}
211−
212−instance (FromJSON a, FromJSON b, FromJSON c) => FromJSON2 ((,,,,) a b c) where
213− liftParseJSON2 pD _ pE _ = withArray "(a, b, c, d, e)" $ \t ->
214− let n = V.length t
215− in if n == 5
216− then (,,,,)
217− <$> parseJSONElemAtIndex parseJSON 0 t
218− <*> parseJSONElemAtIndex parseJSON 1 t
219− <*> parseJSONElemAtIndex parseJSON 2 t
220− <*> parseJSONElemAtIndex pD 3 t
221− <*> parseJSONElemAtIndex pE 4 t
222− else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 5"
223− {-# INLINE liftParseJSON2 #-}
224−
225−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d) => FromJSON1 ((,,,,) a b c d) where
226− liftParseJSON = liftParseJSON2 parseJSON parseJSONList
227− {-# INLINE liftParseJSON #-}
228−
229−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e) => FromJSON (a, b, c, d, e) where
230− parseJSON = parseJSON2
231− {-# INLINE parseJSON #-}
232−
233−
234−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d) => ToJSON2 ((,,,,,) a b c d) where
235− liftToJSON2 toE _ toF _ (a, b, c, d, e, f) = Array $ V.create $ do
236− mv <- VM.unsafeNew 6
237− VM.unsafeWrite mv 0 (toJSON a)
238− VM.unsafeWrite mv 1 (toJSON b)
239− VM.unsafeWrite mv 2 (toJSON c)
240− VM.unsafeWrite mv 3 (toJSON d)
241− VM.unsafeWrite mv 4 (toE e)
242− VM.unsafeWrite mv 5 (toF f)
243− return mv
244− {-# INLINE liftToJSON2 #-}
245−
246− liftToEncoding2 toE _ toF _ (a, b, c, d, e, f) = tuple $
247− toEncoding a >*<
248− toEncoding b >*<
249− toEncoding c >*<
250− toEncoding d >*<
251− toE e >*<
252− toF f
253− {-# INLINE liftToEncoding2 #-}
254−
255−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e) => ToJSON1 ((,,,,,) a b c d e) where
256− liftToJSON = liftToJSON2 toJSON toJSONList
257− {-# INLINE liftToJSON #-}
258− liftToEncoding = liftToEncoding2 toEncoding toEncodingList
259− {-# INLINE liftToEncoding #-}
260−
261−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f) => ToJSON (a, b, c, d, e, f) where
262− toJSON = toJSON2
263− {-# INLINE toJSON #-}
264− toEncoding = toEncoding2
265− {-# INLINE toEncoding #-}
266−
267−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d) => FromJSON2 ((,,,,,) a b c d) where
268− liftParseJSON2 pE _ pF _ = withArray "(a, b, c, d, e, f)" $ \t ->
269− let n = V.length t
270− in if n == 6
271− then (,,,,,)
272− <$> parseJSONElemAtIndex parseJSON 0 t
273− <*> parseJSONElemAtIndex parseJSON 1 t
274− <*> parseJSONElemAtIndex parseJSON 2 t
275− <*> parseJSONElemAtIndex parseJSON 3 t
276− <*> parseJSONElemAtIndex pE 4 t
277− <*> parseJSONElemAtIndex pF 5 t
278− else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 6"
279− {-# INLINE liftParseJSON2 #-}
280−
281−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e) => FromJSON1 ((,,,,,) a b c d e) where
282− liftParseJSON = liftParseJSON2 parseJSON parseJSONList
283− {-# INLINE liftParseJSON #-}
284−
285−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f) => FromJSON (a, b, c, d, e, f) where
286− parseJSON = parseJSON2
287− {-# INLINE parseJSON #-}
288−
289−
290−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e) => ToJSON2 ((,,,,,,) a b c d e) where
291− liftToJSON2 toF _ toG _ (a, b, c, d, e, f, g) = Array $ V.create $ do
292− mv <- VM.unsafeNew 7
293− VM.unsafeWrite mv 0 (toJSON a)
294− VM.unsafeWrite mv 1 (toJSON b)
295− VM.unsafeWrite mv 2 (toJSON c)
296− VM.unsafeWrite mv 3 (toJSON d)
297− VM.unsafeWrite mv 4 (toJSON e)
298− VM.unsafeWrite mv 5 (toF f)
299− VM.unsafeWrite mv 6 (toG g)
300− return mv
301− {-# INLINE liftToJSON2 #-}
302−
303− liftToEncoding2 toF _ toG _ (a, b, c, d, e, f, g) = tuple $
304− toEncoding a >*<
305− toEncoding b >*<
306− toEncoding c >*<
307− toEncoding d >*<
308− toEncoding e >*<
309− toF f >*<
310− toG g
311− {-# INLINE liftToEncoding2 #-}
312−
313−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f) => ToJSON1 ((,,,,,,) a b c d e f) where
314− liftToJSON = liftToJSON2 toJSON toJSONList
315− {-# INLINE liftToJSON #-}
316− liftToEncoding = liftToEncoding2 toEncoding toEncodingList
317− {-# INLINE liftToEncoding #-}
318−
319−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g) => ToJSON (a, b, c, d, e, f, g) where
320− toJSON = toJSON2
321− {-# INLINE toJSON #-}
322− toEncoding = toEncoding2
323− {-# INLINE toEncoding #-}
324−
325−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e) => FromJSON2 ((,,,,,,) a b c d e) where
326− liftParseJSON2 pF _ pG _ = withArray "(a, b, c, d, e, f, g)" $ \t ->
327− let n = V.length t
328− in if n == 7
329− then (,,,,,,)
330− <$> parseJSONElemAtIndex parseJSON 0 t
331− <*> parseJSONElemAtIndex parseJSON 1 t
332− <*> parseJSONElemAtIndex parseJSON 2 t
333− <*> parseJSONElemAtIndex parseJSON 3 t
334− <*> parseJSONElemAtIndex parseJSON 4 t
335− <*> parseJSONElemAtIndex pF 5 t
336− <*> parseJSONElemAtIndex pG 6 t
337− else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 7"
338− {-# INLINE liftParseJSON2 #-}
339−
340−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f) => FromJSON1 ((,,,,,,) a b c d e f) where
341− liftParseJSON = liftParseJSON2 parseJSON parseJSONList
342− {-# INLINE liftParseJSON #-}
343−
344−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g) => FromJSON (a, b, c, d, e, f, g) where
345− parseJSON = parseJSON2
346− {-# INLINE parseJSON #-}
347−
348−
349−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f) => ToJSON2 ((,,,,,,,) a b c d e f) where
350− liftToJSON2 toG _ toH _ (a, b, c, d, e, f, g, h) = Array $ V.create $ do
351− mv <- VM.unsafeNew 8
352− VM.unsafeWrite mv 0 (toJSON a)
353− VM.unsafeWrite mv 1 (toJSON b)
354− VM.unsafeWrite mv 2 (toJSON c)
355− VM.unsafeWrite mv 3 (toJSON d)
356− VM.unsafeWrite mv 4 (toJSON e)
357− VM.unsafeWrite mv 5 (toJSON f)
358− VM.unsafeWrite mv 6 (toG g)
359− VM.unsafeWrite mv 7 (toH h)
360− return mv
361− {-# INLINE liftToJSON2 #-}
362−
363− liftToEncoding2 toG _ toH _ (a, b, c, d, e, f, g, h) = tuple $
364− toEncoding a >*<
365− toEncoding b >*<
366− toEncoding c >*<
367− toEncoding d >*<
368− toEncoding e >*<
369− toEncoding f >*<
370− toG g >*<
371− toH h
372− {-# INLINE liftToEncoding2 #-}
373−
374−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g) => ToJSON1 ((,,,,,,,) a b c d e f g) where
375− liftToJSON = liftToJSON2 toJSON toJSONList
376− {-# INLINE liftToJSON #-}
377− liftToEncoding = liftToEncoding2 toEncoding toEncodingList
378− {-# INLINE liftToEncoding #-}
379−
380−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h) => ToJSON (a, b, c, d, e, f, g, h) where
381− toJSON = toJSON2
382− {-# INLINE toJSON #-}
383− toEncoding = toEncoding2
384− {-# INLINE toEncoding #-}
385−
386−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f) => FromJSON2 ((,,,,,,,) a b c d e f) where
387− liftParseJSON2 pG _ pH _ = withArray "(a, b, c, d, e, f, g, h)" $ \t ->
388− let n = V.length t
389− in if n == 8
390− then (,,,,,,,)
391− <$> parseJSONElemAtIndex parseJSON 0 t
392− <*> parseJSONElemAtIndex parseJSON 1 t
393− <*> parseJSONElemAtIndex parseJSON 2 t
394− <*> parseJSONElemAtIndex parseJSON 3 t
395− <*> parseJSONElemAtIndex parseJSON 4 t
396− <*> parseJSONElemAtIndex parseJSON 5 t
397− <*> parseJSONElemAtIndex pG 6 t
398− <*> parseJSONElemAtIndex pH 7 t
399− else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 8"
400− {-# INLINE liftParseJSON2 #-}
401−
402−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g) => FromJSON1 ((,,,,,,,) a b c d e f g) where
403− liftParseJSON = liftParseJSON2 parseJSON parseJSONList
404− {-# INLINE liftParseJSON #-}
405−
406−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h) => FromJSON (a, b, c, d, e, f, g, h) where
407− parseJSON = parseJSON2
408− {-# INLINE parseJSON #-}
409−
410−
411−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g) => ToJSON2 ((,,,,,,,,) a b c d e f g) where
412− liftToJSON2 toH _ toI _ (a, b, c, d, e, f, g, h, i) = Array $ V.create $ do
413− mv <- VM.unsafeNew 9
414− VM.unsafeWrite mv 0 (toJSON a)
415− VM.unsafeWrite mv 1 (toJSON b)
416− VM.unsafeWrite mv 2 (toJSON c)
417− VM.unsafeWrite mv 3 (toJSON d)
418− VM.unsafeWrite mv 4 (toJSON e)
419− VM.unsafeWrite mv 5 (toJSON f)
420− VM.unsafeWrite mv 6 (toJSON g)
421− VM.unsafeWrite mv 7 (toH h)
422− VM.unsafeWrite mv 8 (toI i)
423− return mv
424− {-# INLINE liftToJSON2 #-}
425−
426− liftToEncoding2 toH _ toI _ (a, b, c, d, e, f, g, h, i) = tuple $
427− toEncoding a >*<
428− toEncoding b >*<
429− toEncoding c >*<
430− toEncoding d >*<
431− toEncoding e >*<
432− toEncoding f >*<
433− toEncoding g >*<
434− toH h >*<
435− toI i
436− {-# INLINE liftToEncoding2 #-}
437−
438−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h) => ToJSON1 ((,,,,,,,,) a b c d e f g h) where
439− liftToJSON = liftToJSON2 toJSON toJSONList
440− {-# INLINE liftToJSON #-}
441− liftToEncoding = liftToEncoding2 toEncoding toEncodingList
442− {-# INLINE liftToEncoding #-}
443−
444−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i) => ToJSON (a, b, c, d, e, f, g, h, i) where
445− toJSON = toJSON2
446− {-# INLINE toJSON #-}
447− toEncoding = toEncoding2
448− {-# INLINE toEncoding #-}
449−
450−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g) => FromJSON2 ((,,,,,,,,) a b c d e f g) where
451− liftParseJSON2 pH _ pI _ = withArray "(a, b, c, d, e, f, g, h, i)" $ \t ->
452− let n = V.length t
453− in if n == 9
454− then (,,,,,,,,)
455− <$> parseJSONElemAtIndex parseJSON 0 t
456− <*> parseJSONElemAtIndex parseJSON 1 t
457− <*> parseJSONElemAtIndex parseJSON 2 t
458− <*> parseJSONElemAtIndex parseJSON 3 t
459− <*> parseJSONElemAtIndex parseJSON 4 t
460− <*> parseJSONElemAtIndex parseJSON 5 t
461− <*> parseJSONElemAtIndex parseJSON 6 t
462− <*> parseJSONElemAtIndex pH 7 t
463− <*> parseJSONElemAtIndex pI 8 t
464− else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 9"
465− {-# INLINE liftParseJSON2 #-}
466−
467−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h) => FromJSON1 ((,,,,,,,,) a b c d e f g h) where
468− liftParseJSON = liftParseJSON2 parseJSON parseJSONList
469− {-# INLINE liftParseJSON #-}
470−
471−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i) => FromJSON (a, b, c, d, e, f, g, h, i) where
472− parseJSON = parseJSON2
473− {-# INLINE parseJSON #-}
474−
475−
476−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h) => ToJSON2 ((,,,,,,,,,) a b c d e f g h) where
477− liftToJSON2 toI _ toJ _ (a, b, c, d, e, f, g, h, i, j) = Array $ V.create $ do
478− mv <- VM.unsafeNew 10
479− VM.unsafeWrite mv 0 (toJSON a)
480− VM.unsafeWrite mv 1 (toJSON b)
481− VM.unsafeWrite mv 2 (toJSON c)
482− VM.unsafeWrite mv 3 (toJSON d)
483− VM.unsafeWrite mv 4 (toJSON e)
484− VM.unsafeWrite mv 5 (toJSON f)
485− VM.unsafeWrite mv 6 (toJSON g)
486− VM.unsafeWrite mv 7 (toJSON h)
487− VM.unsafeWrite mv 8 (toI i)
488− VM.unsafeWrite mv 9 (toJ j)
489− return mv
490− {-# INLINE liftToJSON2 #-}
491−
492− liftToEncoding2 toI _ toJ _ (a, b, c, d, e, f, g, h, i, j) = tuple $
493− toEncoding a >*<
494− toEncoding b >*<
495− toEncoding c >*<
496− toEncoding d >*<
497− toEncoding e >*<
498− toEncoding f >*<
499− toEncoding g >*<
500− toEncoding h >*<
501− toI i >*<
502− toJ j
503− {-# INLINE liftToEncoding2 #-}
504−
505−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i) => ToJSON1 ((,,,,,,,,,) a b c d e f g h i) where
506− liftToJSON = liftToJSON2 toJSON toJSONList
507− {-# INLINE liftToJSON #-}
508− liftToEncoding = liftToEncoding2 toEncoding toEncodingList
509− {-# INLINE liftToEncoding #-}
510−
511−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j) => ToJSON (a, b, c, d, e, f, g, h, i, j) where
512− toJSON = toJSON2
513− {-# INLINE toJSON #-}
514− toEncoding = toEncoding2
515− {-# INLINE toEncoding #-}
516−
517−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h) => FromJSON2 ((,,,,,,,,,) a b c d e f g h) where
518− liftParseJSON2 pI _ pJ _ = withArray "(a, b, c, d, e, f, g, h, i, j)" $ \t ->
519− let n = V.length t
520− in if n == 10
521− then (,,,,,,,,,)
522− <$> parseJSONElemAtIndex parseJSON 0 t
523− <*> parseJSONElemAtIndex parseJSON 1 t
524− <*> parseJSONElemAtIndex parseJSON 2 t
525− <*> parseJSONElemAtIndex parseJSON 3 t
526− <*> parseJSONElemAtIndex parseJSON 4 t
527− <*> parseJSONElemAtIndex parseJSON 5 t
528− <*> parseJSONElemAtIndex parseJSON 6 t
529− <*> parseJSONElemAtIndex parseJSON 7 t
530− <*> parseJSONElemAtIndex pI 8 t
531− <*> parseJSONElemAtIndex pJ 9 t
532− else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 10"
533− {-# INLINE liftParseJSON2 #-}
534−
535−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i) => FromJSON1 ((,,,,,,,,,) a b c d e f g h i) where
536− liftParseJSON = liftParseJSON2 parseJSON parseJSONList
537− {-# INLINE liftParseJSON #-}
538−
539−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j) => FromJSON (a, b, c, d, e, f, g, h, i, j) where
540− parseJSON = parseJSON2
541− {-# INLINE parseJSON #-}
542−
543−
544−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i) => ToJSON2 ((,,,,,,,,,,) a b c d e f g h i) where
545− liftToJSON2 toJ _ toK _ (a, b, c, d, e, f, g, h, i, j, k) = Array $ V.create $ do
546− mv <- VM.unsafeNew 11
547− VM.unsafeWrite mv 0 (toJSON a)
548− VM.unsafeWrite mv 1 (toJSON b)
549− VM.unsafeWrite mv 2 (toJSON c)
550− VM.unsafeWrite mv 3 (toJSON d)
551− VM.unsafeWrite mv 4 (toJSON e)
552− VM.unsafeWrite mv 5 (toJSON f)
553− VM.unsafeWrite mv 6 (toJSON g)
554− VM.unsafeWrite mv 7 (toJSON h)
555− VM.unsafeWrite mv 8 (toJSON i)
556− VM.unsafeWrite mv 9 (toJ j)
557− VM.unsafeWrite mv 10 (toK k)
558− return mv
559− {-# INLINE liftToJSON2 #-}
560−
561− liftToEncoding2 toJ _ toK _ (a, b, c, d, e, f, g, h, i, j, k) = tuple $
562− toEncoding a >*<
563− toEncoding b >*<
564− toEncoding c >*<
565− toEncoding d >*<
566− toEncoding e >*<
567− toEncoding f >*<
568− toEncoding g >*<
569− toEncoding h >*<
570− toEncoding i >*<
571− toJ j >*<
572− toK k
573− {-# INLINE liftToEncoding2 #-}
574−
575−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j) => ToJSON1 ((,,,,,,,,,,) a b c d e f g h i j) where
576− liftToJSON = liftToJSON2 toJSON toJSONList
577− {-# INLINE liftToJSON #-}
578− liftToEncoding = liftToEncoding2 toEncoding toEncodingList
579− {-# INLINE liftToEncoding #-}
580−
581−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k) => ToJSON (a, b, c, d, e, f, g, h, i, j, k) where
582− toJSON = toJSON2
583− {-# INLINE toJSON #-}
584− toEncoding = toEncoding2
585− {-# INLINE toEncoding #-}
586−
587−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i) => FromJSON2 ((,,,,,,,,,,) a b c d e f g h i) where
588− liftParseJSON2 pJ _ pK _ = withArray "(a, b, c, d, e, f, g, h, i, j, k)" $ \t ->
589− let n = V.length t
590− in if n == 11
591− then (,,,,,,,,,,)
592− <$> parseJSONElemAtIndex parseJSON 0 t
593− <*> parseJSONElemAtIndex parseJSON 1 t
594− <*> parseJSONElemAtIndex parseJSON 2 t
595− <*> parseJSONElemAtIndex parseJSON 3 t
596− <*> parseJSONElemAtIndex parseJSON 4 t
597− <*> parseJSONElemAtIndex parseJSON 5 t
598− <*> parseJSONElemAtIndex parseJSON 6 t
599− <*> parseJSONElemAtIndex parseJSON 7 t
600− <*> parseJSONElemAtIndex parseJSON 8 t
601− <*> parseJSONElemAtIndex pJ 9 t
602− <*> parseJSONElemAtIndex pK 10 t
603− else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 11"
604− {-# INLINE liftParseJSON2 #-}
605−
606−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j) => FromJSON1 ((,,,,,,,,,,) a b c d e f g h i j) where
607− liftParseJSON = liftParseJSON2 parseJSON parseJSONList
608− {-# INLINE liftParseJSON #-}
609−
610−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k) => FromJSON (a, b, c, d, e, f, g, h, i, j, k) where
611− parseJSON = parseJSON2
612− {-# INLINE parseJSON #-}
613−
614−
615−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j) => ToJSON2 ((,,,,,,,,,,,) a b c d e f g h i j) where
616− liftToJSON2 toK _ toL _ (a, b, c, d, e, f, g, h, i, j, k, l) = Array $ V.create $ do
617− mv <- VM.unsafeNew 12
618− VM.unsafeWrite mv 0 (toJSON a)
619− VM.unsafeWrite mv 1 (toJSON b)
620− VM.unsafeWrite mv 2 (toJSON c)
621− VM.unsafeWrite mv 3 (toJSON d)
622− VM.unsafeWrite mv 4 (toJSON e)
623− VM.unsafeWrite mv 5 (toJSON f)
624− VM.unsafeWrite mv 6 (toJSON g)
625− VM.unsafeWrite mv 7 (toJSON h)
626− VM.unsafeWrite mv 8 (toJSON i)
627− VM.unsafeWrite mv 9 (toJSON j)
628− VM.unsafeWrite mv 10 (toK k)
629− VM.unsafeWrite mv 11 (toL l)
630− return mv
631− {-# INLINE liftToJSON2 #-}
632−
633− liftToEncoding2 toK _ toL _ (a, b, c, d, e, f, g, h, i, j, k, l) = tuple $
634− toEncoding a >*<
635− toEncoding b >*<
636− toEncoding c >*<
637− toEncoding d >*<
638− toEncoding e >*<
639− toEncoding f >*<
640− toEncoding g >*<
641− toEncoding h >*<
642− toEncoding i >*<
643− toEncoding j >*<
644− toK k >*<
645− toL l
646− {-# INLINE liftToEncoding2 #-}
647−
648−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k) => ToJSON1 ((,,,,,,,,,,,) a b c d e f g h i j k) where
649− liftToJSON = liftToJSON2 toJSON toJSONList
650− {-# INLINE liftToJSON #-}
651− liftToEncoding = liftToEncoding2 toEncoding toEncodingList
652− {-# INLINE liftToEncoding #-}
653−
654−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k, ToJSON l) => ToJSON (a, b, c, d, e, f, g, h, i, j, k, l) where
655− toJSON = toJSON2
656− {-# INLINE toJSON #-}
657− toEncoding = toEncoding2
658− {-# INLINE toEncoding #-}
659−
660−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j) => FromJSON2 ((,,,,,,,,,,,) a b c d e f g h i j) where
661− liftParseJSON2 pK _ pL _ = withArray "(a, b, c, d, e, f, g, h, i, j, k, l)" $ \t ->
662− let n = V.length t
663− in if n == 12
664− then (,,,,,,,,,,,)
665− <$> parseJSONElemAtIndex parseJSON 0 t
666− <*> parseJSONElemAtIndex parseJSON 1 t
667− <*> parseJSONElemAtIndex parseJSON 2 t
668− <*> parseJSONElemAtIndex parseJSON 3 t
669− <*> parseJSONElemAtIndex parseJSON 4 t
670− <*> parseJSONElemAtIndex parseJSON 5 t
671− <*> parseJSONElemAtIndex parseJSON 6 t
672− <*> parseJSONElemAtIndex parseJSON 7 t
673− <*> parseJSONElemAtIndex parseJSON 8 t
674− <*> parseJSONElemAtIndex parseJSON 9 t
675− <*> parseJSONElemAtIndex pK 10 t
676− <*> parseJSONElemAtIndex pL 11 t
677− else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 12"
678− {-# INLINE liftParseJSON2 #-}
679−
680−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k) => FromJSON1 ((,,,,,,,,,,,) a b c d e f g h i j k) where
681− liftParseJSON = liftParseJSON2 parseJSON parseJSONList
682− {-# INLINE liftParseJSON #-}
683−
684−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k, FromJSON l) => FromJSON (a, b, c, d, e, f, g, h, i, j, k, l) where
685− parseJSON = parseJSON2
686− {-# INLINE parseJSON #-}
687−
688−
689−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k) => ToJSON2 ((,,,,,,,,,,,,) a b c d e f g h i j k) where
690− liftToJSON2 toL _ toM _ (a, b, c, d, e, f, g, h, i, j, k, l, m) = Array $ V.create $ do
691− mv <- VM.unsafeNew 13
692− VM.unsafeWrite mv 0 (toJSON a)
693− VM.unsafeWrite mv 1 (toJSON b)
694− VM.unsafeWrite mv 2 (toJSON c)
695− VM.unsafeWrite mv 3 (toJSON d)
696− VM.unsafeWrite mv 4 (toJSON e)
697− VM.unsafeWrite mv 5 (toJSON f)
698− VM.unsafeWrite mv 6 (toJSON g)
699− VM.unsafeWrite mv 7 (toJSON h)
700− VM.unsafeWrite mv 8 (toJSON i)
701− VM.unsafeWrite mv 9 (toJSON j)
702− VM.unsafeWrite mv 10 (toJSON k)
703− VM.unsafeWrite mv 11 (toL l)
704− VM.unsafeWrite mv 12 (toM m)
705− return mv
706− {-# INLINE liftToJSON2 #-}
707−
708− liftToEncoding2 toL _ toM _ (a, b, c, d, e, f, g, h, i, j, k, l, m) = tuple $
709− toEncoding a >*<
710− toEncoding b >*<
711− toEncoding c >*<
712− toEncoding d >*<
713− toEncoding e >*<
714− toEncoding f >*<
715− toEncoding g >*<
716− toEncoding h >*<
717− toEncoding i >*<
718− toEncoding j >*<
719− toEncoding k >*<
720− toL l >*<
721− toM m
722− {-# INLINE liftToEncoding2 #-}
723−
724−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k, ToJSON l) => ToJSON1 ((,,,,,,,,,,,,) a b c d e f g h i j k l) where
725− liftToJSON = liftToJSON2 toJSON toJSONList
726− {-# INLINE liftToJSON #-}
727− liftToEncoding = liftToEncoding2 toEncoding toEncodingList
728− {-# INLINE liftToEncoding #-}
729−
730−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k, ToJSON l, ToJSON m) => ToJSON (a, b, c, d, e, f, g, h, i, j, k, l, m) where
731− toJSON = toJSON2
732− {-# INLINE toJSON #-}
733− toEncoding = toEncoding2
734− {-# INLINE toEncoding #-}
735−
736−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k) => FromJSON2 ((,,,,,,,,,,,,) a b c d e f g h i j k) where
737− liftParseJSON2 pL _ pM _ = withArray "(a, b, c, d, e, f, g, h, i, j, k, l, m)" $ \t ->
738− let n = V.length t
739− in if n == 13
740− then (,,,,,,,,,,,,)
741− <$> parseJSONElemAtIndex parseJSON 0 t
742− <*> parseJSONElemAtIndex parseJSON 1 t
743− <*> parseJSONElemAtIndex parseJSON 2 t
744− <*> parseJSONElemAtIndex parseJSON 3 t
745− <*> parseJSONElemAtIndex parseJSON 4 t
746− <*> parseJSONElemAtIndex parseJSON 5 t
747− <*> parseJSONElemAtIndex parseJSON 6 t
748− <*> parseJSONElemAtIndex parseJSON 7 t
749− <*> parseJSONElemAtIndex parseJSON 8 t
750− <*> parseJSONElemAtIndex parseJSON 9 t
751− <*> parseJSONElemAtIndex parseJSON 10 t
752− <*> parseJSONElemAtIndex pL 11 t
753− <*> parseJSONElemAtIndex pM 12 t
754− else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 13"
755− {-# INLINE liftParseJSON2 #-}
756−
757−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k, FromJSON l) => FromJSON1 ((,,,,,,,,,,,,) a b c d e f g h i j k l) where
758− liftParseJSON = liftParseJSON2 parseJSON parseJSONList
759− {-# INLINE liftParseJSON #-}
760−
761−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k, FromJSON l, FromJSON m) => FromJSON (a, b, c, d, e, f, g, h, i, j, k, l, m) where
762− parseJSON = parseJSON2
763− {-# INLINE parseJSON #-}
764−
765−
766−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k, ToJSON l) => ToJSON2 ((,,,,,,,,,,,,,) a b c d e f g h i j k l) where
767− liftToJSON2 toM _ toN _ (a, b, c, d, e, f, g, h, i, j, k, l, m, n) = Array $ V.create $ do
768− mv <- VM.unsafeNew 14
769− VM.unsafeWrite mv 0 (toJSON a)
770− VM.unsafeWrite mv 1 (toJSON b)
771− VM.unsafeWrite mv 2 (toJSON c)
772− VM.unsafeWrite mv 3 (toJSON d)
773− VM.unsafeWrite mv 4 (toJSON e)
774− VM.unsafeWrite mv 5 (toJSON f)
775− VM.unsafeWrite mv 6 (toJSON g)
776− VM.unsafeWrite mv 7 (toJSON h)
777− VM.unsafeWrite mv 8 (toJSON i)
778− VM.unsafeWrite mv 9 (toJSON j)
779− VM.unsafeWrite mv 10 (toJSON k)
780− VM.unsafeWrite mv 11 (toJSON l)
781− VM.unsafeWrite mv 12 (toM m)
782− VM.unsafeWrite mv 13 (toN n)
783− return mv
784− {-# INLINE liftToJSON2 #-}
785−
786− liftToEncoding2 toM _ toN _ (a, b, c, d, e, f, g, h, i, j, k, l, m, n) = tuple $
787− toEncoding a >*<
788− toEncoding b >*<
789− toEncoding c >*<
790− toEncoding d >*<
791− toEncoding e >*<
792− toEncoding f >*<
793− toEncoding g >*<
794− toEncoding h >*<
795− toEncoding i >*<
796− toEncoding j >*<
797− toEncoding k >*<
798− toEncoding l >*<
799− toM m >*<
800− toN n
801− {-# INLINE liftToEncoding2 #-}
802−
803−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k, ToJSON l, ToJSON m) => ToJSON1 ((,,,,,,,,,,,,,) a b c d e f g h i j k l m) where
804− liftToJSON = liftToJSON2 toJSON toJSONList
805− {-# INLINE liftToJSON #-}
806− liftToEncoding = liftToEncoding2 toEncoding toEncodingList
807− {-# INLINE liftToEncoding #-}
808−
809−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k, ToJSON l, ToJSON m, ToJSON n) => ToJSON (a, b, c, d, e, f, g, h, i, j, k, l, m, n) where
810− toJSON = toJSON2
811− {-# INLINE toJSON #-}
812− toEncoding = toEncoding2
813− {-# INLINE toEncoding #-}
814−
815−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k, FromJSON l) => FromJSON2 ((,,,,,,,,,,,,,) a b c d e f g h i j k l) where
816− liftParseJSON2 pM _ pN _ = withArray "(a, b, c, d, e, f, g, h, i, j, k, l, m, n)" $ \t ->
817− let n = V.length t
818− in if n == 14
819− then (,,,,,,,,,,,,,)
820− <$> parseJSONElemAtIndex parseJSON 0 t
821− <*> parseJSONElemAtIndex parseJSON 1 t
822− <*> parseJSONElemAtIndex parseJSON 2 t
823− <*> parseJSONElemAtIndex parseJSON 3 t
824− <*> parseJSONElemAtIndex parseJSON 4 t
825− <*> parseJSONElemAtIndex parseJSON 5 t
826− <*> parseJSONElemAtIndex parseJSON 6 t
827− <*> parseJSONElemAtIndex parseJSON 7 t
828− <*> parseJSONElemAtIndex parseJSON 8 t
829− <*> parseJSONElemAtIndex parseJSON 9 t
830− <*> parseJSONElemAtIndex parseJSON 10 t
831− <*> parseJSONElemAtIndex parseJSON 11 t
832− <*> parseJSONElemAtIndex pM 12 t
833− <*> parseJSONElemAtIndex pN 13 t
834− else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 14"
835− {-# INLINE liftParseJSON2 #-}
836−
837−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k, FromJSON l, FromJSON m) => FromJSON1 ((,,,,,,,,,,,,,) a b c d e f g h i j k l m) where
838− liftParseJSON = liftParseJSON2 parseJSON parseJSONList
839− {-# INLINE liftParseJSON #-}
840−
841−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k, FromJSON l, FromJSON m, FromJSON n) => FromJSON (a, b, c, d, e, f, g, h, i, j, k, l, m, n) where
842− parseJSON = parseJSON2
843− {-# INLINE parseJSON #-}
844−
845−
846−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k, ToJSON l, ToJSON m) => ToJSON2 ((,,,,,,,,,,,,,,) a b c d e f g h i j k l m) where
847− liftToJSON2 toN _ toO _ (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) = Array $ V.create $ do
848− mv <- VM.unsafeNew 15
849− VM.unsafeWrite mv 0 (toJSON a)
850− VM.unsafeWrite mv 1 (toJSON b)
851− VM.unsafeWrite mv 2 (toJSON c)
852− VM.unsafeWrite mv 3 (toJSON d)
853− VM.unsafeWrite mv 4 (toJSON e)
854− VM.unsafeWrite mv 5 (toJSON f)
855− VM.unsafeWrite mv 6 (toJSON g)
856− VM.unsafeWrite mv 7 (toJSON h)
857− VM.unsafeWrite mv 8 (toJSON i)
858− VM.unsafeWrite mv 9 (toJSON j)
859− VM.unsafeWrite mv 10 (toJSON k)
860− VM.unsafeWrite mv 11 (toJSON l)
861− VM.unsafeWrite mv 12 (toJSON m)
862− VM.unsafeWrite mv 13 (toN n)
863− VM.unsafeWrite mv 14 (toO o)
864− return mv
865− {-# INLINE liftToJSON2 #-}
866−
867− liftToEncoding2 toN _ toO _ (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) = tuple $
868− toEncoding a >*<
869− toEncoding b >*<
870− toEncoding c >*<
871− toEncoding d >*<
872− toEncoding e >*<
873− toEncoding f >*<
874− toEncoding g >*<
875− toEncoding h >*<
876− toEncoding i >*<
877− toEncoding j >*<
878− toEncoding k >*<
879− toEncoding l >*<
880− toEncoding m >*<
881− toN n >*<
882− toO o
883− {-# INLINE liftToEncoding2 #-}
884−
885−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k, ToJSON l, ToJSON m, ToJSON n) => ToJSON1 ((,,,,,,,,,,,,,,) a b c d e f g h i j k l m n) where
886− liftToJSON = liftToJSON2 toJSON toJSONList
887− {-# INLINE liftToJSON #-}
888− liftToEncoding = liftToEncoding2 toEncoding toEncodingList
889− {-# INLINE liftToEncoding #-}
890−
891−instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k, ToJSON l, ToJSON m, ToJSON n, ToJSON o) => ToJSON (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) where
892− toJSON = toJSON2
893− {-# INLINE toJSON #-}
894− toEncoding = toEncoding2
895− {-# INLINE toEncoding #-}
896−
897−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k, FromJSON l, FromJSON m) => FromJSON2 ((,,,,,,,,,,,,,,) a b c d e f g h i j k l m) where
898− liftParseJSON2 pN _ pO _ = withArray "(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)" $ \t ->
899− let n = V.length t
900− in if n == 15
901− then (,,,,,,,,,,,,,,)
902− <$> parseJSONElemAtIndex parseJSON 0 t
903− <*> parseJSONElemAtIndex parseJSON 1 t
904− <*> parseJSONElemAtIndex parseJSON 2 t
905− <*> parseJSONElemAtIndex parseJSON 3 t
906− <*> parseJSONElemAtIndex parseJSON 4 t
907− <*> parseJSONElemAtIndex parseJSON 5 t
908− <*> parseJSONElemAtIndex parseJSON 6 t
909− <*> parseJSONElemAtIndex parseJSON 7 t
910− <*> parseJSONElemAtIndex parseJSON 8 t
911− <*> parseJSONElemAtIndex parseJSON 9 t
912− <*> parseJSONElemAtIndex parseJSON 10 t
913− <*> parseJSONElemAtIndex parseJSON 11 t
914− <*> parseJSONElemAtIndex parseJSON 12 t
915− <*> parseJSONElemAtIndex pN 13 t
916− <*> parseJSONElemAtIndex pO 14 t
917− else fail $ "cannot unpack array of length " ++ show n ++ " into a tuple of length 15"
918− {-# INLINE liftParseJSON2 #-}
919−
920−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k, FromJSON l, FromJSON m, FromJSON n) => FromJSON1 ((,,,,,,,,,,,,,,) a b c d e f g h i j k l m n) where
921− liftParseJSON = liftParseJSON2 parseJSON parseJSONList
922− {-# INLINE liftParseJSON #-}
923−
924−instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g, FromJSON h, FromJSON i, FromJSON j, FromJSON k, FromJSON l, FromJSON m, FromJSON n, FromJSON o) => FromJSON (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) where
925− parseJSON = parseJSON2
926− {-# INLINE parseJSON #-}
Data/Aeson/Types/Internal.hs+1
@@ -29,6 +29,7 @@ module Data.Aeson.Types.Internal
2929 , Pair
3030 , Object
3131 , emptyObject
32+
3233 -- * Type conversion
3334 , Parser
3435 , Result(..)
Data/Aeson/Types/ToJSON.hsnew file+2099
@@ -0,0 +1,2099 @@
1+{-# LANGUAGE CPP #-}
2+{-# LANGUAGE DataKinds #-}
3+{-# LANGUAGE DefaultSignatures #-}
4+{-# LANGUAGE FlexibleContexts #-}
5+{-# LANGUAGE FlexibleInstances #-}
6+{-# LANGUAGE GADTs #-}
7+{-# LANGUAGE MultiParamTypeClasses #-}
8+{-# LANGUAGE NamedFieldPuns #-}
9+{-# LANGUAGE OverloadedStrings #-}
10+{-# LANGUAGE PatternGuards #-}
11+{-# LANGUAGE RecordWildCards #-}
12+{-# LANGUAGE ScopedTypeVariables #-}
13+{-# LANGUAGE TypeOperators #-}
14+{-# LANGUAGE TypeSynonymInstances #-}
15+{-# LANGUAGE UndecidableInstances #-}
16+
17+#if __GLASGOW_HASKELL__ >= 706
18+{-# LANGUAGE PolyKinds #-}
19+#endif
20+
21+#include "overlapping-compat.h"
22+
23+-- TODO: Drop this when we remove support for Data.Attoparsec.Number
24+{-# OPTIONS_GHC -fno-warn-deprecations #-}
25+
26+module Data.Aeson.Types.ToJSON (
27+ -- * Core JSON classes
28+ ToJSON(..)
29+ -- * Liftings to unary and binary type constructors
30+ , ToJSON1(..)
31+ , toJSON1
32+ , toEncoding1
33+ , ToJSON2(..)
34+ , toJSON2
35+ , toEncoding2
36+ -- * Generic JSON classes
37+ , GToJSON(..)
38+ , GToEncoding(..)
39+ , genericToJSON
40+ , genericToEncoding
41+ -- * Classes and types for map keys
42+ , ToJSONKey(..)
43+ , ToJSONKeyFunction(..)
44+ , contramapToJSONKeyFunction
45+ -- * Object key-value pairs
46+ , KeyValue(..)
47+ -- * Functions needed for documentation
48+ -- * Encoding functions
49+ , listEncoding
50+ , listValue
51+ ) where
52+
53+import Prelude ()
54+import Prelude.Compat
55+
56+import Data.Aeson.Encoding.Internal (Encoding (..), Series, dict, emptyArray_,
57+ tuple, (>*<))
58+import Data.Aeson.Functions (mapHashKeyVal, mapKeyVal)
59+import Data.Aeson.Types.Generic
60+import Data.Aeson.Types.Internal
61+
62+import qualified Data.Aeson.Encode.Builder as EB
63+import qualified Data.Aeson.Encoding.Internal as E
64+
65+import Control.Applicative (Const (..))
66+import Control.Monad.ST (ST)
67+import Data.Attoparsec.Number (Number (..))
68+import Data.Bits (unsafeShiftR)
69+import Data.DList (DList)
70+import Data.Fixed (Fixed, HasResolution)
71+import Data.Foldable (toList)
72+import Data.Functor.Identity (Identity (..))
73+import Data.Int (Int16, Int32, Int64, Int8)
74+import Data.List (intersperse)
75+import Data.List.NonEmpty (NonEmpty (..))
76+import Data.Monoid (Dual (..), First (..), Last (..), (<>))
77+import Data.Proxy (Proxy (..))
78+import Data.Ratio (Ratio, denominator, numerator)
79+import Data.Scientific (Scientific)
80+import Data.Tagged (Tagged (..))
81+import Data.Text (Text, pack)
82+import Data.Time (Day, LocalTime, NominalDiffTime, TimeOfDay,
83+ UTCTime, ZonedTime)
84+import Data.Time.Format (FormatTime, formatTime)
85+import Data.Time.Locale.Compat (defaultTimeLocale)
86+import Data.Vector (Vector)
87+import Data.Version (Version, showVersion)
88+import Data.Word (Word16, Word32, Word64, Word8)
89+import Foreign.Storable (Storable)
90+import GHC.Generics
91+import Numeric.Natural (Natural)
92+
93+import qualified Data.ByteString.Builder as B
94+import qualified Data.ByteString.Lazy as L
95+import qualified Data.DList as DList
96+import qualified Data.HashMap.Strict as H
97+import qualified Data.HashSet as HashSet
98+import qualified Data.IntMap as IntMap
99+import qualified Data.IntSet as IntSet
100+import qualified Data.List.NonEmpty as NE
101+import qualified Data.Map as M
102+import qualified Data.Scientific as Scientific
103+import qualified Data.Sequence as Seq
104+import qualified Data.Set as Set
105+import qualified Data.Text as T
106+import qualified Data.Text.Encoding as T
107+import qualified Data.Text.Lazy as LT
108+import qualified Data.Text.Lazy.Builder as LTB
109+import qualified Data.Text.Lazy.Builder.Int as LTBI
110+import qualified Data.Tree as Tree
111+import qualified Data.Vector as V
112+import qualified Data.Vector.Generic as VG
113+import qualified Data.Vector.Mutable as VM
114+import qualified Data.Vector.Primitive as VP
115+import qualified Data.Vector.Storable as VS
116+import qualified Data.Vector.Unboxed as VU
117+
118+builder :: ToJSON a => a -> B.Builder
119+builder = fromEncoding . toEncoding
120+
121+toJSONPair :: (a -> Value) -> (b -> Value) -> (a, b) -> Value
122+toJSONPair keySerialiser valSerializer (a, b) = Array $ V.create $ do
123+ mv <- VM.unsafeNew 2
124+ VM.unsafeWrite mv 0 (keySerialiser a)
125+ VM.unsafeWrite mv 1 (valSerializer b)
126+ return mv
127+{-# INLINE toJSONPair #-}
128+
129+realFloatToJSON :: RealFloat a => a -> Value
130+realFloatToJSON d
131+ | isNaN d || isInfinite d = Null
132+ | otherwise = Number $ Scientific.fromFloatDigits d
133+{-# INLINE realFloatToJSON #-}
134+
135+realFloatToEncoding :: RealFloat a => a -> Encoding
136+realFloatToEncoding d
137+ | isNaN d || isInfinite d = Encoding EB.null_
138+ | otherwise = toEncoding (Scientific.fromFloatDigits d)
139+{-# INLINE realFloatToEncoding #-}
140+-------------------------------------------------------------------------------
141+-- Generics
142+-------------------------------------------------------------------------------
143+
144+-- | Class of generic representation types ('Rep') that can be converted to
145+-- JSON.
146+class GToJSON f where
147+ -- | This method (applied to 'defaultOptions') is used as the
148+ -- default generic implementation of 'toJSON'.
149+ gToJSON :: Options -> f a -> Value
150+
151+-- | Class of generic representation types ('Rep') that can be converted to
152+-- a JSON 'Encoding'.
153+class GToEncoding f where
154+ -- | This method (applied to 'defaultOptions') can be used as the
155+ -- default generic implementation of 'toEncoding'.
156+ gToEncoding :: Options -> f a -> Encoding
157+
158+
159+-- | A configurable generic JSON creator. This function applied to
160+-- 'defaultOptions' is used as the default for 'toJSON' when the type
161+-- is an instance of 'Generic'.
162+genericToJSON :: (Generic a, GToJSON (Rep a)) => Options -> a -> Value
163+genericToJSON opts = gToJSON opts . from
164+
165+-- | A configurable generic JSON encoder. This function applied to
166+-- 'defaultOptions' is used as the default for 'toEncoding' when the type
167+-- is an instance of 'Generic'.
168+genericToEncoding :: (Generic a, GToEncoding (Rep a)) => Options -> a -> Encoding
169+genericToEncoding opts = gToEncoding opts . from
170+
171+-------------------------------------------------------------------------------
172+-- Class
173+-------------------------------------------------------------------------------
174+
175+-- | A type that can be converted to JSON.
176+--
177+-- An example type and instance:
178+--
179+-- @
180+-- \-- Allow ourselves to write 'Text' literals.
181+-- {-\# LANGUAGE OverloadedStrings #-}
182+--
183+-- data Coord = Coord { x :: Double, y :: Double }
184+--
185+-- instance ToJSON Coord where
186+-- toJSON (Coord x y) = 'object' [\"x\" '.=' x, \"y\" '.=' y]
187+--
188+-- toEncoding (Coord x y) = 'pairs' (\"x\" '.=' x '<>' \"y\" '.=' y)
189+-- @
190+--
191+-- Instead of manually writing your 'ToJSON' instance, there are two options
192+-- to do it automatically:
193+--
194+-- * "Data.Aeson.TH" provides Template Haskell functions which will derive an
195+-- instance at compile time. The generated instance is optimized for your type
196+-- so will probably be more efficient than the following two options:
197+--
198+-- * The compiler can provide a default generic implementation for
199+-- 'toJSON'.
200+--
201+-- To use the second, simply add a @deriving 'Generic'@ clause to your
202+-- datatype and declare a 'ToJSON' instance for your datatype without giving
203+-- definitions for 'toJSON' or 'toEncoding'.
204+--
205+-- For example, the previous example can be simplified to a more
206+-- minimal instance:
207+--
208+-- @
209+-- {-\# LANGUAGE DeriveGeneric \#-}
210+--
211+-- import "GHC.Generics"
212+--
213+-- data Coord = Coord { x :: Double, y :: Double } deriving 'Generic'
214+--
215+-- instance ToJSON Coord where
216+-- toEncoding = 'genericToEncoding' 'defaultOptions'
217+-- @
218+--
219+-- Why do we provide an implementation for 'toEncoding' here? The
220+-- 'toEncoding' function is a relatively new addition to this class.
221+-- To allow users of older versions of this library to upgrade without
222+-- having to edit all of their instances or encounter surprising
223+-- incompatibilities, the default implementation of 'toEncoding' uses
224+-- 'toJSON'. This produces correct results, but since it performs an
225+-- intermediate conversion to a 'Value', it will be less efficient
226+-- than directly emitting an 'Encoding'. Our one-liner definition of
227+-- 'toEncoding' above bypasses the intermediate 'Value'.
228+--
229+-- If @DefaultSignatures@ doesn't give exactly the results you want,
230+-- you can customize the generic encoding with only a tiny amount of
231+-- effort, using 'genericToJSON' and 'genericToEncoding' with your
232+-- preferred 'Options':
233+--
234+-- @
235+-- instance ToJSON Coord where
236+-- toJSON = 'genericToJSON' 'defaultOptions'
237+-- toEncoding = 'genericToEncoding' 'defaultOptions'
238+-- @
239+class ToJSON a where
240+ -- | Convert a Haskell value to a JSON-friendly intermediate type.
241+ toJSON :: a -> Value
242+
243+ default toJSON :: (Generic a, GToJSON (Rep a)) => a -> Value
244+ toJSON = genericToJSON defaultOptions
245+
246+ -- | Encode a Haskell value as JSON.
247+ --
248+ -- The default implementation of this method creates an
249+ -- intermediate 'Value' using 'toJSON'. This provides
250+ -- source-level compatibility for people upgrading from older
251+ -- versions of this library, but obviously offers no performance
252+ -- advantage.
253+ --
254+ -- To benefit from direct encoding, you /must/ provide an
255+ -- implementation for this method. The easiest way to do so is by
256+ -- having your types implement 'Generic' using the @DeriveGeneric@
257+ -- extension, and then have GHC generate a method body as follows.
258+ --
259+ -- @
260+ -- instance ToJSON Coord where
261+ -- toEncoding = 'genericToEncoding' 'defaultOptions'
262+ -- @
263+
264+ toEncoding :: a -> Encoding
265+ toEncoding = E.Encoding . EB.encodeToBuilder . toJSON
266+ {-# INLINE toEncoding #-}
267+
268+ toJSONList :: [a] -> Value
269+ toJSONList = listValue toJSON
270+ {-# INLINE toJSONList #-}
271+
272+ toEncodingList :: [a] -> Encoding
273+ toEncodingList = listEncoding toEncoding
274+ {-# INLINE toEncodingList #-}
275+
276+-------------------------------------------------------------------------------
277+-- Object key-value pairs
278+-------------------------------------------------------------------------------
279+
280+-- | A key-value pair for encoding a JSON object.
281+class KeyValue kv where
282+ (.=) :: ToJSON v => Text -> v -> kv
283+ infixr 8 .=
284+
285+instance KeyValue Series where
286+ name .= value = E.Value $ E.text name <> E.colon <> toEncoding value
287+ {-# INLINE (.=) #-}
288+
289+instance KeyValue Pair where
290+ name .= value = (name, toJSON value)
291+ {-# INLINE (.=) #-}
292+
293+-------------------------------------------------------------------------------
294+-- Classes and types for map keys
295+-------------------------------------------------------------------------------
296+
297+class ToJSONKey a where
298+ toJSONKey :: ToJSONKeyFunction a
299+ default toJSONKey :: ToJSON a => ToJSONKeyFunction a
300+ toJSONKey = ToJSONKeyValue (toJSON, toEncoding)
301+ toJSONKeyList :: ToJSONKeyFunction [a]
302+ default toJSONKeyList :: ToJSON a => ToJSONKeyFunction [a]
303+ toJSONKeyList = ToJSONKeyValue (toJSON, toEncoding)
304+
305+data ToJSONKeyFunction a
306+ = ToJSONKeyText (a -> Text, a -> Encoding)
307+ | ToJSONKeyValue (a -> Value, a -> Encoding)
308+
309+contramapToJSONKeyFunction :: (b -> a) -> ToJSONKeyFunction a -> ToJSONKeyFunction b
310+contramapToJSONKeyFunction h x = case x of
311+ ToJSONKeyText (f,g) -> ToJSONKeyText (f . h, g . h)
312+ ToJSONKeyValue (f,g) -> ToJSONKeyValue (f . h, g . h)
313+
314+-------------------------------------------------------------------------------
315+-- Lifings of FromJSON and ToJSON to unary and binary type constructors
316+-------------------------------------------------------------------------------
317+
318+-- | Lifting of the 'ToJSON' class to unary type constructors.
319+class ToJSON1 f where
320+ liftToJSON :: (a -> Value) -> ([a] -> Value) -> f a -> Value
321+ liftToJSONList :: (a -> Value) -> ([a] -> Value) -> [f a] -> Value
322+ liftToJSONList f g = listValue (liftToJSON f g)
323+
324+ -- | Unfortunately there cannot be a default implementation of 'liftToEncoding'.
325+ liftToEncoding :: (a -> Encoding) -> ([a] -> Encoding) -> f a -> Encoding
326+ liftToEncodingList :: (a -> Encoding) -> ([a] -> Encoding) -> [f a] -> Encoding
327+ liftToEncodingList f g = listEncoding (liftToEncoding f g)
328+
329+-- | Lift the standard 'toJSON' function through the type constructor.
330+toJSON1 :: (ToJSON1 f, ToJSON a) => f a -> Value
331+toJSON1 = liftToJSON toJSON toJSONList
332+{-# INLINE toJSON1 #-}
333+
334+-- | Lift the standard 'toEncoding' function through the type constructor.
335+toEncoding1 :: (ToJSON1 f, ToJSON a) => f a -> Encoding
336+toEncoding1 = liftToEncoding toEncoding toEncodingList
337+{-# INLINE toEncoding1 #-}
338+
339+
340+-- | Lifting of the 'ToJSON' class to binary type constructors.
341+class ToJSON2 f where
342+ liftToJSON2 :: (a -> Value) -> ([a] -> Value) -> (b -> Value) -> ([b] -> Value) -> f a b -> Value
343+ liftToJSONList2 :: (a -> Value) -> ([a] -> Value) -> (b -> Value) -> ([b] -> Value) -> [f a b] -> Value
344+ liftToJSONList2 fa ga fb gb = listValue (liftToJSON2 fa ga fb gb)
345+
346+ liftToEncoding2 :: (a -> Encoding) -> ([a] -> Encoding) -> (b -> Encoding) -> ([b] -> Encoding) -> f a b -> Encoding
347+ liftToEncodingList2 :: (a -> Encoding) -> ([a] -> Encoding) -> (b -> Encoding) -> ([b] -> Encoding) -> [f a b] -> Encoding
348+ liftToEncodingList2 fa ga fb gb = listEncoding (liftToEncoding2 fa ga fb gb)
349+
350+-- | Lift the standard 'toJSON' function through the type constructor.
351+toJSON2 :: (ToJSON2 f, ToJSON a, ToJSON b) => f a b -> Value
352+toJSON2 = liftToJSON2 toJSON toJSONList toJSON toJSONList
353+{-# INLINE toJSON2 #-}
354+
355+-- | Lift the standard 'toEncoding' function through the type constructor.
356+toEncoding2 :: (ToJSON2 f, ToJSON a, ToJSON b) => f a b -> Encoding
357+toEncoding2 = liftToEncoding2 toEncoding toEncodingList toEncoding toEncodingList
358+{-# INLINE toEncoding2 #-}
359+
360+-------------------------------------------------------------------------------
361+-- Encoding functions
362+-------------------------------------------------------------------------------
363+
364+listEncoding :: (a -> Encoding) -> [a] -> Encoding
365+listEncoding = E.list
366+
367+listValue :: (a -> Value) -> [a] -> Value
368+listValue f = Array . V.fromList . map f
369+{-# INLINE listValue #-}
370+
371+-------------------------------------------------------------------------------
372+-- [] instances
373+-------------------------------------------------------------------------------
374+
375+-- These are needed for key-class default definitions
376+
377+instance ToJSON1 [] where
378+ liftToJSON _ to' = to'
379+ {-# INLINE liftToJSON #-}
380+
381+ liftToEncoding _ to' = to'
382+ {-# INLINE liftToEncoding #-}
383+
384+instance (ToJSON a) => ToJSON [a] where
385+ toJSON = toJSON1
386+ {-# INLINE toJSON #-}
387+
388+ toEncoding = toEncoding1
389+ {-# INLINE toEncoding #-}
390+
391+-------------------------------------------------------------------------------
392+-- Generic toJSON / toEncoding
393+-------------------------------------------------------------------------------
394+
395+--------------------------------------------------------------------------------
396+-- Generic toJSON
397+
398+instance OVERLAPPABLE_ (GToJSON a) => GToJSON (M1 i c a) where
399+ -- Meta-information, which is not handled elsewhere, is ignored:
400+ gToJSON opts = gToJSON opts . unM1
401+
402+instance (ToJSON a) => GToJSON (K1 i a) where
403+ -- Constant values are encoded using their ToJSON instance:
404+ gToJSON _opts = toJSON . unK1
405+
406+instance GToJSON U1 where
407+ -- Empty constructors are encoded to an empty array:
408+ gToJSON _opts _ = emptyArray
409+
410+instance (ConsToJSON a) => GToJSON (C1 c a) where
411+ -- Constructors need to be encoded differently depending on whether they're
412+ -- a record or not. This distinction is made by 'consToJSON':
413+ gToJSON opts = consToJSON opts . unM1
414+
415+instance ( WriteProduct a, WriteProduct b
416+ , ProductSize a, ProductSize b ) => GToJSON (a :*: b) where
417+ -- Products are encoded to an array. Here we allocate a mutable vector of
418+ -- the same size as the product and write the product's elements to it using
419+ -- 'writeProduct':
420+ gToJSON opts p =
421+ Array $ V.create $ do
422+ mv <- VM.unsafeNew lenProduct
423+ writeProduct opts mv 0 lenProduct p
424+ return mv
425+ where
426+ lenProduct = (unTagged2 :: Tagged2 (a :*: b) Int -> Int)
427+ productSize
428+
429+instance ( AllNullary (a :+: b) allNullary
430+ , SumToJSON (a :+: b) allNullary ) => GToJSON (a :+: b) where
431+ -- If all constructors of a sum datatype are nullary and the
432+ -- 'allNullaryToStringTag' option is set they are encoded to
433+ -- strings. This distinction is made by 'sumToJSON':
434+ gToJSON opts = (unTagged :: Tagged allNullary Value -> Value)
435+ . sumToJSON opts
436+
437+--------------------------------------------------------------------------------
438+-- Generic toEncoding
439+
440+instance OVERLAPPABLE_ (GToEncoding a) => GToEncoding (M1 i c a) where
441+ -- Meta-information, which is not handled elsewhere, is ignored:
442+ gToEncoding opts = gToEncoding opts . unM1
443+
444+instance (ToJSON a) => GToEncoding (K1 i a) where
445+ -- Constant values are encoded using their ToJSON instance:
446+ gToEncoding _opts = toEncoding . unK1
447+
448+instance GToEncoding U1 where
449+ -- Empty constructors are encoded to an empty array:
450+ gToEncoding _opts _ = E.emptyArray_
451+
452+instance (ConsToEncoding a) => GToEncoding (C1 c a) where
453+ -- Constructors need to be encoded differently depending on whether they're
454+ -- a record or not. This distinction is made by 'consToEncoding':
455+ gToEncoding opts = consToEncoding opts . unM1
456+
457+instance ( EncodeProduct a, EncodeProduct b ) => GToEncoding (a :*: b) where
458+ -- Products are encoded to an array. Here we allocate a mutable vector of
459+ -- the same size as the product and write the product's elements to it using
460+ -- 'encodeProduct':
461+ gToEncoding opts p = E.tuple $ encodeProduct opts p
462+
463+instance ( AllNullary (a :+: b) allNullary
464+ , SumToEncoding (a :+: b) allNullary ) => GToEncoding (a :+: b) where
465+ -- If all constructors of a sum datatype are nullary and the
466+ -- 'allNullaryToStringTag' option is set they are encoded to
467+ -- strings. This distinction is made by 'sumToEncoding':
468+ gToEncoding opts
469+ = (unTagged :: Tagged allNullary Encoding -> Encoding)
470+ . sumToEncoding opts
471+
472+--------------------------------------------------------------------------------
473+
474+class SumToJSON f allNullary where
475+ sumToJSON :: Options -> f a -> Tagged allNullary Value
476+
477+instance ( GetConName f
478+ , TaggedObjectPairs f
479+ , ObjectWithSingleFieldObj f
480+ , TwoElemArrayObj f ) => SumToJSON f True where
481+ sumToJSON opts
482+ | allNullaryToStringTag opts = Tagged . String . pack
483+ . constructorTagModifier opts . getConName
484+ | otherwise = Tagged . nonAllNullarySumToJSON opts
485+
486+instance ( TwoElemArrayObj f
487+ , TaggedObjectPairs f
488+ , ObjectWithSingleFieldObj f ) => SumToJSON f False where
489+ sumToJSON opts = Tagged . nonAllNullarySumToJSON opts
490+
491+nonAllNullarySumToJSON :: ( TwoElemArrayObj f
492+ , TaggedObjectPairs f
493+ , ObjectWithSingleFieldObj f
494+ ) => Options -> f a -> Value
495+nonAllNullarySumToJSON opts =
496+ case sumEncoding opts of
497+ TaggedObject{..} ->
498+ object . taggedObjectPairs opts tagFieldName contentsFieldName
499+ ObjectWithSingleField -> Object . objectWithSingleFieldObj opts
500+ TwoElemArray -> Array . twoElemArrayObj opts
501+
502+--------------------------------------------------------------------------------
503+
504+class SumToEncoding f allNullary where
505+ sumToEncoding :: Options -> f a -> Tagged allNullary Encoding
506+
507+instance ( GetConName f
508+ , TaggedObjectEnc f
509+ , ObjectWithSingleFieldEnc f
510+ , TwoElemArrayEnc f ) => SumToEncoding f True where
511+ sumToEncoding opts
512+ | allNullaryToStringTag opts = Tagged . toEncoding .
513+ constructorTagModifier opts . getConName
514+ | otherwise = Tagged . nonAllNullarySumToEncoding opts
515+
516+instance ( TwoElemArrayEnc f
517+ , TaggedObjectEnc f
518+ , ObjectWithSingleFieldEnc f ) => SumToEncoding f False where
519+ sumToEncoding opts = Tagged . nonAllNullarySumToEncoding opts
520+
521+nonAllNullarySumToEncoding :: ( TwoElemArrayEnc f
522+ , TaggedObjectEnc f
523+ , ObjectWithSingleFieldEnc f
524+ ) => Options -> f a -> Encoding
525+nonAllNullarySumToEncoding opts =
526+ case sumEncoding opts of
527+ TaggedObject{..} ->
528+ taggedObjectEnc opts tagFieldName contentsFieldName
529+ ObjectWithSingleField -> objectWithSingleFieldEnc opts
530+ TwoElemArray -> twoElemArrayEnc opts
531+
532+--------------------------------------------------------------------------------
533+
534+class TaggedObjectPairs f where
535+ taggedObjectPairs :: Options -> String -> String -> f a -> [Pair]
536+
537+instance ( TaggedObjectPairs a
538+ , TaggedObjectPairs b ) => TaggedObjectPairs (a :+: b) where
539+ taggedObjectPairs opts tagFieldName contentsFieldName (L1 x) =
540+ taggedObjectPairs opts tagFieldName contentsFieldName x
541+ taggedObjectPairs opts tagFieldName contentsFieldName (R1 x) =
542+ taggedObjectPairs opts tagFieldName contentsFieldName x
543+
544+instance ( IsRecord a isRecord
545+ , TaggedObjectPairs' a isRecord
546+ , Constructor c ) => TaggedObjectPairs (C1 c a) where
547+ taggedObjectPairs opts tagFieldName contentsFieldName =
548+ (pack tagFieldName .= constructorTagModifier opts
549+ (conName (undefined :: t c a p)) :) .
550+ (unTagged :: Tagged isRecord [Pair] -> [Pair]) .
551+ taggedObjectPairs' opts contentsFieldName . unM1
552+
553+class TaggedObjectPairs' f isRecord where
554+ taggedObjectPairs' :: Options -> String -> f a -> Tagged isRecord [Pair]
555+
556+instance OVERLAPPING_ TaggedObjectPairs' U1 False where
557+ taggedObjectPairs' _ _ _ = Tagged []
558+
559+instance (RecordToPairs f) => TaggedObjectPairs' f True where
560+ taggedObjectPairs' opts _ = Tagged . toList . recordToPairs opts
561+
562+instance (GToJSON f) => TaggedObjectPairs' f False where
563+ taggedObjectPairs' opts contentsFieldName =
564+ Tagged . (:[]) . (pack contentsFieldName .=) . gToJSON opts
565+
566+--------------------------------------------------------------------------------
567+
568+class TaggedObjectEnc f where
569+ taggedObjectEnc :: Options -> String -> String -> f a -> Encoding
570+
571+instance ( TaggedObjectEnc a
572+ , TaggedObjectEnc b ) => TaggedObjectEnc (a :+: b) where
573+ taggedObjectEnc opts tagFieldName contentsFieldName (L1 x) =
574+ taggedObjectEnc opts tagFieldName contentsFieldName x
575+ taggedObjectEnc opts tagFieldName contentsFieldName (R1 x) =
576+ taggedObjectEnc opts tagFieldName contentsFieldName x
577+
578+instance ( IsRecord a isRecord
579+ , TaggedObjectEnc' a isRecord
580+ , Constructor c ) => TaggedObjectEnc (C1 c a) where
581+ taggedObjectEnc opts tagFieldName contentsFieldName v =
582+ E.openCurly <>
583+ (toEncoding tagFieldName <>
584+ E.colon <>
585+ toEncoding (constructorTagModifier opts (conName (undefined :: t c a p)))) <>
586+ ((unTagged :: Tagged isRecord Encoding -> Encoding) .
587+ taggedObjectEnc' opts contentsFieldName . unM1 $ v) <>
588+ E.closeCurly
589+
590+class TaggedObjectEnc' f isRecord where
591+ taggedObjectEnc' :: Options -> String -> f a -> Tagged isRecord Encoding
592+
593+instance OVERLAPPING_ TaggedObjectEnc' U1 False where
594+ taggedObjectEnc' _ _ _ = Tagged mempty
595+
596+instance (RecordToEncoding f) => TaggedObjectEnc' f True where
597+ taggedObjectEnc' opts _ = Tagged . (E.comma <>) . fst . recordToEncoding opts
598+
599+instance (GToEncoding f) => TaggedObjectEnc' f False where
600+ taggedObjectEnc' opts contentsFieldName =
601+ Tagged . (\z -> E.comma <> toEncoding contentsFieldName <> E.colon <> z) .
602+ gToEncoding opts
603+
604+--------------------------------------------------------------------------------
605+
606+-- | Get the name of the constructor of a sum datatype.
607+class GetConName f where
608+ getConName :: f a -> String
609+
610+instance (GetConName a, GetConName b) => GetConName (a :+: b) where
611+ getConName (L1 x) = getConName x
612+ getConName (R1 x) = getConName x
613+
614+instance (Constructor c) => GetConName (C1 c a) where
615+ getConName = conName
616+
617+--------------------------------------------------------------------------------
618+
619+class TwoElemArrayObj f where
620+ twoElemArrayObj :: Options -> f a -> V.Vector Value
621+
622+instance (TwoElemArrayObj a, TwoElemArrayObj b) => TwoElemArrayObj (a :+: b) where
623+ twoElemArrayObj opts (L1 x) = twoElemArrayObj opts x
624+ twoElemArrayObj opts (R1 x) = twoElemArrayObj opts x
625+
626+instance ( GToJSON a, ConsToJSON a
627+ , Constructor c ) => TwoElemArrayObj (C1 c a) where
628+ twoElemArrayObj opts x = V.create $ do
629+ mv <- VM.unsafeNew 2
630+ VM.unsafeWrite mv 0 $ String $ pack $ constructorTagModifier opts
631+ $ conName (undefined :: t c a p)
632+ VM.unsafeWrite mv 1 $ gToJSON opts x
633+ return mv
634+
635+--------------------------------------------------------------------------------
636+
637+class TwoElemArrayEnc f where
638+ twoElemArrayEnc :: Options -> f a -> Encoding
639+
640+instance (TwoElemArrayEnc a, TwoElemArrayEnc b) => TwoElemArrayEnc (a :+: b) where
641+ twoElemArrayEnc opts (L1 x) = twoElemArrayEnc opts x
642+ twoElemArrayEnc opts (R1 x) = twoElemArrayEnc opts x
643+
644+instance ( GToEncoding a, ConsToEncoding a
645+ , Constructor c ) => TwoElemArrayEnc (C1 c a) where
646+ twoElemArrayEnc opts x = E.tuple $
647+ toEncoding (constructorTagModifier opts (conName (undefined :: t c a p))) >*<
648+ gToEncoding opts x
649+
650+--------------------------------------------------------------------------------
651+
652+class ConsToJSON f where
653+ consToJSON :: Options -> f a -> Value
654+
655+class ConsToJSON' f isRecord where
656+ consToJSON' :: Options -> Bool -- ^ Are we a record with one field?
657+ -> f a -> Tagged isRecord Value
658+
659+instance ( IsRecord f isRecord
660+ , ConsToJSON' f isRecord ) => ConsToJSON f where
661+ consToJSON opts = (unTagged :: Tagged isRecord Value -> Value)
662+ . consToJSON' opts (isUnary (undefined :: f a))
663+
664+instance (RecordToPairs f) => ConsToJSON' f True where
665+ consToJSON' opts isUn f = let
666+ vals = toList $ recordToPairs opts f
667+ in case (unwrapUnaryRecords opts,isUn,vals) of
668+ (True,True,[(_,val)]) -> Tagged val
669+ _ -> Tagged $ object vals
670+
671+instance GToJSON f => ConsToJSON' f False where
672+ consToJSON' opts _ = Tagged . gToJSON opts
673+
674+--------------------------------------------------------------------------------
675+
676+class ConsToEncoding f where
677+ consToEncoding :: Options -> f a -> Encoding
678+
679+class ConsToEncoding' f isRecord where
680+ consToEncoding' :: Options -> Bool -- ^ Are we a record with one field?
681+ -> f a -> Tagged isRecord Encoding
682+
683+instance ( IsRecord f isRecord
684+ , ConsToEncoding' f isRecord ) => ConsToEncoding f where
685+ consToEncoding opts = (unTagged :: Tagged isRecord Encoding -> Encoding)
686+ . consToEncoding' opts (isUnary (undefined :: f a))
687+
688+instance (RecordToEncoding f) => ConsToEncoding' f True where
689+ consToEncoding' opts isUn x =
690+ let (enc, mbVal) = recordToEncoding opts x
691+ in case (unwrapUnaryRecords opts, isUn, mbVal) of
692+ (True, True, Just val) -> Tagged val
693+ _ -> Tagged $ E.wrapObject enc
694+
695+instance GToEncoding f => ConsToEncoding' f False where
696+ consToEncoding' opts _ = Tagged . gToEncoding opts
697+
698+--------------------------------------------------------------------------------
699+
700+class RecordToPairs f where
701+ recordToPairs :: Options -> f a -> DList Pair
702+
703+instance (RecordToPairs a, RecordToPairs b) => RecordToPairs (a :*: b) where
704+ recordToPairs opts (a :*: b) = recordToPairs opts a <>
705+ recordToPairs opts b
706+
707+instance (Selector s, GToJSON a) => RecordToPairs (S1 s a) where
708+ recordToPairs = fieldToPair
709+
710+instance OVERLAPPING_ (Selector s, ToJSON a) =>
711+ RecordToPairs (S1 s (K1 i (Maybe a))) where
712+ recordToPairs opts (M1 k1) | omitNothingFields opts
713+ , K1 Nothing <- k1 = DList.empty
714+ recordToPairs opts m1 = fieldToPair opts m1
715+
716+fieldToPair :: (Selector s, GToJSON a) => Options -> S1 s a p -> DList Pair
717+fieldToPair opts m1 = pure ( pack $ fieldLabelModifier opts $ selName m1
718+ , gToJSON opts (unM1 m1)
719+ )
720+
721+--------------------------------------------------------------------------------
722+
723+class RecordToEncoding f where
724+ -- 1st element: whole thing
725+ -- 2nd element: in case the record has only 1 field, just the value
726+ -- of the field (without the key); 'Nothing' otherwise
727+ recordToEncoding :: Options -> f a -> (Encoding, Maybe Encoding)
728+
729+instance (RecordToEncoding a, RecordToEncoding b) => RecordToEncoding (a :*: b) where
730+ recordToEncoding opts (a :*: b) | omitNothingFields opts =
731+ (mconcat $ intersperse E.comma $
732+ filter (not . E.nullEncoding)
733+ [fst (recordToEncoding opts a), fst (recordToEncoding opts b)]
734+ , Nothing)
735+ recordToEncoding opts (a :*: b) =
736+ (fst (recordToEncoding opts a) <> E.comma <>
737+ fst (recordToEncoding opts b),
738+ Nothing)
739+
740+instance (Selector s, GToEncoding a) => RecordToEncoding (S1 s a) where
741+ recordToEncoding = fieldToEncoding
742+
743+instance OVERLAPPING_ (Selector s, ToJSON a) =>
744+ RecordToEncoding (S1 s (K1 i (Maybe a))) where
745+ recordToEncoding opts (M1 k1) | omitNothingFields opts
746+ , K1 Nothing <- k1 = (mempty, Nothing)
747+ recordToEncoding opts m1 = fieldToEncoding opts m1
748+
749+fieldToEncoding :: (Selector s, GToEncoding a) => Options -> S1 s a p -> (Encoding, Maybe Encoding)
750+fieldToEncoding opts m1 =
751+ let keyBuilder = toEncoding (fieldLabelModifier opts $ selName m1)
752+ valueBuilder = gToEncoding opts (unM1 m1)
753+ in (keyBuilder <> E.colon <> valueBuilder, Just valueBuilder)
754+
755+--------------------------------------------------------------------------------
756+
757+class WriteProduct f where
758+ writeProduct :: Options
759+ -> VM.MVector s Value
760+ -> Int -- ^ index
761+ -> Int -- ^ length
762+ -> f a
763+ -> ST s ()
764+
765+instance ( WriteProduct a
766+ , WriteProduct b ) => WriteProduct (a :*: b) where
767+ writeProduct opts mv ix len (a :*: b) = do
768+ writeProduct opts mv ix lenL a
769+ writeProduct opts mv ixR lenR b
770+ where
771+ lenL = len `unsafeShiftR` 1
772+ lenR = len - lenL
773+ ixR = ix + lenL
774+
775+instance OVERLAPPABLE_ (GToJSON a) => WriteProduct a where
776+ writeProduct opts mv ix _ = VM.unsafeWrite mv ix . gToJSON opts
777+
778+--------------------------------------------------------------------------------
779+
780+class EncodeProduct f where
781+ encodeProduct :: Options -> f a -> Encoding
782+
783+instance ( EncodeProduct a
784+ , EncodeProduct b ) => EncodeProduct (a :*: b) where
785+ encodeProduct opts (a :*: b) | omitNothingFields opts =
786+ mconcat $ intersperse E.comma $
787+ filter (not . E.nullEncoding)
788+ [encodeProduct opts a, encodeProduct opts b]
789+ encodeProduct opts (a :*: b) = encodeProduct opts a <>
790+ E.comma <>
791+ encodeProduct opts b
792+
793+instance OVERLAPPABLE_ (GToEncoding a) => EncodeProduct a where
794+ encodeProduct opts = gToEncoding opts
795+
796+--------------------------------------------------------------------------------
797+
798+class ObjectWithSingleFieldObj f where
799+ objectWithSingleFieldObj :: Options -> f a -> Object
800+
801+instance ( ObjectWithSingleFieldObj a
802+ , ObjectWithSingleFieldObj b ) => ObjectWithSingleFieldObj (a :+: b) where
803+ objectWithSingleFieldObj opts (L1 x) = objectWithSingleFieldObj opts x
804+ objectWithSingleFieldObj opts (R1 x) = objectWithSingleFieldObj opts x
805+
806+instance ( GToJSON a, ConsToJSON a
807+ , Constructor c ) => ObjectWithSingleFieldObj (C1 c a) where
808+ objectWithSingleFieldObj opts = H.singleton typ . gToJSON opts
809+ where
810+ typ = pack $ constructorTagModifier opts $
811+ conName (undefined :: t c a p)
812+
813+--------------------------------------------------------------------------------
814+
815+class ObjectWithSingleFieldEnc f where
816+ objectWithSingleFieldEnc :: Options -> f a -> Encoding
817+
818+instance ( ObjectWithSingleFieldEnc a
819+ , ObjectWithSingleFieldEnc b ) => ObjectWithSingleFieldEnc (a :+: b) where
820+ objectWithSingleFieldEnc opts (L1 x) = objectWithSingleFieldEnc opts x
821+ objectWithSingleFieldEnc opts (R1 x) = objectWithSingleFieldEnc opts x
822+
823+instance ( GToEncoding a, ConsToEncoding a
824+ , Constructor c ) => ObjectWithSingleFieldEnc (C1 c a) where
825+ objectWithSingleFieldEnc opts v =
826+ E.openCurly <>
827+ toEncoding
828+ (constructorTagModifier opts
829+ (conName (undefined :: t c a p))) <>
830+ E.colon <>
831+ gToEncoding opts v <>
832+ E.closeCurly
833+
834+-------------------------------------------------------------------------------
835+-- Instances
836+-------------------------------------------------------------------------------
837+
838+
839+
840+-------------------------------------------------------------------------------
841+-- base
842+-------------------------------------------------------------------------------
843+
844+instance ToJSON1 Identity where
845+ liftToJSON t _ (Identity a) = t a
846+ {-# INLINE liftToJSON #-}
847+
848+ liftToEncoding t _ (Identity a) = t a
849+ {-# INLINE liftToEncoding #-}
850+
851+instance (ToJSON a) => ToJSON (Identity a) where
852+ toJSON = toJSON1
853+ {-# INLINE toJSON #-}
854+
855+ toEncoding = toEncoding1
856+ {-# INLINE toEncoding #-}
857+
858+
859+instance ToJSON2 Const where
860+ liftToJSON2 t _ _ _ (Const x) = t x
861+ {-# INLINE liftToJSON2 #-}
862+
863+ liftToEncoding2 t _ _ _ (Const x) = t x
864+ {-# INLINE liftToEncoding2 #-}
865+
866+instance ToJSON a => ToJSON1 (Const a) where
867+ liftToJSON _ _ (Const x) = toJSON x
868+ {-# INLINE liftToJSON #-}
869+
870+ liftToEncoding _ _ (Const x) = toEncoding x
871+ {-# INLINE liftToEncoding #-}
872+
873+instance ToJSON a => ToJSON (Const a b) where
874+ toJSON (Const x) = toJSON x
875+ {-# INLINE toJSON #-}
876+
877+ toEncoding (Const x) = toEncoding x
878+ {-# INLINE toEncoding #-}
879+
880+
881+instance ToJSON1 Maybe where
882+ liftToJSON t _ (Just a) = t a
883+ liftToJSON _ _ Nothing = Null
884+ {-# INLINE liftToJSON #-}
885+
886+ liftToEncoding t _ (Just a) = t a
887+ liftToEncoding _ _ Nothing = Encoding EB.null_
888+ {-# INLINE liftToEncoding #-}
889+
890+instance (ToJSON a) => ToJSON (Maybe a) where
891+ toJSON = toJSON1
892+ {-# INLINE toJSON #-}
893+
894+ toEncoding = toEncoding1
895+ {-# INLINE toEncoding #-}
896+
897+
898+instance ToJSON2 Either where
899+ liftToJSON2 toA _ _toB _ (Left a) = Object $ H.singleton left (toA a)
900+ liftToJSON2 _toA _ toB _ (Right b) = Object $ H.singleton right (toB b)
901+ {-# INLINE liftToJSON2 #-}
902+
903+ liftToEncoding2 toA _ _toB _ (Left a) =
904+ Encoding (B.shortByteString "{\"Left\":")
905+ <> toA a
906+ <> Encoding (B.char7 '}')
907+
908+ liftToEncoding2 _toA _ toB _ (Right b) =
909+ Encoding (B.shortByteString "{\"Right\":")
910+ <> toB b
911+ <> Encoding (B.char7 '}')
912+ {-# INLINE liftToEncoding2 #-}
913+
914+instance (ToJSON a) => ToJSON1 (Either a) where
915+ liftToJSON = liftToJSON2 toJSON toJSONList
916+ {-# INLINE liftToJSON #-}
917+
918+ liftToEncoding = liftToEncoding2 toEncoding toEncodingList
919+ {-# INLINE liftToEncoding #-}
920+
921+instance (ToJSON a, ToJSON b) => ToJSON (Either a b) where
922+ toJSON = toJSON2
923+ {-# INLINE toJSON #-}
924+
925+ toEncoding = toEncoding2
926+ {-# INLINE toEncoding #-}
927+
928+left, right :: Text
929+left = "Left"
930+right = "Right"
931+
932+
933+instance ToJSON Bool where
934+ toJSON = Bool
935+ {-# INLINE toJSON #-}
936+
937+ toEncoding = Encoding . EB.bool
938+ {-# INLINE toEncoding #-}
939+
940+
941+instance ToJSON Ordering where
942+ toJSON = toJSON . orderingToText
943+ toEncoding = toEncoding . orderingToText
944+
945+orderingToText :: Ordering -> T.Text
946+orderingToText o = case o of
947+ LT -> "LT"
948+ EQ -> "EQ"
949+ GT -> "GT"
950+
951+instance ToJSON () where
952+ toJSON _ = emptyArray
953+ {-# INLINE toJSON #-}
954+
955+ toEncoding _ = emptyArray_
956+ {-# INLINE toEncoding #-}
957+
958+
959+instance ToJSON Char where
960+ toJSON = String . T.singleton
961+ {-# INLINE toJSON #-}
962+
963+ toJSONList = String . T.pack
964+ {-# INLINE toJSONList #-}
965+
966+ toEncoding = Encoding . EB.string . (:[])
967+ {-# INLINE toEncoding #-}
968+
969+ toEncodingList = Encoding . EB.string
970+ {-# INLINE toEncodingList #-}
971+
972+
973+instance ToJSON Double where
974+ toJSON = realFloatToJSON
975+ {-# INLINE toJSON #-}
976+
977+ toEncoding = realFloatToEncoding
978+ {-# INLINE toEncoding #-}
979+
980+
981+instance ToJSON Number where
982+ toJSON (D d) = toJSON d
983+ toJSON (I i) = toJSON i
984+ {-# INLINE toJSON #-}
985+
986+ toEncoding (D d) = toEncoding d
987+ toEncoding (I i) = toEncoding i
988+ {-# INLINE toEncoding #-}
989+
990+
991+instance ToJSON Float where
992+ toJSON = realFloatToJSON
993+ {-# INLINE toJSON #-}
994+
995+ toEncoding = realFloatToEncoding
996+ {-# INLINE toEncoding #-}
997+
998+
999+instance ToJSON (Ratio Integer) where
1000+ toJSON r = object [ "numerator" .= numerator r
1001+ , "denominator" .= denominator r
1002+ ]
1003+ {-# INLINE toJSON #-}
1004+
1005+ toEncoding r = Encoding $
1006+ B.shortByteString "{\"numerator\":" <> builder (numerator r) <>
1007+ B.shortByteString ",\"denominator\":" <> builder (denominator r) <>
1008+ B.char7 '}'
1009+ {-# INLINE toEncoding #-}
1010+
1011+
1012+instance HasResolution a => ToJSON (Fixed a) where
1013+ toJSON = Number . realToFrac
1014+ {-# INLINE toJSON #-}
1015+
1016+ toEncoding = Encoding . EB.number . realToFrac
1017+ {-# INLINE toEncoding #-}
1018+
1019+
1020+instance ToJSON Int where
1021+ toJSON = Number . fromIntegral
1022+ {-# INLINE toJSON #-}
1023+
1024+ toEncoding = Encoding . B.intDec
1025+ {-# INLINE toEncoding #-}
1026+
1027+instance ToJSON Integer where
1028+ toJSON = Number . fromInteger
1029+ {-# INLINE toJSON #-}
1030+
1031+ toEncoding = Encoding . B.integerDec
1032+ {-# INLINE toEncoding #-}
1033+
1034+
1035+instance ToJSON Natural where
1036+ toJSON = toJSON . toInteger
1037+ {-# INLINE toJSON #-}
1038+
1039+ toEncoding = toEncoding . toInteger
1040+ {-# INLINE toEncoding #-}
1041+
1042+
1043+instance ToJSON Int8 where
1044+ toJSON = Number . fromIntegral
1045+ {-# INLINE toJSON #-}
1046+
1047+ toEncoding = Encoding . B.int8Dec
1048+ {-# INLINE toEncoding #-}
1049+
1050+
1051+instance ToJSON Int16 where
1052+ toJSON = Number . fromIntegral
1053+ {-# INLINE toJSON #-}
1054+
1055+ toEncoding = Encoding . B.int16Dec
1056+ {-# INLINE toEncoding #-}
1057+
1058+
1059+instance ToJSON Int32 where
1060+ toJSON = Number . fromIntegral
1061+ {-# INLINE toJSON #-}
1062+
1063+ toEncoding = Encoding . B.int32Dec
1064+ {-# INLINE toEncoding #-}
1065+
1066+
1067+instance ToJSON Int64 where
1068+ toJSON = Number . fromIntegral
1069+ {-# INLINE toJSON #-}
1070+
1071+ toEncoding = Encoding . B.int64Dec
1072+ {-# INLINE toEncoding #-}
1073+
1074+
1075+instance ToJSON Word where
1076+ toJSON = Number . fromIntegral
1077+ {-# INLINE toJSON #-}
1078+
1079+ toEncoding = Encoding . B.wordDec
1080+ {-# INLINE toEncoding #-}
1081+
1082+
1083+instance ToJSON Word8 where
1084+ toJSON = Number . fromIntegral
1085+ {-# INLINE toJSON #-}
1086+
1087+ toEncoding = Encoding . B.word8Dec
1088+ {-# INLINE toEncoding #-}
1089+
1090+
1091+instance ToJSON Word16 where
1092+ toJSON = Number . fromIntegral
1093+ {-# INLINE toJSON #-}
1094+
1095+ toEncoding = Encoding . B.word16Dec
1096+ {-# INLINE toEncoding #-}
1097+
1098+
1099+instance ToJSON Word32 where
1100+ toJSON = Number . fromIntegral
1101+ {-# INLINE toJSON #-}
1102+
1103+ toEncoding = Encoding . B.word32Dec
1104+ {-# INLINE toEncoding #-}
1105+
1106+instance ToJSON Word64 where
1107+ toJSON = Number . fromIntegral
1108+ {-# INLINE toJSON #-}
1109+
1110+ toEncoding = Encoding . B.word64Dec
1111+ {-# INLINE toEncoding #-}
1112+
1113+instance ToJSON Text where
1114+ toJSON = String
1115+ {-# INLINE toJSON #-}
1116+
1117+ toEncoding = Encoding . EB.text
1118+ {-# INLINE toEncoding #-}
1119+
1120+instance ToJSON LT.Text where
1121+ toJSON = String . LT.toStrict
1122+ {-# INLINE toJSON #-}
1123+
1124+ toEncoding t = Encoding $
1125+ B.char7 '"' <>
1126+ LT.foldrChunks (\x xs -> EB.unquoted x <> xs) (B.char7 '"') t
1127+ {-# INLINE toEncoding #-}
1128+
1129+instance ToJSON Version where
1130+ toJSON = toJSON . showVersion
1131+ {-# INLINE toJSON #-}
1132+
1133+ toEncoding = toEncoding . showVersion
1134+ {-# INLINE toEncoding #-}
1135+
1136+
1137+-------------------------------------------------------------------------------
1138+-- semigroups NonEmpty
1139+-------------------------------------------------------------------------------
1140+
1141+instance ToJSON1 NonEmpty where
1142+ liftToJSON t _ = listValue t . NE.toList
1143+ {-# INLINE liftToJSON #-}
1144+
1145+ liftToEncoding t _ = listEncoding t . NE.toList
1146+ {-# INLINE liftToEncoding #-}
1147+
1148+instance (ToJSON a) => ToJSON (NonEmpty a) where
1149+ toJSON = toJSON1
1150+ {-# INLINE toJSON #-}
1151+
1152+ toEncoding = toEncoding1
1153+ {-# INLINE toEncoding #-}
1154+
1155+-------------------------------------------------------------------------------
1156+-- scientific
1157+-------------------------------------------------------------------------------
1158+
1159+instance ToJSON Scientific where
1160+ toJSON = Number
1161+ {-# INLINE toJSON #-}
1162+
1163+ toEncoding = Encoding . EB.number
1164+ {-# INLINE toEncoding #-}
1165+
1166+-------------------------------------------------------------------------------
1167+-- containers
1168+-------------------------------------------------------------------------------
1169+
1170+instance ToJSON1 Seq.Seq where
1171+ liftToJSON t _ = listValue t . toList
1172+ {-# INLINE liftToJSON #-}
1173+
1174+ liftToEncoding t _ = listEncoding t . toList
1175+ {-# INLINE liftToEncoding #-}
1176+
1177+instance (ToJSON a) => ToJSON (Seq.Seq a) where
1178+ toJSON = toJSON1
1179+ {-# INLINE toJSON #-}
1180+
1181+ toEncoding = toEncoding1
1182+ {-# INLINE toEncoding #-}
1183+
1184+
1185+instance ToJSON1 Set.Set where
1186+ liftToJSON t _ = listValue t . Set.toList
1187+ {-# INLINE liftToJSON #-}
1188+
1189+ liftToEncoding t _ = listEncoding t . Set.toList
1190+ {-# INLINE liftToEncoding #-}
1191+
1192+instance (ToJSON a) => ToJSON (Set.Set a) where
1193+ toJSON = toJSON1
1194+ {-# INLINE toJSON #-}
1195+
1196+ toEncoding = toEncoding1
1197+ {-# INLINE toEncoding #-}
1198+
1199+
1200+instance ToJSON IntSet.IntSet where
1201+ toJSON = toJSON . IntSet.toList
1202+ {-# INLINE toJSON #-}
1203+
1204+ toEncoding = toEncoding . IntSet.toList
1205+ {-# INLINE toEncoding #-}
1206+
1207+
1208+instance ToJSON1 IntMap.IntMap where
1209+ liftToJSON t tol = liftToJSON to' tol' . IntMap.toList
1210+ where
1211+ to' = liftToJSON2 toJSON toJSONList t tol
1212+ tol' = liftToJSONList2 toJSON toJSONList t tol
1213+ {-# INLINE liftToJSON #-}
1214+
1215+ liftToEncoding t tol = liftToEncoding to' tol' . IntMap.toList
1216+ where
1217+ to' = liftToEncoding2 toEncoding toEncodingList t tol
1218+ tol' = liftToEncodingList2 toEncoding toEncodingList t tol
1219+ {-# INLINE liftToEncoding #-}
1220+
1221+instance ToJSON a => ToJSON (IntMap.IntMap a) where
1222+ toJSON = toJSON1
1223+ {-# INLINE toJSON #-}
1224+
1225+ toEncoding = toEncoding1
1226+ {-# INLINE toEncoding #-}
1227+
1228+
1229+instance ToJSONKey k => ToJSON1 (M.Map k) where
1230+ liftToJSON g _ = case toJSONKey of
1231+ ToJSONKeyText (f,_) -> Object . mapHashKeyVal f g
1232+ ToJSONKeyValue (f,_) -> Array . V.fromList . map (toJSONPair f g) . M.toList
1233+ {-# INLINE liftToJSON #-}
1234+
1235+ -- liftToEncoding :: forall a. (a -> Encoding) -> ([a] -> Encoding) -> M.Map k a -> Encoding
1236+ liftToEncoding g _ = case toJSONKey of
1237+ ToJSONKeyText (_,f) -> dict f g M.foldrWithKey
1238+ ToJSONKeyValue (_,f) -> listEncoding (pairEncoding f) . M.toList
1239+ where
1240+ -- pairEncoding :: (k -> Encoding) -> (k, a) -> Encoding
1241+ pairEncoding f (a, b) = tuple $ f a >*< g b
1242+ {-# INLINE liftToEncoding #-}
1243+
1244+
1245+instance (ToJSON v, ToJSONKey k) => ToJSON (M.Map k v) where
1246+ toJSON = toJSON1
1247+ {-# INLINE toJSON #-}
1248+
1249+ toEncoding = toEncoding1
1250+ {-# INLINE toEncoding #-}
1251+
1252+
1253+instance ToJSON1 Tree.Tree where
1254+ liftToJSON t tol = go
1255+ where
1256+ go (Tree.Node root branches) =
1257+ liftToJSON2 t tol to' tol' (root, branches)
1258+
1259+ to' = liftToJSON go (listValue go)
1260+ tol' = liftToJSONList go (listValue go)
1261+ {-# INLINE liftToJSON #-}
1262+
1263+ liftToEncoding t tol = go
1264+ where
1265+ go (Tree.Node root branches) =
1266+ liftToEncoding2 t tol to' tol' (root, branches)
1267+
1268+ to' = liftToEncoding go (listEncoding go)
1269+ tol' = liftToEncodingList go (listEncoding go)
1270+ {-# INLINE liftToEncoding #-}
1271+
1272+instance (ToJSON v) => ToJSON (Tree.Tree v) where
1273+ toJSON = toJSON1
1274+ {-# INLINE toJSON #-}
1275+
1276+ toEncoding = toEncoding1
1277+ {-# INLINE toEncoding #-}
1278+
1279+
1280+-------------------------------------------------------------------------------
1281+-- vector
1282+-------------------------------------------------------------------------------
1283+
1284+instance ToJSON1 Vector where
1285+ liftToJSON t _ = Array . V.map t
1286+ {-# INLINE liftToJSON #-}
1287+
1288+ liftToEncoding t _ xs
1289+ | V.null xs = emptyArray_
1290+ | otherwise = Encoding $
1291+ B.char7 '[' <> fromEncoding (t (V.unsafeHead xs)) <>
1292+ V.foldr go (B.char7 ']') (V.unsafeTail xs)
1293+ where
1294+ go v b = B.char7 ',' <> fromEncoding (t v) <> b
1295+ {-# INLINE liftToEncoding #-}
1296+
1297+instance (ToJSON a) => ToJSON (Vector a) where
1298+ toJSON = Array . V.map toJSON
1299+ {-# INLINE toJSON #-}
1300+
1301+ toEncoding = encodeVector
1302+ {-# INLINE toEncoding #-}
1303+
1304+encodeVector :: (ToJSON a, VG.Vector v a) => v a -> Encoding
1305+encodeVector xs
1306+ | VG.null xs = emptyArray_
1307+ | otherwise = Encoding $
1308+ B.char7 '[' <> builder (VG.unsafeHead xs) <>
1309+ VG.foldr go (B.char7 ']') (VG.unsafeTail xs)
1310+ where go v b = B.char7 ',' <> builder v <> b
1311+{-# INLINE encodeVector #-}
1312+
1313+vectorToJSON :: (VG.Vector v a, ToJSON a) => v a -> Value
1314+vectorToJSON = Array . V.map toJSON . V.convert
1315+{-# INLINE vectorToJSON #-}
1316+
1317+instance (Storable a, ToJSON a) => ToJSON (VS.Vector a) where
1318+ toJSON = vectorToJSON
1319+ {-# INLINE toJSON #-}
1320+
1321+ toEncoding = encodeVector
1322+ {-# INLINE toEncoding #-}
1323+
1324+
1325+instance (VP.Prim a, ToJSON a) => ToJSON (VP.Vector a) where
1326+ toJSON = vectorToJSON
1327+ {-# INLINE toJSON #-}
1328+
1329+ toEncoding = encodeVector
1330+ {-# INLINE toEncoding #-}
1331+
1332+
1333+instance (VG.Vector VU.Vector a, ToJSON a) => ToJSON (VU.Vector a) where
1334+ toJSON = vectorToJSON
1335+ {-# INLINE toJSON #-}
1336+
1337+ toEncoding = encodeVector
1338+ {-# INLINE toEncoding #-}
1339+
1340+-------------------------------------------------------------------------------
1341+-- unordered-containers
1342+-------------------------------------------------------------------------------
1343+
1344+instance ToJSON1 HashSet.HashSet where
1345+ liftToJSON t _ = listValue t . HashSet.toList
1346+ {-# INLINE liftToJSON #-}
1347+
1348+ liftToEncoding t _ = listEncoding t . HashSet.toList
1349+ {-# INLINE liftToEncoding #-}
1350+
1351+instance (ToJSON a) => ToJSON (HashSet.HashSet a) where
1352+ toJSON = toJSON1
1353+ {-# INLINE toJSON #-}
1354+
1355+ toEncoding = toEncoding1
1356+ {-# INLINE toEncoding #-}
1357+
1358+
1359+instance ToJSONKey k => ToJSON1 (H.HashMap k) where
1360+ liftToJSON g _ = case toJSONKey of
1361+ ToJSONKeyText (f,_) -> Object . mapKeyVal f g
1362+ ToJSONKeyValue (f,_) -> Array . V.fromList . map (toJSONPair f g) . H.toList
1363+ {-# INLINE liftToJSON #-}
1364+
1365+ -- liftToEncoding :: forall a. (a -> Encoding) -> ([a] -> Encoding) -> H.HashMap k a -> Encoding
1366+ liftToEncoding g _ = case toJSONKey of
1367+ ToJSONKeyText (_,f) -> dict f g H.foldrWithKey
1368+ ToJSONKeyValue (_,f) -> listEncoding (pairEncoding f) . H.toList
1369+ where
1370+ -- pairEncoding :: (k -> Encoding) -> (k, a) -> Encoding
1371+ pairEncoding f (a, b) = tuple $ f a >*< g b
1372+ {-# INLINE liftToEncoding #-}
1373+
1374+instance (ToJSON v, ToJSONKey k) => ToJSON (H.HashMap k v) where
1375+ toJSON = toJSON1
1376+ {-# INLINE toJSON #-}
1377+
1378+ toEncoding = toEncoding1
1379+ {-# INLINE toEncoding #-}
1380+
1381+-------------------------------------------------------------------------------
1382+-- aeson
1383+-------------------------------------------------------------------------------
1384+
1385+instance ToJSON Value where
1386+ toJSON a = a
1387+ {-# INLINE toJSON #-}
1388+
1389+ toEncoding = Encoding . EB.encodeToBuilder
1390+ {-# INLINE toEncoding #-}
1391+
1392+instance ToJSON DotNetTime where
1393+ toJSON = toJSON . dotNetTime
1394+
1395+ toEncoding = toEncoding . dotNetTime
1396+
1397+dotNetTime :: DotNetTime -> String
1398+dotNetTime (DotNetTime t) = secs ++ formatMillis t ++ ")/"
1399+ where secs = formatTime defaultTimeLocale "/Date(%s" t
1400+
1401+-------------------------------------------------------------------------------
1402+-- time
1403+-------------------------------------------------------------------------------
1404+
1405+instance ToJSON Day where
1406+ toJSON = stringEncoding
1407+ toEncoding z = Encoding (EB.quote $ EB.day z)
1408+
1409+
1410+instance ToJSON TimeOfDay where
1411+ toJSON = stringEncoding
1412+ toEncoding z = Encoding (EB.quote $ EB.timeOfDay z)
1413+
1414+
1415+instance ToJSON LocalTime where
1416+ toJSON = stringEncoding
1417+ toEncoding z = Encoding (EB.quote $ EB.localTime z)
1418+
1419+instance ToJSON ZonedTime where
1420+ toJSON = stringEncoding
1421+
1422+ toEncoding z = Encoding (EB.quote $ EB.zonedTime z)
1423+
1424+formatMillis :: (FormatTime t) => t -> String
1425+formatMillis = take 3 . formatTime defaultTimeLocale "%q"
1426+
1427+instance ToJSON UTCTime where
1428+ toJSON = stringEncoding
1429+
1430+ toEncoding t = Encoding (EB.quote $ EB.utcTime t)
1431+
1432+-- | Encode something t a JSON string.
1433+--
1434+-- TODO: remove me, this is a hack
1435+stringEncoding :: (ToJSON a) => a -> Value
1436+stringEncoding = String
1437+ . T.dropAround (== '"')
1438+ . T.decodeLatin1
1439+ . L.toStrict
1440+ . B.toLazyByteString
1441+ . fromEncoding
1442+ . toEncoding
1443+{-# INLINE stringEncoding #-}
1444+
1445+instance ToJSON NominalDiffTime where
1446+ toJSON = Number . realToFrac
1447+ {-# INLINE toJSON #-}
1448+
1449+ toEncoding = Encoding . EB.number . realToFrac
1450+ {-# INLINE toEncoding #-}
1451+
1452+-------------------------------------------------------------------------------
1453+-- base Monoid/Semigroup
1454+-------------------------------------------------------------------------------
1455+
1456+instance ToJSON1 Dual where
1457+ liftToJSON t _ = t . getDual
1458+ {-# INLINE liftToJSON #-}
1459+
1460+ liftToEncoding t _ = t . getDual
1461+ {-# INLINE liftToEncoding #-}
1462+
1463+instance ToJSON a => ToJSON (Dual a) where
1464+ toJSON = toJSON1
1465+ {-# INLINE toJSON #-}
1466+
1467+ toEncoding = toEncoding1
1468+ {-# INLINE toEncoding #-}
1469+
1470+
1471+instance ToJSON1 First where
1472+ liftToJSON t to' = liftToJSON t to' . getFirst
1473+ {-# INLINE liftToJSON #-}
1474+
1475+ liftToEncoding t to' = liftToEncoding t to' . getFirst
1476+ {-# INLINE liftToEncoding #-}
1477+
1478+instance ToJSON a => ToJSON (First a) where
1479+ toJSON = toJSON1
1480+ {-# INLINE toJSON #-}
1481+
1482+ toEncoding = toEncoding1
1483+ {-# INLINE toEncoding #-}
1484+
1485+
1486+instance ToJSON1 Last where
1487+ liftToJSON t to' = liftToJSON t to' . getLast
1488+ {-# INLINE liftToJSON #-}
1489+
1490+ liftToEncoding t to' = liftToEncoding t to' . getLast
1491+ {-# INLINE liftToEncoding #-}
1492+
1493+instance ToJSON a => ToJSON (Last a) where
1494+ toJSON = toJSON1
1495+ {-# INLINE toJSON #-}
1496+
1497+ toEncoding = toEncoding1
1498+ {-# INLINE toEncoding #-}
1499+
1500+-------------------------------------------------------------------------------
1501+-- tagged
1502+-------------------------------------------------------------------------------
1503+
1504+instance ToJSON (Proxy a) where
1505+ toJSON _ = Null
1506+ {-# INLINE toJSON #-}
1507+
1508+ toEncoding _ = Encoding EB.null_
1509+ {-# INLINE toEncoding #-}
1510+
1511+
1512+instance ToJSON1 (Tagged a) where
1513+ liftToJSON t _ (Tagged x) = t x
1514+ {-# INLINE liftToJSON #-}
1515+
1516+ liftToEncoding t _ (Tagged x) = t x
1517+ {-# INLINE liftToEncoding #-}
1518+
1519+instance ToJSON b => ToJSON (Tagged a b) where
1520+ toJSON = toJSON1
1521+ {-# INLINE toJSON #-}
1522+
1523+ toEncoding = toEncoding1
1524+ {-# INLINE toEncoding #-}
1525+
1526+
1527+instance ToJSONKey b => ToJSONKey (Tagged a b) where
1528+ toJSONKey = contramapToJSONKeyFunction unTagged toJSONKey
1529+ toJSONKeyList = contramapToJSONKeyFunction (fmap unTagged) toJSONKeyList
1530+
1531+-------------------------------------------------------------------------------
1532+-- Instances for converting t map keys
1533+-------------------------------------------------------------------------------
1534+
1535+instance ToJSONKey Text where
1536+ toJSONKey = ToJSONKeyText (id,toEncoding)
1537+
1538+
1539+instance ToJSONKey Bool where
1540+ toJSONKey = ToJSONKeyText
1541+ ( (\x -> if x then "true" else "false")
1542+ , (\x -> Encoding $ if x then "\"true\"" else "\"false\"")
1543+ )
1544+
1545+instance ToJSONKey Int where
1546+ toJSONKey = ToJSONKeyText
1547+ ( LT.toStrict . LTB.toLazyText . LTBI.decimal
1548+ , \x -> Encoding $ B.char7 '"' <> fromEncoding (toEncoding x) <> B.char7 '"'
1549+ )
1550+
1551+instance (ToJSON a, ToJSON b) => ToJSONKey (a,b)
1552+instance (ToJSON a, ToJSON b, ToJSON c) => ToJSONKey (a,b,c)
1553+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d) => ToJSONKey (a,b,c,d)
1554+
1555+instance ToJSONKey Char where
1556+ toJSONKey = ToJSONKeyText (T.singleton, toEncoding)
1557+ toJSONKeyList = ToJSONKeyText (T.pack, toEncoding . T.pack)
1558+
1559+instance (ToJSONKey a, ToJSON a) => ToJSONKey [a] where
1560+ toJSONKey = toJSONKeyList
1561+
1562+instance (ToJSONKey a, ToJSON a) => ToJSONKey (Identity a) where
1563+ toJSONKey = contramapToJSONKeyFunction runIdentity toJSONKey
1564+
1565+-------------------------------------------------------------------------------
1566+-- Tuple instances, see tuple-instances-to.hs
1567+-------------------------------------------------------------------------------
1568+
1569+instance ToJSON2 ((,) ) where
1570+ liftToJSON2 toA _ toB _ (a, b) = Array $ V.create $ do
1571+ mv <- VM.unsafeNew 2
1572+ VM.unsafeWrite mv 0 (toA a)
1573+ VM.unsafeWrite mv 1 (toB b)
1574+ return mv
1575+ {-# INLINE liftToJSON2 #-}
1576+
1577+ liftToEncoding2 toA _ toB _ (a, b) = tuple $
1578+ toA a >*<
1579+ toB b
1580+ {-# INLINE liftToEncoding2 #-}
1581+
1582+instance (ToJSON a) => ToJSON1 ((,) a) where
1583+ liftToJSON = liftToJSON2 toJSON toJSONList
1584+ {-# INLINE liftToJSON #-}
1585+ liftToEncoding = liftToEncoding2 toEncoding toEncodingList
1586+ {-# INLINE liftToEncoding #-}
1587+
1588+instance (ToJSON a, ToJSON b) => ToJSON (a, b) where
1589+ toJSON = toJSON2
1590+ {-# INLINE toJSON #-}
1591+ toEncoding = toEncoding2
1592+ {-# INLINE toEncoding #-}
1593+
1594+instance (ToJSON a) => ToJSON2 ((,,) a) where
1595+ liftToJSON2 toB _ toC _ (a, b, c) = Array $ V.create $ do
1596+ mv <- VM.unsafeNew 3
1597+ VM.unsafeWrite mv 0 (toJSON a)
1598+ VM.unsafeWrite mv 1 (toB b)
1599+ VM.unsafeWrite mv 2 (toC c)
1600+ return mv
1601+ {-# INLINE liftToJSON2 #-}
1602+
1603+ liftToEncoding2 toB _ toC _ (a, b, c) = tuple $
1604+ toEncoding a >*<
1605+ toB b >*<
1606+ toC c
1607+ {-# INLINE liftToEncoding2 #-}
1608+
1609+instance (ToJSON a, ToJSON b) => ToJSON1 ((,,) a b) where
1610+ liftToJSON = liftToJSON2 toJSON toJSONList
1611+ {-# INLINE liftToJSON #-}
1612+ liftToEncoding = liftToEncoding2 toEncoding toEncodingList
1613+ {-# INLINE liftToEncoding #-}
1614+
1615+instance (ToJSON a, ToJSON b, ToJSON c) => ToJSON (a, b, c) where
1616+ toJSON = toJSON2
1617+ {-# INLINE toJSON #-}
1618+ toEncoding = toEncoding2
1619+ {-# INLINE toEncoding #-}
1620+
1621+instance (ToJSON a, ToJSON b) => ToJSON2 ((,,,) a b) where
1622+ liftToJSON2 toC _ toD _ (a, b, c, d) = Array $ V.create $ do
1623+ mv <- VM.unsafeNew 4
1624+ VM.unsafeWrite mv 0 (toJSON a)
1625+ VM.unsafeWrite mv 1 (toJSON b)
1626+ VM.unsafeWrite mv 2 (toC c)
1627+ VM.unsafeWrite mv 3 (toD d)
1628+ return mv
1629+ {-# INLINE liftToJSON2 #-}
1630+
1631+ liftToEncoding2 toC _ toD _ (a, b, c, d) = tuple $
1632+ toEncoding a >*<
1633+ toEncoding b >*<
1634+ toC c >*<
1635+ toD d
1636+ {-# INLINE liftToEncoding2 #-}
1637+
1638+instance (ToJSON a, ToJSON b, ToJSON c) => ToJSON1 ((,,,) a b c) where
1639+ liftToJSON = liftToJSON2 toJSON toJSONList
1640+ {-# INLINE liftToJSON #-}
1641+ liftToEncoding = liftToEncoding2 toEncoding toEncodingList
1642+ {-# INLINE liftToEncoding #-}
1643+
1644+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d) => ToJSON (a, b, c, d) where
1645+ toJSON = toJSON2
1646+ {-# INLINE toJSON #-}
1647+ toEncoding = toEncoding2
1648+ {-# INLINE toEncoding #-}
1649+
1650+instance (ToJSON a, ToJSON b, ToJSON c) => ToJSON2 ((,,,,) a b c) where
1651+ liftToJSON2 toD _ toE _ (a, b, c, d, e) = Array $ V.create $ do
1652+ mv <- VM.unsafeNew 5
1653+ VM.unsafeWrite mv 0 (toJSON a)
1654+ VM.unsafeWrite mv 1 (toJSON b)
1655+ VM.unsafeWrite mv 2 (toJSON c)
1656+ VM.unsafeWrite mv 3 (toD d)
1657+ VM.unsafeWrite mv 4 (toE e)
1658+ return mv
1659+ {-# INLINE liftToJSON2 #-}
1660+
1661+ liftToEncoding2 toD _ toE _ (a, b, c, d, e) = tuple $
1662+ toEncoding a >*<
1663+ toEncoding b >*<
1664+ toEncoding c >*<
1665+ toD d >*<
1666+ toE e
1667+ {-# INLINE liftToEncoding2 #-}
1668+
1669+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d) => ToJSON1 ((,,,,) a b c d) where
1670+ liftToJSON = liftToJSON2 toJSON toJSONList
1671+ {-# INLINE liftToJSON #-}
1672+ liftToEncoding = liftToEncoding2 toEncoding toEncodingList
1673+ {-# INLINE liftToEncoding #-}
1674+
1675+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e) => ToJSON (a, b, c, d, e) where
1676+ toJSON = toJSON2
1677+ {-# INLINE toJSON #-}
1678+ toEncoding = toEncoding2
1679+ {-# INLINE toEncoding #-}
1680+
1681+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d) => ToJSON2 ((,,,,,) a b c d) where
1682+ liftToJSON2 toE _ toF _ (a, b, c, d, e, f) = Array $ V.create $ do
1683+ mv <- VM.unsafeNew 6
1684+ VM.unsafeWrite mv 0 (toJSON a)
1685+ VM.unsafeWrite mv 1 (toJSON b)
1686+ VM.unsafeWrite mv 2 (toJSON c)
1687+ VM.unsafeWrite mv 3 (toJSON d)
1688+ VM.unsafeWrite mv 4 (toE e)
1689+ VM.unsafeWrite mv 5 (toF f)
1690+ return mv
1691+ {-# INLINE liftToJSON2 #-}
1692+
1693+ liftToEncoding2 toE _ toF _ (a, b, c, d, e, f) = tuple $
1694+ toEncoding a >*<
1695+ toEncoding b >*<
1696+ toEncoding c >*<
1697+ toEncoding d >*<
1698+ toE e >*<
1699+ toF f
1700+ {-# INLINE liftToEncoding2 #-}
1701+
1702+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e) => ToJSON1 ((,,,,,) a b c d e) where
1703+ liftToJSON = liftToJSON2 toJSON toJSONList
1704+ {-# INLINE liftToJSON #-}
1705+ liftToEncoding = liftToEncoding2 toEncoding toEncodingList
1706+ {-# INLINE liftToEncoding #-}
1707+
1708+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f) => ToJSON (a, b, c, d, e, f) where
1709+ toJSON = toJSON2
1710+ {-# INLINE toJSON #-}
1711+ toEncoding = toEncoding2
1712+ {-# INLINE toEncoding #-}
1713+
1714+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e) => ToJSON2 ((,,,,,,) a b c d e) where
1715+ liftToJSON2 toF _ toG _ (a, b, c, d, e, f, g) = Array $ V.create $ do
1716+ mv <- VM.unsafeNew 7
1717+ VM.unsafeWrite mv 0 (toJSON a)
1718+ VM.unsafeWrite mv 1 (toJSON b)
1719+ VM.unsafeWrite mv 2 (toJSON c)
1720+ VM.unsafeWrite mv 3 (toJSON d)
1721+ VM.unsafeWrite mv 4 (toJSON e)
1722+ VM.unsafeWrite mv 5 (toF f)
1723+ VM.unsafeWrite mv 6 (toG g)
1724+ return mv
1725+ {-# INLINE liftToJSON2 #-}
1726+
1727+ liftToEncoding2 toF _ toG _ (a, b, c, d, e, f, g) = tuple $
1728+ toEncoding a >*<
1729+ toEncoding b >*<
1730+ toEncoding c >*<
1731+ toEncoding d >*<
1732+ toEncoding e >*<
1733+ toF f >*<
1734+ toG g
1735+ {-# INLINE liftToEncoding2 #-}
1736+
1737+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f) => ToJSON1 ((,,,,,,) a b c d e f) where
1738+ liftToJSON = liftToJSON2 toJSON toJSONList
1739+ {-# INLINE liftToJSON #-}
1740+ liftToEncoding = liftToEncoding2 toEncoding toEncodingList
1741+ {-# INLINE liftToEncoding #-}
1742+
1743+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g) => ToJSON (a, b, c, d, e, f, g) where
1744+ toJSON = toJSON2
1745+ {-# INLINE toJSON #-}
1746+ toEncoding = toEncoding2
1747+ {-# INLINE toEncoding #-}
1748+
1749+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f) => ToJSON2 ((,,,,,,,) a b c d e f) where
1750+ liftToJSON2 toG _ toH _ (a, b, c, d, e, f, g, h) = Array $ V.create $ do
1751+ mv <- VM.unsafeNew 8
1752+ VM.unsafeWrite mv 0 (toJSON a)
1753+ VM.unsafeWrite mv 1 (toJSON b)
1754+ VM.unsafeWrite mv 2 (toJSON c)
1755+ VM.unsafeWrite mv 3 (toJSON d)
1756+ VM.unsafeWrite mv 4 (toJSON e)
1757+ VM.unsafeWrite mv 5 (toJSON f)
1758+ VM.unsafeWrite mv 6 (toG g)
1759+ VM.unsafeWrite mv 7 (toH h)
1760+ return mv
1761+ {-# INLINE liftToJSON2 #-}
1762+
1763+ liftToEncoding2 toG _ toH _ (a, b, c, d, e, f, g, h) = tuple $
1764+ toEncoding a >*<
1765+ toEncoding b >*<
1766+ toEncoding c >*<
1767+ toEncoding d >*<
1768+ toEncoding e >*<
1769+ toEncoding f >*<
1770+ toG g >*<
1771+ toH h
1772+ {-# INLINE liftToEncoding2 #-}
1773+
1774+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g) => ToJSON1 ((,,,,,,,) a b c d e f g) where
1775+ liftToJSON = liftToJSON2 toJSON toJSONList
1776+ {-# INLINE liftToJSON #-}
1777+ liftToEncoding = liftToEncoding2 toEncoding toEncodingList
1778+ {-# INLINE liftToEncoding #-}
1779+
1780+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h) => ToJSON (a, b, c, d, e, f, g, h) where
1781+ toJSON = toJSON2
1782+ {-# INLINE toJSON #-}
1783+ toEncoding = toEncoding2
1784+ {-# INLINE toEncoding #-}
1785+
1786+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g) => ToJSON2 ((,,,,,,,,) a b c d e f g) where
1787+ liftToJSON2 toH _ toI _ (a, b, c, d, e, f, g, h, i) = Array $ V.create $ do
1788+ mv <- VM.unsafeNew 9
1789+ VM.unsafeWrite mv 0 (toJSON a)
1790+ VM.unsafeWrite mv 1 (toJSON b)
1791+ VM.unsafeWrite mv 2 (toJSON c)
1792+ VM.unsafeWrite mv 3 (toJSON d)
1793+ VM.unsafeWrite mv 4 (toJSON e)
1794+ VM.unsafeWrite mv 5 (toJSON f)
1795+ VM.unsafeWrite mv 6 (toJSON g)
1796+ VM.unsafeWrite mv 7 (toH h)
1797+ VM.unsafeWrite mv 8 (toI i)
1798+ return mv
1799+ {-# INLINE liftToJSON2 #-}
1800+
1801+ liftToEncoding2 toH _ toI _ (a, b, c, d, e, f, g, h, i) = tuple $
1802+ toEncoding a >*<
1803+ toEncoding b >*<
1804+ toEncoding c >*<
1805+ toEncoding d >*<
1806+ toEncoding e >*<
1807+ toEncoding f >*<
1808+ toEncoding g >*<
1809+ toH h >*<
1810+ toI i
1811+ {-# INLINE liftToEncoding2 #-}
1812+
1813+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h) => ToJSON1 ((,,,,,,,,) a b c d e f g h) where
1814+ liftToJSON = liftToJSON2 toJSON toJSONList
1815+ {-# INLINE liftToJSON #-}
1816+ liftToEncoding = liftToEncoding2 toEncoding toEncodingList
1817+ {-# INLINE liftToEncoding #-}
1818+
1819+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i) => ToJSON (a, b, c, d, e, f, g, h, i) where
1820+ toJSON = toJSON2
1821+ {-# INLINE toJSON #-}
1822+ toEncoding = toEncoding2
1823+ {-# INLINE toEncoding #-}
1824+
1825+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h) => ToJSON2 ((,,,,,,,,,) a b c d e f g h) where
1826+ liftToJSON2 toI _ toJ _ (a, b, c, d, e, f, g, h, i, j) = Array $ V.create $ do
1827+ mv <- VM.unsafeNew 10
1828+ VM.unsafeWrite mv 0 (toJSON a)
1829+ VM.unsafeWrite mv 1 (toJSON b)
1830+ VM.unsafeWrite mv 2 (toJSON c)
1831+ VM.unsafeWrite mv 3 (toJSON d)
1832+ VM.unsafeWrite mv 4 (toJSON e)
1833+ VM.unsafeWrite mv 5 (toJSON f)
1834+ VM.unsafeWrite mv 6 (toJSON g)
1835+ VM.unsafeWrite mv 7 (toJSON h)
1836+ VM.unsafeWrite mv 8 (toI i)
1837+ VM.unsafeWrite mv 9 (toJ j)
1838+ return mv
1839+ {-# INLINE liftToJSON2 #-}
1840+
1841+ liftToEncoding2 toI _ toJ _ (a, b, c, d, e, f, g, h, i, j) = tuple $
1842+ toEncoding a >*<
1843+ toEncoding b >*<
1844+ toEncoding c >*<
1845+ toEncoding d >*<
1846+ toEncoding e >*<
1847+ toEncoding f >*<
1848+ toEncoding g >*<
1849+ toEncoding h >*<
1850+ toI i >*<
1851+ toJ j
1852+ {-# INLINE liftToEncoding2 #-}
1853+
1854+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i) => ToJSON1 ((,,,,,,,,,) a b c d e f g h i) where
1855+ liftToJSON = liftToJSON2 toJSON toJSONList
1856+ {-# INLINE liftToJSON #-}
1857+ liftToEncoding = liftToEncoding2 toEncoding toEncodingList
1858+ {-# INLINE liftToEncoding #-}
1859+
1860+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j) => ToJSON (a, b, c, d, e, f, g, h, i, j) where
1861+ toJSON = toJSON2
1862+ {-# INLINE toJSON #-}
1863+ toEncoding = toEncoding2
1864+ {-# INLINE toEncoding #-}
1865+
1866+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i) => ToJSON2 ((,,,,,,,,,,) a b c d e f g h i) where
1867+ liftToJSON2 toJ _ toK _ (a, b, c, d, e, f, g, h, i, j, k) = Array $ V.create $ do
1868+ mv <- VM.unsafeNew 11
1869+ VM.unsafeWrite mv 0 (toJSON a)
1870+ VM.unsafeWrite mv 1 (toJSON b)
1871+ VM.unsafeWrite mv 2 (toJSON c)
1872+ VM.unsafeWrite mv 3 (toJSON d)
1873+ VM.unsafeWrite mv 4 (toJSON e)
1874+ VM.unsafeWrite mv 5 (toJSON f)
1875+ VM.unsafeWrite mv 6 (toJSON g)
1876+ VM.unsafeWrite mv 7 (toJSON h)
1877+ VM.unsafeWrite mv 8 (toJSON i)
1878+ VM.unsafeWrite mv 9 (toJ j)
1879+ VM.unsafeWrite mv 10 (toK k)
1880+ return mv
1881+ {-# INLINE liftToJSON2 #-}
1882+
1883+ liftToEncoding2 toJ _ toK _ (a, b, c, d, e, f, g, h, i, j, k) = tuple $
1884+ toEncoding a >*<
1885+ toEncoding b >*<
1886+ toEncoding c >*<
1887+ toEncoding d >*<
1888+ toEncoding e >*<
1889+ toEncoding f >*<
1890+ toEncoding g >*<
1891+ toEncoding h >*<
1892+ toEncoding i >*<
1893+ toJ j >*<
1894+ toK k
1895+ {-# INLINE liftToEncoding2 #-}
1896+
1897+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j) => ToJSON1 ((,,,,,,,,,,) a b c d e f g h i j) where
1898+ liftToJSON = liftToJSON2 toJSON toJSONList
1899+ {-# INLINE liftToJSON #-}
1900+ liftToEncoding = liftToEncoding2 toEncoding toEncodingList
1901+ {-# INLINE liftToEncoding #-}
1902+
1903+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k) => ToJSON (a, b, c, d, e, f, g, h, i, j, k) where
1904+ toJSON = toJSON2
1905+ {-# INLINE toJSON #-}
1906+ toEncoding = toEncoding2
1907+ {-# INLINE toEncoding #-}
1908+
1909+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j) => ToJSON2 ((,,,,,,,,,,,) a b c d e f g h i j) where
1910+ liftToJSON2 toK _ toL _ (a, b, c, d, e, f, g, h, i, j, k, l) = Array $ V.create $ do
1911+ mv <- VM.unsafeNew 12
1912+ VM.unsafeWrite mv 0 (toJSON a)
1913+ VM.unsafeWrite mv 1 (toJSON b)
1914+ VM.unsafeWrite mv 2 (toJSON c)
1915+ VM.unsafeWrite mv 3 (toJSON d)
1916+ VM.unsafeWrite mv 4 (toJSON e)
1917+ VM.unsafeWrite mv 5 (toJSON f)
1918+ VM.unsafeWrite mv 6 (toJSON g)
1919+ VM.unsafeWrite mv 7 (toJSON h)
1920+ VM.unsafeWrite mv 8 (toJSON i)
1921+ VM.unsafeWrite mv 9 (toJSON j)
1922+ VM.unsafeWrite mv 10 (toK k)
1923+ VM.unsafeWrite mv 11 (toL l)
1924+ return mv
1925+ {-# INLINE liftToJSON2 #-}
1926+
1927+ liftToEncoding2 toK _ toL _ (a, b, c, d, e, f, g, h, i, j, k, l) = tuple $
1928+ toEncoding a >*<
1929+ toEncoding b >*<
1930+ toEncoding c >*<
1931+ toEncoding d >*<
1932+ toEncoding e >*<
1933+ toEncoding f >*<
1934+ toEncoding g >*<
1935+ toEncoding h >*<
1936+ toEncoding i >*<
1937+ toEncoding j >*<
1938+ toK k >*<
1939+ toL l
1940+ {-# INLINE liftToEncoding2 #-}
1941+
1942+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k) => ToJSON1 ((,,,,,,,,,,,) a b c d e f g h i j k) where
1943+ liftToJSON = liftToJSON2 toJSON toJSONList
1944+ {-# INLINE liftToJSON #-}
1945+ liftToEncoding = liftToEncoding2 toEncoding toEncodingList
1946+ {-# INLINE liftToEncoding #-}
1947+
1948+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k, ToJSON l) => ToJSON (a, b, c, d, e, f, g, h, i, j, k, l) where
1949+ toJSON = toJSON2
1950+ {-# INLINE toJSON #-}
1951+ toEncoding = toEncoding2
1952+ {-# INLINE toEncoding #-}
1953+
1954+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k) => ToJSON2 ((,,,,,,,,,,,,) a b c d e f g h i j k) where
1955+ liftToJSON2 toL _ toM _ (a, b, c, d, e, f, g, h, i, j, k, l, m) = Array $ V.create $ do
1956+ mv <- VM.unsafeNew 13
1957+ VM.unsafeWrite mv 0 (toJSON a)
1958+ VM.unsafeWrite mv 1 (toJSON b)
1959+ VM.unsafeWrite mv 2 (toJSON c)
1960+ VM.unsafeWrite mv 3 (toJSON d)
1961+ VM.unsafeWrite mv 4 (toJSON e)
1962+ VM.unsafeWrite mv 5 (toJSON f)
1963+ VM.unsafeWrite mv 6 (toJSON g)
1964+ VM.unsafeWrite mv 7 (toJSON h)
1965+ VM.unsafeWrite mv 8 (toJSON i)
1966+ VM.unsafeWrite mv 9 (toJSON j)
1967+ VM.unsafeWrite mv 10 (toJSON k)
1968+ VM.unsafeWrite mv 11 (toL l)
1969+ VM.unsafeWrite mv 12 (toM m)
1970+ return mv
1971+ {-# INLINE liftToJSON2 #-}
1972+
1973+ liftToEncoding2 toL _ toM _ (a, b, c, d, e, f, g, h, i, j, k, l, m) = tuple $
1974+ toEncoding a >*<
1975+ toEncoding b >*<
1976+ toEncoding c >*<
1977+ toEncoding d >*<
1978+ toEncoding e >*<
1979+ toEncoding f >*<
1980+ toEncoding g >*<
1981+ toEncoding h >*<
1982+ toEncoding i >*<
1983+ toEncoding j >*<
1984+ toEncoding k >*<
1985+ toL l >*<
1986+ toM m
1987+ {-# INLINE liftToEncoding2 #-}
1988+
1989+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k, ToJSON l) => ToJSON1 ((,,,,,,,,,,,,) a b c d e f g h i j k l) where
1990+ liftToJSON = liftToJSON2 toJSON toJSONList
1991+ {-# INLINE liftToJSON #-}
1992+ liftToEncoding = liftToEncoding2 toEncoding toEncodingList
1993+ {-# INLINE liftToEncoding #-}
1994+
1995+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k, ToJSON l, ToJSON m) => ToJSON (a, b, c, d, e, f, g, h, i, j, k, l, m) where
1996+ toJSON = toJSON2
1997+ {-# INLINE toJSON #-}
1998+ toEncoding = toEncoding2
1999+ {-# INLINE toEncoding #-}
2000+
2001+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k, ToJSON l) => ToJSON2 ((,,,,,,,,,,,,,) a b c d e f g h i j k l) where
2002+ liftToJSON2 toM _ toN _ (a, b, c, d, e, f, g, h, i, j, k, l, m, n) = Array $ V.create $ do
2003+ mv <- VM.unsafeNew 14
2004+ VM.unsafeWrite mv 0 (toJSON a)
2005+ VM.unsafeWrite mv 1 (toJSON b)
2006+ VM.unsafeWrite mv 2 (toJSON c)
2007+ VM.unsafeWrite mv 3 (toJSON d)
2008+ VM.unsafeWrite mv 4 (toJSON e)
2009+ VM.unsafeWrite mv 5 (toJSON f)
2010+ VM.unsafeWrite mv 6 (toJSON g)
2011+ VM.unsafeWrite mv 7 (toJSON h)
2012+ VM.unsafeWrite mv 8 (toJSON i)
2013+ VM.unsafeWrite mv 9 (toJSON j)
2014+ VM.unsafeWrite mv 10 (toJSON k)
2015+ VM.unsafeWrite mv 11 (toJSON l)
2016+ VM.unsafeWrite mv 12 (toM m)
2017+ VM.unsafeWrite mv 13 (toN n)
2018+ return mv
2019+ {-# INLINE liftToJSON2 #-}
2020+
2021+ liftToEncoding2 toM _ toN _ (a, b, c, d, e, f, g, h, i, j, k, l, m, n) = tuple $
2022+ toEncoding a >*<
2023+ toEncoding b >*<
2024+ toEncoding c >*<
2025+ toEncoding d >*<
2026+ toEncoding e >*<
2027+ toEncoding f >*<
2028+ toEncoding g >*<
2029+ toEncoding h >*<
2030+ toEncoding i >*<
2031+ toEncoding j >*<
2032+ toEncoding k >*<
2033+ toEncoding l >*<
2034+ toM m >*<
2035+ toN n
2036+ {-# INLINE liftToEncoding2 #-}
2037+
2038+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k, ToJSON l, ToJSON m) => ToJSON1 ((,,,,,,,,,,,,,) a b c d e f g h i j k l m) where
2039+ liftToJSON = liftToJSON2 toJSON toJSONList
2040+ {-# INLINE liftToJSON #-}
2041+ liftToEncoding = liftToEncoding2 toEncoding toEncodingList
2042+ {-# INLINE liftToEncoding #-}
2043+
2044+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k, ToJSON l, ToJSON m, ToJSON n) => ToJSON (a, b, c, d, e, f, g, h, i, j, k, l, m, n) where
2045+ toJSON = toJSON2
2046+ {-# INLINE toJSON #-}
2047+ toEncoding = toEncoding2
2048+ {-# INLINE toEncoding #-}
2049+
2050+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k, ToJSON l, ToJSON m) => ToJSON2 ((,,,,,,,,,,,,,,) a b c d e f g h i j k l m) where
2051+ liftToJSON2 toN _ toO _ (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) = Array $ V.create $ do
2052+ mv <- VM.unsafeNew 15
2053+ VM.unsafeWrite mv 0 (toJSON a)
2054+ VM.unsafeWrite mv 1 (toJSON b)
2055+ VM.unsafeWrite mv 2 (toJSON c)
2056+ VM.unsafeWrite mv 3 (toJSON d)
2057+ VM.unsafeWrite mv 4 (toJSON e)
2058+ VM.unsafeWrite mv 5 (toJSON f)
2059+ VM.unsafeWrite mv 6 (toJSON g)
2060+ VM.unsafeWrite mv 7 (toJSON h)
2061+ VM.unsafeWrite mv 8 (toJSON i)
2062+ VM.unsafeWrite mv 9 (toJSON j)
2063+ VM.unsafeWrite mv 10 (toJSON k)
2064+ VM.unsafeWrite mv 11 (toJSON l)
2065+ VM.unsafeWrite mv 12 (toJSON m)
2066+ VM.unsafeWrite mv 13 (toN n)
2067+ VM.unsafeWrite mv 14 (toO o)
2068+ return mv
2069+ {-# INLINE liftToJSON2 #-}
2070+
2071+ liftToEncoding2 toN _ toO _ (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) = tuple $
2072+ toEncoding a >*<
2073+ toEncoding b >*<
2074+ toEncoding c >*<
2075+ toEncoding d >*<
2076+ toEncoding e >*<
2077+ toEncoding f >*<
2078+ toEncoding g >*<
2079+ toEncoding h >*<
2080+ toEncoding i >*<
2081+ toEncoding j >*<
2082+ toEncoding k >*<
2083+ toEncoding l >*<
2084+ toEncoding m >*<
2085+ toN n >*<
2086+ toO o
2087+ {-# INLINE liftToEncoding2 #-}
2088+
2089+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k, ToJSON l, ToJSON m, ToJSON n) => ToJSON1 ((,,,,,,,,,,,,,,) a b c d e f g h i j k l m n) where
2090+ liftToJSON = liftToJSON2 toJSON toJSONList
2091+ {-# INLINE liftToJSON #-}
2092+ liftToEncoding = liftToEncoding2 toEncoding toEncodingList
2093+ {-# INLINE liftToEncoding #-}
2094+
2095+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g, ToJSON h, ToJSON i, ToJSON j, ToJSON k, ToJSON l, ToJSON m, ToJSON n, ToJSON o) => ToJSON (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) where
2096+ toJSON = toJSON2
2097+ {-# INLINE toJSON #-}
2098+ toEncoding = toEncoding2
2099+ {-# INLINE toEncoding #-}
aeson.cabal+5−4
@@ -80,19 +80,20 @@ library
8080
8181 other-modules:
8282 Data.Aeson.Encode.Builder
83− Data.Aeson.Encode.Functions
8483 Data.Aeson.Functions
8584 Data.Aeson.Parser.Internal
8685 Data.Aeson.Parser.Time
87− Data.Aeson.Types.Class
86+ Data.Aeson.Types.FromJSON
8887 Data.Aeson.Types.Generic
89− Data.Aeson.Types.Instances
90− Data.Aeson.Types.Instances.Tuple
88+ Data.Aeson.Types.ToJSON
89+ Data.Aeson.Types.Class
9190 Data.Aeson.Types.Internal
9291
9392 build-depends:
9493 attoparsec >= 0.13.0.1,
9594 base >= 4.5 && < 5,
95+ base-compat >= 0.9.1 && <0.10,
96+ time-locale-compat >=0.1.1 && <0.2,
9697 bytestring >= 0.10.4.0,
9798 containers,
9899 deepseq,
benchmarks/aeson-benchmarks.cabal+11−9
@@ -15,28 +15,30 @@ library
1515
1616 exposed-modules:
1717 Data.Aeson
18+ Data.Aeson.Encode
1819 Data.Aeson.Encoding
1920 Data.Aeson.Encoding.Internal
20− Data.Aeson.Encode
21− Data.Aeson.Encode.Builder
22− Data.Aeson.Encode.Functions
23− Data.Aeson.Functions
2421 Data.Aeson.Internal
2522 Data.Aeson.Internal.Time
2623 Data.Aeson.Parser
24+ Data.Aeson.Types
25+ Data.Aeson.TH
26+
27+ Data.Aeson.Encode.Builder
28+ Data.Aeson.Functions
2729 Data.Aeson.Parser.Internal
2830 Data.Aeson.Parser.Time
29− Data.Aeson.TH
30− Data.Aeson.Types
31− Data.Aeson.Types.Class
31+ Data.Aeson.Types.FromJSON
3232 Data.Aeson.Types.Generic
33− Data.Aeson.Types.Instances
33+ Data.Aeson.Types.ToJSON
34+ Data.Aeson.Types.Class
3435 Data.Aeson.Types.Internal
35− Data.Aeson.Types.Instances.Tuple
3636
3737 build-depends:
3838 attoparsec >= 0.13.0.1,
3939 base == 4.*,
40+ base-compat >= 0.9.1 && <0.10,
41+ time-locale-compat >=0.1.1 && <0.2,
4042 bytestring >= 0.10.4.0,
4143 containers,
4244 deepseq,
tuple-instances.hsdeleted−126
@@ -1,126 +0,0 @@
1−#!/usr/bin/env stack
2−{- stack --resolver=lts-6.0 runghc
3− --package mtl
4− --package dlist
5−-}
6−
7−import Control.Monad (forM_)
8−import Control.Monad.State.Strict
9−import Control.Monad.Writer (MonadWriter (..))
10−import Data.Char (toUpper)
11−import Data.Foldable (fold, traverse_)
12−import Data.List (intercalate)
13−import Data.Semigroup ((<>))
14−
15−import qualified Data.DList as DList
16−
17−variables :: [String]
18−variables = map (:[]) $ ['a'..'z']
19−
20−t :: [String] -> State (DList.DList String) ()
21−t xs = traverse_ f xs *> f "\n"
22− where
23− f :: String -> State (DList.DList String) ()
24− f x = state (\s -> ((), mappend s $ DList.singleton x))
25−
26−commaSep :: [String] -> String
27−commaSep vs = "(" <> intercalate ", " vs <> ")"
28−
29−tuple :: Int -> String
30−tuple n = fold $ flip execState DList.empty $ do
31− -- ToJSON2
32− t ["instance ", toJsonContext2, "ToJSON2 (", tupleConstr, " ", vs2, ") where" ]
33− t [" liftToJSON2 ", toPrev, " _ ", toLast, " _ ", vs', " = Array $ V.create $ do" ]
34− t [" mv <- VM.unsafeNew ", show n ]
35− forM_ (zip [0..] vs) $ \(i, v) ->
36− let to = case i of
37− _ | i == n - 1 -> toLast
38− | i == n - 2 -> toPrev
39− | otherwise -> "toJSON"
40− in t [ " VM.unsafeWrite mv ", show i, " (", to, " ", v, ")" ]
41− t [" return mv" ]
42− t [" {-# INLINE liftToJSON2 #-}" ]
43− t []
44−
45− t [" liftToEncoding2 ", toPrev, " _ ", toLast, " _ ", vs', " = tuple $" ]
46− forM_ (zip [0..] vs) $ \(i, v) -> t . (" " :) $ case i of
47−
48− _ | i == n - 1 -> [ toLast, " ", v ]
49− _ | i == n - 2 -> [ toPrev, " ", v, " >*<" ]
50− _ | otherwise -> [ "toEncoding ", v, " >*<" ]
51− t [" {-# INLINE liftToEncoding2 #-}" ]
52− t []
53−
54− -- ToJSON1
55− t ["instance ", toJsonContext1, "ToJSON1 (", tupleConstr, " ", vs1, ") where" ]
56− t [" liftToJSON = liftToJSON2 toJSON toJSONList" ]
57− t [" {-# INLINE liftToJSON #-}" ]
58− t [" liftToEncoding = liftToEncoding2 toEncoding toEncodingList" ]
59− t [" {-# INLINE liftToEncoding #-}" ]
60− t []
61−
62− -- ToJSON
63− t [ "instance ", toJsonContext, " => ToJSON ", vs', " where" ]
64− t [ " toJSON = toJSON2" ]
65− t [ " {-# INLINE toJSON #-}" ]
66− t [ " toEncoding = toEncoding2" ]
67− t [ " {-# INLINE toEncoding #-}" ]
68− t []
69−
70− -- FromJSON2
71− t ["instance ", fromJsonContext2, "FromJSON2 (", tupleConstr, " ", vs2, ") where" ]
72− t [" liftParseJSON2 ", pPrev, " _ ", pLast, " _ = withArray \"", vs', "\" $ \\t -> " ]
73− t [" let n = V.length t" ]
74− t [" in if n == ", show n ]
75− t [" then ", tupleConstr ]
76− forM_ (zip [0..] vs) $ \(i, v) -> do
77− let op = if i == 0 then "<$>" else "<*>"
78− let p = case i of
79− _ | i == n - 1 -> pLast
80− | i == n - 2 -> pPrev
81− | otherwise -> "parseJSON"
82− t [" ", op, " parseJSONElemAtIndex ", p, " ", show i, " t" ]
83− t [" else fail $ \"cannot unpack array of length \" ++ show n ++ \" into a tuple of length ", show n, "\"" ]
84− t [" {-# INLINE liftParseJSON2 #-}" ]
85− t []
86−
87− -- FromJSON1
88− t ["instance ", fromJsonContext1, "FromJSON1 (", tupleConstr, " ", vs1, ") where" ]
89− t [" liftParseJSON = liftParseJSON2 parseJSON parseJSONList" ]
90− t [" {-# INLINE liftParseJSON #-}" ]
91− t []
92−
93− -- FeomJSON
94− t [ "instance ", fromJsonContext, " => FromJSON ", vs', " where" ]
95− t [ " parseJSON = parseJSON2" ]
96− t [ " {-# INLINE parseJSON #-}" ]
97− t []
98−
99− t []
100− where
101− vs = take n variables
102− vs' = commaSep vs
103− toJsonContext = commaSep $ map ("ToJSON " <>) vs
104− fromJsonContext = commaSep $ map ("FromJSON " <>) vs
105−
106− toJsonContext2
107− | n <= 2 = ""
108− | otherwise = (commaSep $ map ("ToJSON " <>) $ take (n - 2) vs) <> " => "
109− fromJsonContext2
110− | n <= 2 = ""
111− | otherwise = (commaSep $ map ("FromJSON " <>) $ take (n - 2) vs) <> " => "
112− vs2 = intercalate " " $ take (n - 2) vs
113−
114− toJsonContext1 = (commaSep $ map ("ToJSON " <>) $ take (n - 1) vs) <> " => "
115− fromJsonContext1 = (commaSep $ map ("FromJSON " <>) $ take (n - 1) vs) <> " => "
116− vs1 = intercalate " " $ take (n - 1) vs
117−
118− toLast = "to" <> map toUpper (vs !! (n - 1))
119− toPrev = "to" <> map toUpper (vs !! (n - 2))
120− pLast = "p" <> map toUpper (vs !! (n - 1))
121− pPrev = "p" <> map toUpper (vs !! (n - 2))
122−
123− tupleConstr = "(" <> intercalate "," (replicate n "") <> ")"
124−
125−main :: IO ()
126−main = forM_ [2..15] $ putStr . tuple