-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Instances of <tt>FromYaml</tt> and <tt>ToYaml</tt> of <a>yamlet</a>
--   for the types that have <tt>FromJSON</tt> and <tt>ToJSON</tt>
--   instances of <a>aeson</a>, e.g. in a program that moves from the yaml
--   package to yamlet. Errors point to the node of the input that caused
--   them, and the encoder keeps the order of the fields of a type whose
--   instance defines <tt>toEncoding</tt>.
@package yamlet-aeson
@version 1.0.0.1


-- | Use the <a>FromJSON</a> and <a>ToJSON</a> instances of aeson with
--   yamlet, for a type that has no <a>FromYaml</a> and <a>ToYaml</a>
--   instances yet, e.g. in a program that moves from the yaml package to
--   yamlet.
--   
--   The examples use these external imports:
--   
--   <pre>
--   &gt;&gt;&gt; import Data.Aeson qualified as A
--   
--   &gt;&gt;&gt; import Data.Map.Strict qualified as M
--   
--   &gt;&gt;&gt; import Data.Text qualified as T
--   
--   &gt;&gt;&gt; import Data.Text.IO qualified as T
--   </pre>
--   
--   A value in <a>ViaAeson</a> decodes and encodes with the
--   <a>FromJSON</a> and <a>ToJSON</a> instances:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   data Server = Server {port :: Int, host :: T.Text}
--     deriving stock (Generic, Show)
--     deriving anyclass (A.FromJSON)
--   instance A.ToJSON Server where
--     toEncoding = A.genericToEncoding A.defaultOptions
--   :}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; Right (ViaAeson server) = decodeText @(ViaAeson Server) "port: 80\nhost: localhost\n"
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; server
--   Server {port = 80, host = "localhost"}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; T.putStr (encodeText (ViaAeson server))
--   port: 80
--   host: localhost
--   </pre>
--   
--   A type with <a>FromJSON</a> and <a>ToJSON</a> instances can derive its
--   <a>FromYaml</a> and <a>ToYaml</a> instances via <a>ViaAeson</a>, e.g.
--   in a program that reads and writes both JSON and YAML and keeps one
--   set of instances. Such a type can be a field of a type with instances
--   of its own:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   newtype Address = Address T.Text
--     deriving stock (Show)
--     deriving newtype (A.FromJSON, A.ToJSON)
--     deriving (FromYaml, ToYaml) via ViaAeson Address
--   data Mail = Mail {from :: Address, to :: [Address]}
--     deriving stock (Generic, Show)
--     deriving anyclass (GenericYamlOptions)
--     deriving (FromYaml, ToYaml) via GenericYaml Mail
--   :}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; decodeText @Mail "from: a@example.com\nto: [b@example.com]\n"
--   Right (Mail {from = Address "a@example.com", to = [Address "b@example.com"]})
--   </pre>
--   
--   An error of a decoder of aeson points to the node that caused it:
--   
--   <pre>
--   &gt;&gt;&gt; input = "- port: 80\n  host: a\n- port: http\n  host: b\n"
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; T.putStr input
--   - port: 80
--     host: a
--   - port: http
--     host: b
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; either printErrors print (decodeText @(ViaAeson [Server]) input)
--   input.yaml:3:9: [1].port: parsing Int failed, expected Number, but encountered String
--     |
--   3 | - port: http
--     |         ^
--   </pre>
--   
--   The module also has the <a>FromYaml</a> and <a>ToYaml</a> instances
--   for an aeson <a>Value</a>, e.g. for a field that holds any data. They
--   convert as the section <a>Conversion</a> says:
--   
--   <pre>
--   &gt;&gt;&gt; decodeText @A.Value "name: a\nports: [80, 443]\n"
--   Right (Object (fromList [("name",String "a"),("ports",Array [Number 80.0,Number 443.0])]))
--   </pre>
--   
--   <h1>Order of keys</h1>
--   
--   The encoder writes the keys of a mapping in the order of
--   <a>toEncoding</a>. That is the order of the fields if the instance
--   defines <a>toEncoding</a>, e.g. with <a>genericToEncoding</a> as
--   <tt>Server</tt> above, or with <a>deriveJSON</a>. The default
--   <a>toEncoding</a> goes through <a>toJSON</a>, so the keys come in the
--   order of an aeson object, which is sorted by default.
--   
--   <a>parseJSON</a> gets the keys in no order, because an aeson object
--   has none. To keep the order of a mapping, decode the mapping with a
--   decoder of yamlet. Its values can still decode via <a>ViaAeson</a>:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   newtype Servers = Servers [(T.Text, Server)]
--     deriving stock (Show)
--   instance FromYaml Servers where
--     parseYaml = withMapping $ \o -&gt;
--       Servers
--         &lt;$&gt; traverse
--           ( \(k, v) -&gt;
--               (,) &lt;$&gt; parseYaml k &lt;*&gt; fmap (.value) (parseYaml @(ViaAeson Server) v)
--           )
--           (objectEntries o)
--   :}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; decodeText @Servers "web: {port: 80, host: a}\napi: {port: 81, host: b}\n"
--   Right (Servers [("web",Server {port = 80, host = "a"}),("api",Server {port = 81, host = "b"})])
--   </pre>
--   
--   <a>decodeWithDocument</a> keeps the whole document with the decoded
--   value, e.g. to write the document back with a change.
--   
--   <h1>Conversion</h1>
--   
--   A YAML document converts to an aeson <a>Value</a> as follows:
--   
--   <ul>
--   <li>A key is the text of its scalar, e.g. <tt>"0x10"</tt> for
--   <tt>0x10</tt> and <tt>"~"</tt> for <tt>~</tt>, as in the yaml package.
--   Two keys with the same text are an error, e.g. <tt>1</tt> and
--   <tt>"1"</tt>, which are different keys in YAML. A key that is a
--   collection is an error.</li>
--   <li>A key <tt>&lt;&lt;</tt> is an ordinary key, because the merge keys
--   of YAML 1.1 are not supported.</li>
--   <li><tt>.inf</tt> and <tt>-.inf</tt> are the strings <tt>"+inf"</tt>
--   and <tt>"-inf"</tt>, and <tt>.nan</tt> is null. The <a>FromJSON</a>
--   and <a>ToJSON</a> instances for <a>Double</a> and <a>Float</a> read
--   and write these values.</li>
--   <li><tt>-0.0</tt> is the number 0, because a <a>Scientific</a> has no
--   negative zero.</li>
--   <li>A number whose exponent in scientific notation is beyond the range
--   from -1000 to 1000, e.g. <tt>1e1001</tt>, is an error, as in yamlet. A
--   <a>Number</a> converts to YAML as aeson writes it in JSON: as an
--   integer if its <a>base10Exponent</a> is from 0 to 1024, otherwise in
--   scientific notation. Thus <tt>1e1001</tt> reads back as an integer,
--   but <tt>1e1025</tt> and <tt>1e-1001</tt> do not read back.</li>
--   <li>A tag that is not of the core schema makes a scalar a string, e.g.
--   <tt>!secret 123</tt> is the string <tt>"123"</tt>. The yaml package
--   reads it as the number 123. A collection with such a tag converts as
--   without it, e.g. <tt>!point {x: 1}</tt> is the object <tt>{"x":
--   1}</tt>.</li>
--   </ul>
--   
--   A <a>FromJSON</a> instance can convert two different keys to the same
--   key and then keep only one of the pairs, as it does for JSON, e.g.
--   <tt>1</tt> and <tt>1.0</tt> for a <tt>Map Int</tt>. The
--   <a>FromYaml</a> instances for maps reject such keys.
--   
--   <pre>
--   &gt;&gt;&gt; decodeText @(ViaAeson (M.Map Int T.Text)) "1: a\n1.0: b\n"
--   Right (ViaAeson {value = fromList [(1,"a")]})
--   </pre>
--   
--   An aeson <a>Value</a> converts to YAML as aeson writes it in JSON,
--   e.g. the keys of a <tt>Map Int</tt> are strings, which the encoder
--   quotes because they look like numbers:
--   
--   <pre>
--   &gt;&gt;&gt; T.putStr (encodeText (ViaAeson (M.fromList @Int @T.Text [(1, "a")])))
--   '1': a
--   </pre>
module Yamlet.Aeson

-- | A value that decodes and encodes with its <a>FromJSON</a> and
--   <a>ToJSON</a> instances. The field has no selector function, so read
--   it with record dot syntax, e.g. <tt>(.value)</tt>, or with a pattern.
newtype ViaAeson a
ViaAeson :: a -> ViaAeson a
[value] :: ViaAeson a -> a
instance GHC.Classes.Eq Yamlet.Aeson.KeyText
instance GHC.Classes.Eq a => GHC.Classes.Eq (Yamlet.Aeson.ViaAeson a)
instance Yamlet.Internal.FromYaml.FromYaml Yamlet.Aeson.KeyText
instance Yamlet.Internal.FromYaml.FromYaml Data.Aeson.Types.Internal.Value
instance Data.Aeson.Types.FromJSON.FromJSON a => Yamlet.Internal.FromYaml.FromYaml (Yamlet.Aeson.ViaAeson a)
instance GHC.Classes.Ord Yamlet.Aeson.KeyText
instance GHC.Classes.Ord a => GHC.Classes.Ord (Yamlet.Aeson.ViaAeson a)
instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (Yamlet.Aeson.ViaAeson a)
instance Yamlet.Internal.ToYaml.ToYaml Data.Aeson.Types.Internal.Value
instance Data.Aeson.Types.ToJSON.ToJSON a => Yamlet.Internal.ToYaml.ToYaml (Yamlet.Aeson.ViaAeson a)
