-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | aeson instances for 'NonEmpty' -- -- aeson instances for NonEmpty. @package nonempty-wrapper-aeson @version 0.1.0.0 -- | aeson instances for NonEmpty module Data.Aeson.Types.Instances.NonEmpty -- | A type that can be converted from JSON, with the possibility of -- failure. -- -- In many cases, you can get the compiler to generate parsing code for -- you (see below). To begin, let's cover writing an instance by hand. -- -- There are various reasons a conversion could fail. For example, an -- Object could be missing a required key, an Array could -- be of the wrong size, or a value could be of an incompatible type. -- -- The basic ways to signal a failed conversion are as follows: -- --
-- -- Allow ourselves to write Text literals.
-- {-# LANGUAGE OverloadedStrings #-}
--
-- data Coord = Coord { x :: Double, y :: Double }
--
-- instance FromJSON Coord where
-- parseJSON (Object v) = Coord
-- <$> v .: "x"
-- <*> v .: "y"
--
-- -- We do not expect a non-Object value here.
-- -- We could use empty to fail, but typeMismatch
-- -- gives a much more informative error message.
-- parseJSON invalid =
-- prependFailure "parsing Coord failed, "
-- (typeMismatch "Object" invalid)
--
--
-- For this common case of only being concerned with a single type of
-- JSON value, the functions withObject, withScientific,
-- etc. are provided. Their use is to be preferred when possible, since
-- they are more terse. Using withObject, we can rewrite the above
-- instance (assuming the same language extension and data type) as:
--
-- -- instance FromJSON Coord where -- parseJSON = withObject "Coord" $ \v -> Coord -- <$> v .: "x" -- <*> v .: "y" ---- -- Instead of manually writing your FromJSON instance, there are -- two options to do it automatically: -- --
-- {-# LANGUAGE DeriveGeneric #-}
--
-- import GHC.Generics
--
-- data Coord = Coord { x :: Double, y :: Double } deriving Generic
--
-- instance FromJSON Coord
--
--
-- or using the DerivingVia extension
--
-- -- deriving via Generically Coord instance FromJSON Coord ---- -- The default implementation will be equivalent to parseJSON = -- genericParseJSON defaultOptions; if you need -- different options, you can customize the generic decoding by defining: -- --
-- customOptions = defaultOptions
-- { fieldLabelModifier = map toUpper
-- }
--
-- instance FromJSON Coord where
-- parseJSON = genericParseJSON customOptions
--
class FromJSON a
parseJSON :: FromJSON a => Value -> Parser a
parseJSONList :: FromJSON a => Value -> Parser [a]
-- | A type that can be converted to JSON.
--
-- Instances in general must specify toJSON and
-- should (but don't need to) specify toEncoding.
--
-- An example type and instance:
--
--
-- -- Allow ourselves to write Text literals.
-- {-# LANGUAGE OverloadedStrings #-}
--
-- data Coord = Coord { x :: Double, y :: Double }
--
-- instance ToJSON Coord where
-- toJSON (Coord x y) = object ["x" .= x, "y" .= y]
--
-- toEncoding (Coord x y) = pairs ("x" .= x <> "y" .= y)
--
--
-- Instead of manually writing your ToJSON instance, there are two
-- options to do it automatically:
--
--
-- {-# LANGUAGE DeriveGeneric #-}
--
-- import GHC.Generics
--
-- data Coord = Coord { x :: Double, y :: Double } deriving Generic
--
-- instance ToJSON Coord where
-- toEncoding = genericToEncoding defaultOptions
--
--
-- or more conveniently using the DerivingVia extension
--
-- -- deriving via Generically Coord instance ToJSON Coord ---- -- If on the other hand you wish to customize the generic decoding, you -- have to implement both methods: -- --
-- customOptions = defaultOptions
-- { fieldLabelModifier = map toUpper
-- }
--
-- instance ToJSON Coord where
-- toJSON = genericToJSON customOptions
-- toEncoding = genericToEncoding customOptions
--
--
-- Previous versions of this library only had the toJSON method.
-- Adding toEncoding had two reasons:
--
-- -- instance ToJSON Coord where -- toEncoding = genericToEncoding defaultOptions --toEncoding :: ToJSON a => a -> Encoding toJSONList :: ToJSON a => [a] -> Value toEncodingList :: ToJSON a => [a] -> Encoding -- | Read the docs for ToJSONKey first. This class is a conversion -- in the opposite direction. If you have a newtype wrapper around -- Text, the recommended way to define instances is with -- generalized newtype deriving: -- --
-- newtype SomeId = SomeId { getSomeId :: Text }
-- deriving (Eq,Ord,Hashable,FromJSONKey)
--
--
-- If you have a sum of nullary constructors, you may use the generic
-- implementation:
--
-- -- data Color = Red | Green | Blue -- deriving Generic -- -- instance FromJSONKey Color where -- fromJSONKey = genericFromJSONKey defaultJSONKeyOptions --class FromJSONKey a -- | Strategy for parsing the key of a map-like container. fromJSONKey :: FromJSONKey a => FromJSONKeyFunction a -- | This is similar in spirit to the readList method of -- Read. It makes it possible to give String keys special -- treatment without using OverlappingInstances. End users -- should always be able to use the default implementation of this -- method. fromJSONKeyList :: FromJSONKey a => FromJSONKeyFunction [a] -- | Typeclass for types that can be used as the key of a map-like -- container (like Map or HashMap). For example, since -- Text has a ToJSONKey instance and Char has a -- ToJSON instance, we can encode a value of type Map -- Text Char: -- --
-- >>> LBC8.putStrLn $ encode $ Map.fromList [("foo" :: Text, 'a')]
-- {"foo":"a"}
--
--
-- Since Int also has a ToJSONKey instance, we can
-- similarly write:
--
--
-- >>> LBC8.putStrLn $ encode $ Map.fromList [(5 :: Int, 'a')]
-- {"5":"a"}
--
--
-- JSON documents only accept strings as object keys. For any type from
-- base that has a natural textual representation, it can be
-- expected that its ToJSONKey instance will choose that
-- representation.
--
-- For data types that lack a natural textual representation, an
-- alternative is provided. The map-like container is represented as a
-- JSON array instead of a JSON object. Each value in the array is an
-- array with exactly two values. The first is the key and the second is
-- the value.
--
-- For example, values of type '[Text]' cannot be encoded to a string, so
-- a Map with keys of type '[Text]' is encoded as follows:
--
-- -- >>> LBC8.putStrLn $ encode $ Map.fromList [(["foo","bar","baz" :: Text], 'a')] -- [[["foo","bar","baz"],"a"]] ---- -- The default implementation of ToJSONKey chooses this method of -- encoding a key, using the ToJSON instance of the type. -- -- To use your own data type as the key in a map, all that is needed is -- to write a ToJSONKey (and possibly a FromJSONKey) -- instance for it. If the type cannot be trivially converted to and from -- Text, it is recommended that ToJSONKeyValue is used. -- Since the default implementations of the typeclass methods can build -- this from a ToJSON instance, there is nothing that needs to be -- written: -- --
-- data Foo = Foo { fooAge :: Int, fooName :: Text }
-- deriving (Eq,Ord,Generic)
-- instance ToJSON Foo
-- instance ToJSONKey Foo
--
--
-- That's it. We can now write:
--
--
-- >>> let m = Map.fromList [(Foo 4 "bar",'a'),(Foo 6 "arg",'b')]
--
-- >>> LBC8.putStrLn $ encode m
-- [[{"fooName":"bar","fooAge":4},"a"],[{"fooName":"arg","fooAge":6},"b"]]
--
--
-- The next case to consider is if we have a type that is a newtype
-- wrapper around Text. The recommended approach is to use
-- generalized newtype deriving:
--
--
-- newtype RecordId = RecordId { getRecordId :: Text }
-- deriving (Eq,Ord,ToJSONKey)
--
--
-- Then we may write:
--
--
-- >>> LBC8.putStrLn $ encode $ Map.fromList [(RecordId "abc",'a')]
-- {"abc":"a"}
--
--
-- Simple sum types are a final case worth considering. Suppose we have:
--
-- -- data Color = Red | Green | Blue -- deriving (Show,Read,Eq,Ord) ---- -- It is possible to get the ToJSONKey instance for free as we did -- with Foo. However, in this case, we have a natural way to go -- to and from Text that does not require any escape sequences. So -- ToJSONKeyText can be used instead of ToJSONKeyValue to -- encode maps as objects instead of arrays of pairs. This instance may -- be implemented using generics as follows: -- --
-- instance ToJSONKey Color where -- toJSONKey = genericToJSONKey defaultJSONKeyOptions ---- --
-- instance ToJSONKey Color where -- toJSONKey = ToJSONKeyText f g -- where f = Text.pack . show -- g = text . Text.pack . show -- -- text function is from Data.Aeson.Encoding ---- -- The situation of needing to turning function a -> Text -- into a ToJSONKeyFunction is common enough that a special -- combinator is provided for it. The above instance can be rewritten as: -- --
-- instance ToJSONKey Color where -- toJSONKey = toJSONKeyText (Text.pack . show) ---- -- The performance of the above instance can be improved by not using -- String as an intermediate step when converting to Text. -- One option for improving performance would be to use template haskell -- machinery from the text-show package. However, even with the -- approach, the Encoding (a wrapper around a bytestring builder) -- is generated by encoding the Text to a ByteString, an -- intermediate step that could be avoided. The fastest possible -- implementation would be: -- --
-- -- Assuming that OverloadedStrings is enabled
-- instance ToJSONKey Color where
-- toJSONKey = ToJSONKeyText f g
-- where f x = case x of {Red -> "Red";Green ->"Green";Blue -> "Blue"}
-- g x = case x of {Red -> text "Red";Green -> text "Green";Blue -> text "Blue"}
-- -- text function is from Data.Aeson.Encoding
--
--
-- This works because GHC can lift the encoded values out of the case
-- statements, which means that they are only evaluated once. This
-- approach should only be used when there is a serious need to maximize
-- performance.
class ToJSONKey a
-- | Strategy for rendering the key for a map-like container.
toJSONKey :: ToJSONKey a => ToJSONKeyFunction a
-- | This is similar in spirit to the showsList method of
-- Show. It makes it possible to give String keys special
-- treatment without using OverlappingInstances. End users
-- should always be able to use the default implementation of this
-- method.
toJSONKeyList :: ToJSONKey a => ToJSONKeyFunction [a]
instance (Data.Aeson.Types.FromJSON.FromJSON a, GHC.Base.Semigroup a, Data.NonEmpty.NonEmptySingleton a, Data.NonEmpty.NonEmptyFromContainer a, Data.Aeson.Types.FromJSON.FromJSON (Data.NonEmpty.NonEmptySingletonElement a)) => Data.Aeson.Types.FromJSON.FromJSON (Data.NonEmpty.NonEmpty a)
instance (Data.Aeson.Types.FromJSON.FromJSON a, Data.NonEmpty.NonEmptySingleton a, Data.NonEmpty.NonEmptyFromContainer a, Data.Aeson.Types.FromJSON.FromJSON (Data.NonEmpty.NonEmptySingletonElement a), Data.Aeson.Types.FromJSON.FromJSONKey (Data.NonEmpty.NonEmptySingletonElement a), Data.Aeson.Types.FromJSON.FromJSONKey a, GHC.Base.Semigroup a) => Data.Aeson.Types.FromJSON.FromJSONKey (Data.NonEmpty.NonEmpty a)
instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Data.NonEmpty.NonEmpty a)
instance Data.Aeson.Types.ToJSON.ToJSONKey a => Data.Aeson.Types.ToJSON.ToJSONKey (Data.NonEmpty.NonEmpty a)