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


-- | Handle JSON that may or may not be a list, or exist
--   
--   According to the standard promoted by Schema.org, the same JSON object
--   field may legally contain an array or a single element, be null, or be
--   absent entirely. This library provides an intermediary data type and
--   supporting functions to help aeson parse and output JSON conforming to
--   this frustrating behavior.
@package aeson-yak
@version 0.1.1.3


-- | There are two ways to use this library: the way with extra
--   boilerplate, or the way with a leaky abstraction. A truly good
--   solution would fix it all with Template Haskell; but the author is not
--   a truly good Haskeller, so this will have to do for now.
--   
--   The boilerplate way:
--   
--   <pre>
--   data Hideous = Hideous { yak :: [String] }
--   instance ToJSON Hideous where
--     toJSON x = object [ "yak" .= hairy (yak x) ]
--   instance FromJSON Hideous where
--     parseJSON (Object o) = Hideous &lt;$&gt; (shave &lt;$&gt; o .:? "yak")
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; encode $ Hideous ["foo","bar"]
--   "{\"yak\":[\"foo\",\"bar\"]}"
--   
--   &gt;&gt;&gt; encode $ Hideous ["baz"]
--   "{\"yak\":\"baz\"}"
--   
--   &gt;&gt;&gt; encode $ Hideous []
--   "{\"yak\":null}"
--   
--   &gt;&gt;&gt; yak &lt;$&gt; decode "{\"yak\":[\"foo\",\"bar\"]}"
--   Just ["foo", "bar"]
--   
--   &gt;&gt;&gt; yak &lt;$&gt; decode "{\"yak\":\"baz\"}"
--   Just ["baz"]
--   
--   &gt;&gt;&gt; yak &lt;$&gt; decode "{}"
--   Just []
--   </pre>
--   
--   The leaky way:
--   
--   <pre>
--   data Abhorrent = Abhorrent { yak :: Yak String }
--   $(deriveJSON defaultOptions{omitNothingFields=True} ''Abhorrent)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; encode . Abhorrent . hairy $ ["shaven","shorn","sheared"]
--   "{\"yak\":[\"shaven\",\"shorn\",\"sheared\"]}"
--   
--   &gt;&gt;&gt; shave . yak &lt;$&gt; decode "{}"
--   Just []
--   </pre>
--   
--   Which to prefer depends on how many yaks you need to deal with
--   <i>vs.</i> how much you hate cleaning up yak droppings in the rest of
--   your codebase.
module Data.Aeson.Yak

-- | Data whose JSON representation may legally be an array, a single
--   element, or null/absent. No, please, calm down. It'll be okay. Mostly.
--   
--   <i>(<a>Lousy</a> is not exposed to avoid namespace infestation.</i>
--   <i>This is open for discussion if a use case can be shown.)</i>
type Yak a = Maybe (Lousy a)

-- | Convert a <tt><a>Foldable</a></tt> to a <a>Yak</a>. Should probably be
--   specific to lists, but what's life without a little adventure?
hairy :: Foldable f => f a -> Yak a

-- | Convert a <a>Yak</a> to a list. Relax, and allow yourself to breathe.
shave :: Yak a -> [a]
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Aeson.Yak.Lousy a)
instance GHC.Show.Show a => GHC.Show.Show (Data.Aeson.Yak.Lousy a)
instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Data.Aeson.Yak.Lousy a)
instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Data.Aeson.Yak.Lousy a)
