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


-- | XML picklers based on xml-types, ported from hexpat-pickle
--   
--   A library of combinators that allows Haskell data structures to be
--   pickled (serialized) to/from a representation of XML as defined in
--   xml-types
--   
--   Release history
--   
--   <ul>
--   <li><i>0.3</i> Changed the Result type of unpicklers. Unpicklers now
--   fail by default when there are remaining elements</li>
--   <li><i>0.2</i> Error system overhaul</li>
--   <li><i>0.1</i> Initial release</li>
--   </ul>
@package xml-picklers
@version 0.3.6


-- | This module provides XML picklers that plug into the XML tree of the
--   <i>xml-types</i> package. This module was "inspired" by
--   <i>hexpat-pickle</i>.
--   
--   The API differences between <i>hexpat-pickle</i> and this module
--   include:
--   
--   <ul>
--   <li>When unpickling, picklers will <i>consume</i> matching elmements
--   so that they will be ignored by sucessive picklers. To circumvent this
--   behaviour, use <tt><a>xpPeek</a></tt></li>
--   <li>Wrappers like <a>xpWrap</a> are uncurried</li>
--   <li>There are no lazy unpicklers</li>
--   <li>Most unpicklers will produce an error when their child unpicklers
--   fail to consume all elements. Use <a>xpClean</a> to discard those
--   elements</li>
--   </ul>
--   
--   The data type <tt><a>PU</a> t a</tt> represents both a pickler
--   (converting Haskell data to XML) and an unpickler (XML to Haskell
--   data), so your code only needs to be written once for both
--   serialization and deserialization. The <a>PU</a> primitives, such as
--   <a>xpElem</a> for XML elements, may be composed into complex
--   arrangements using <a>xpPair</a> and other combinators.
--   
--   Most picklers will try to find the <i>first match</i> rather than
--   failing when the first element doesn't match. This is why the target
--   type often is a list. To prevent this behaviour and commit the pickler
--   to the first element available, use <a>xpIsolate</a>.
--   
--   The top level of the document does not follow this rule, because it is
--   a single node type. <a>xpRoot</a> is needed to adapt this to type
--   [<a>Node</a>] for your pickler to use. You would typically define a
--   pickler for a whole document with <a>xpElem</a>, then pickle it to a
--   single <a>Node</a> with <tt><a>pickleTree</a> (xpRoot myDocPickler)
--   value</tt>.
--   
--   <i>NB</i>: Unresolved entities are considered an error and will
--   trigger an exception
--   
--   When unpickling, the following invariant regarding the list of
--   remaining elements should be observed:
--   
--   <ul>
--   <li>The returned list should be a subset of or the initial list
--   itself, that is, no elements should be added or changed</li>
--   <li>The relative order of elements should be preserved</li>
--   <li>Elements may, however, be removed from anywhere in the list</li>
--   </ul>
--   
--   Here is a simple example to get you started:
--   
--   <pre>
--   {-# LANGUAGE OverloadedStrings #-}
--   import Data.Text
--   import Data.XML.Types
--   import Data.XML.Pickle
--   
--   -- Person name, age and description
--   data Person = Person Text Int Text
--   
--   xpPerson :: PU [Node] Person
--   xpPerson =
--       -- How to wrap and unwrap a Person
--       xpWrap (\((name, age), descr) -&gt; Person name age descr)
--              (\(Person name age descr) -&gt; ((name, age), descr)) $
--       xpElem "person"
--           (xpPair
--               (xpAttr "name" xpId)
--               (xpAttr "age" xpPrim))
--           (xpContent xpId)
--   
--   people = [
--       Person "Dave" 27 "A fat thin man with long short hair",
--       Person "Jane" 21 "Lives in a white house with green windows"]
--   
--   main = do
--       print $ pickle (xpRoot $ xpElemNodes "people" $ xpAll xpPerson) people
--   </pre>
--   
--   Program output would be an xml-value equivalent to:
--   
--   <pre>
--   &lt;people&gt;
--     &lt;person name="Dave" age="27"&gt;
--       A fat thin man with long short hair
--     &lt;/person&gt;
--     &lt;person name="Jane" age="21"&gt;
--       Lives in a white house with green windows
--    &lt;/person&gt;
--   &lt;/people&gt;
--   </pre>
--   
--   Functions marked with <i>compat</i> are included for compatibility
--   with <i>hexpat-pickle</i>.
module Data.XML.Pickle
data PU t a
PU :: (t -> UnpickleResult t a) -> (a -> t) -> PU t a
[unpickleTree] :: PU t a -> t -> UnpickleResult t a
[pickleTree] :: PU t a -> a -> t
type Attribute = (Name, [Content])
data UnpickleResult t a
UnpickleError :: UnpickleError -> UnpickleResult t a

-- | Not found, description of element
NoResult :: Text -> UnpickleResult t a

-- | Result and remainder. The remainder is wrapped in <tt>Maybe</tt> to
--   avoid a <tt>Monoid</tt> constraint on <tt>t</tt>
--   
--   <i>Invariant</i>: When <tt>t</tt> is a <tt>Monoid</tt>, the empty
--   remainder should always be <tt>Nothing</tt> instead of <tt>Just
--   mempty</tt>
Result :: a -> (Maybe t) -> UnpickleResult t a

-- | Pickle a tree.
pickle :: PU t a -> a -> t

-- | Unpickle a tree.
unpickle :: PU t a -> t -> Either UnpickleError a

-- | Doesn't create or consume anything, always succeeds.
xpUnit :: PU [a] ()

-- | The zero pickler.
--   
--   Encodes nothing, always fails during unpickling. (Same as
--   <tt><a>xpThrow</a> "got xpZero"</tt>).
xpZero :: PU [t] a

-- | No output when pickling, always generates an error with the specified
--   message on unpickling.
xpThrow :: Monoid m => String -> PU m a

-- | Isomorphic pickler.
xpIso :: (a -> b) -> (b -> a) -> PU a b
xpPartial :: (a -> Either Text b) -> (b -> a) -> PU a b

-- | Returns everything (remaining), untouched.
xpId :: PU a a
xpFst :: Monoid b => PU t (a, b) -> PU t a
xpSnd :: Monoid a => PU t (a, b) -> PU t b

-- | <a>xpId</a>. (<i>compat</i>)
xpTrees :: PU a a

-- | Return one element, untouched.
xpHead :: PU [a] a

-- | <a>xpHead</a>. (<i>compat</i>)
xpTree :: PU [a] a

-- | Specialised version of <a>xpId</a>. (<i>compat</i>)
xpText0 :: PU Text Text

-- | Like <a>xpText0</a>, but fails on non-empty input.
xpText :: PU Text Text

-- | Convert <tt>Text</tt> to/from <tt>String</tt>.
xpString :: PU Text String

-- | Transforms a pickler on lists to a pickler on single elements.
--   
--   <i>NB</i>: Will error when the given pickler doesn't produce exactly
--   one element.
xpRoot :: PU [a] b -> PU a b

-- | Convert text to/from any type that implements <a>Read</a> and
--   <a>Show</a>. Fails on unpickle if <a>read</a> fails.
xpPrim :: (Show a, Read a) => PU Text a

-- | Pickle to/from attribute.
xpAttribute :: Name -> PU Text a -> PU [Attribute] a

-- | Pickle attribute if <tt>Just</tt> is given, on unpickling return
--   <tt>Just <a>val</a></tt> when the attribute is found, <tt>Nothing</tt>
--   otherwise.
xpAttribute' :: Name -> PU Text a -> PU [Attribute] (Maybe a)

-- | Pickle an attribute with the specified name and value, fail if the
--   same attribute is not present on unpickle.
xpAttribute_ :: Name -> Text -> PU [Attribute] ()

-- | <a>xpAttribute</a> (<i>compat</i>)
xpAttr :: Name -> PU Text a -> PU [Attribute] a
xpAttrImplied :: Name -> PU Text a -> PU [Attribute] (Maybe a)

-- | <a>xpAttribute_</a> (<i>compat</i>)
xpAttrFixed :: Name -> Text -> PU [Attribute] ()

-- | Add an attribute with a fixed value.
xpAddFixedAttr :: Name -> Text -> PU [Attribute] b -> PU [Attribute] b

-- | When unpickling, tries to find the first element with the supplied
--   name. Once such an element is found, it will commit to it and
--   <i>fail</i> if any of the picklers don't match.
xpElem :: Name -> PU [Attribute] a -> PU [Node] n -> PU [Node] (a, n)

-- | Pickle <a>Element</a> without a restriction on the name. The name as
--   taken / returned as the first element of the triple.
xpElemWithName :: PU [Attribute] a -> PU [Node] n -> PU [Node] (Name, a, n)

-- | Find element by name space, prefixes are ignored.
xpElemByNamespace :: Text -> PU Text name -> PU [Attribute] a -> PU [Node] n -> PU [Node] (name, a, n)

-- | Pickler returns the first found <a>Element</a> untouched.
--   
--   Unpickler wraps element in <a>NodeElement</a>.
xpElemVerbatim :: PU [Node] Element

-- | A helper variant of <a>xpElem</a> for elements that contain attributes
--   but no child tags.
xpElemAttrs :: Name -> PU [Attribute] b -> PU [Node] b

-- | A helper variant of <a>xpElem</a> for elements that contain child
--   nodes but no attributes.
xpElemNodes :: Name -> PU [Node] b -> PU [Node] b

-- | A helper variant of <a>xpElem</a> for elements that contain only
--   character data.
xpElemText :: Name -> PU [Node] Text

-- | Helper for <a>Element</a> values that don't contain anything.
xpElemBlank :: Name -> PU [Node] ()

-- | When pickling, creates an empty element iff parameter is
--   <tt>True</tt>.
--   
--   When unpickling, checks whether element exists. Generates an error
--   when the element is not empty.
xpElemExists :: Name -> PU [Node] Bool

-- | Handle all elements with a given name. The unpickler will fail when
--   any of the elements fails to unpickle.
xpElems :: Name -> PU [Attribute] a -> PU [Node] n -> PU [Node] [(a, n)]

-- | Get the first non-element <a>NodeContent</a> from a node.
xpContent :: PU Text a -> PU [Node] a

-- | Converts Booleans to XML boolean values
--   
--   <ul>
--   <li>"true" and "1" are read as <tt>True</tt></li>
--   <li>"false" and "0" are read as <tt>False</tt></li>
--   <li>All other values generate an unpickle error</li>
--   </ul>
--   
--   Will always generate "true" or "false" (not "0" or "1") when pickling.
xpBool :: PU Text Bool

-- | Lift a pickler. Nothing is returned when the given pickler doesn't
--   return a value (e.g. the element isn't found). Does not affect
--   unpickling errors. <tt>Nothing</tt> is pickled to <tt>mempty</tt>.
--   
--   A typical example is:
--   
--   <pre>
--   xpElemAttributes "score" $ xpOption $ xpAttribute "value" xpPrim
--   </pre>
--   
--   in which <tt>Just 5</tt> is encoded as <tt>&lt;score
--   value="5"/&gt;</tt> and <tt>Nothing</tt> as <tt>&lt;score/&gt;</tt>.
xpOption :: PU [t] a -> PU [t] (Maybe a)

-- | Optional conversion with default value.
--   
--   Unlike <a>xpWithDefault</a> the default value is not encoded in the
--   XML document, during unpickling the default value is inserted if the
--   pickler doesn't return a value.
xpDefault :: (Eq a) => a -> PU [t] a -> PU [t] a

-- | Attempt to use a pickler. Return a default value when the pickler
--   doesn't return anything (doesn't touch on <a>UnpickleError</a>).
--   
--   Unlike <a>xpDefault</a>, the default value <i>is</i> encoded in the
--   XML document.
xpWithDefault :: a -> PU t a -> PU t a

-- | Standard pickler for maps
--   
--   This pickler converts a map into a list of pairs of the form
--   
--   <pre>
--   &lt;elt attr="key"&gt;value&lt;/elt&gt;
--   </pre>
xpMap :: Ord k => Name -> Name -> PU Text k -> PU [Node] a -> PU [Node] (Map k a)

-- | Execute one of a list of picklers. The <i>selector function</i> is
--   used during pickling, and the integer returned is taken as a 0-based
--   index to select a pickler from <i>pickler options</i>. Unpickling is
--   done by trying each list element in order until one returns a
--   <tt>Result</tt> (the <i>selector</i> is not used).
--   
--   This is typically used to handle each constructor of a data type.
--   However, it can be used wherever multiple serialization strategies
--   apply to a single type.
--   
--   <i>NB</i>: This function will ignore all errors as long as one of the
--   branches returns a result. Also, it will produce an error when all
--   branches return <tt>NoResult</tt>. Use <a>xpChoice</a> for a saner
--   version of this function.
xpAlt :: (a -> Int) -> [PU t a] -> PU t a

-- | Execute one of a list of picklers. The <i>selector function</i> is
--   used during pickling, and the integer returned is taken as a 0-based
--   index to select a pickler from <i>pickler options</i>. Unpickling is
--   done by trying each list element in order until one returns a
--   <tt>Result</tt> or an <tt>Error</tt>.
--   
--   This is typically used to handle each constructor of a data type.
--   However, it can be used wherever multiple serialization strategies
--   apply to a single type.
--   
--   This function is similar to <a>xpAlt</a> but it will stop unpickling
--   on the first error. It will return <tt>NoResult</tt> iff all of the
--   picklers return <tt>NoResult</tt> (or the list of picklers is empty).
xpChoice :: (a -> Int) -> [PU t a] -> PU t a

-- | Try the left pickler first and if that doesn't produce anything the
--   right one. Wrapping the result in <tt>Left</tt> or <tt>Right</tt>,
--   respectively.
--   
--   Not to be confused with <a>xpWrapEither</a>.
xpEither :: PU n t1 -> PU n t2 -> PU n (Either t1 t2)

-- | Pickler that during pickling always uses the first pickler, and during
--   unpickling tries the first, and on failure then tries the second.
xpTryCatch :: PU t a -> PU t a -> PU t a

-- | When unpickling, tries to apply the pickler to all elements returning
--   and consuming only matched elements.
xpFindMatches :: PU [b] a -> PU [b] [a]

-- | Select a single element from the list and apply unpickler to it.
--   
--   Returns no value when no element matches the predicate.
--   
--   Fails when the unpickler doesn't return a value.
--   
--   When pickling, this is a noop.
xpFindFirst :: (t -> Bool) -> PU [t] a -> PU [t] a

-- | Tries to apply the pickler to all the remaining elements; fails if any
--   of them don't match.
xpAll :: PU [a] b -> PU [a] [b]

-- | For unpickling, apply the given pickler to a subset of the elements
--   determined by a given predicate.
--   
--   Pickles like <a>xpAll</a>.
xpSubsetAll :: (a -> Bool) -> PU [a] b -> PU [a] [b]

-- | Apply unpickler to all elements with the given namespace.
--   
--   Pickles like <a>xpAll</a>.
xpAllByNamespace :: Text -> PU [Node] b -> PU [Node] [b]

-- | <a>xpAll</a>. (<i>compat</i>)
xpList0 :: PU [a] b -> PU [a] [b]

-- | When unpickling, successively applies pickler to single elements until
--   it doesn't return anything; returns all matched elements.
xpSeqWhile :: PU [a] b -> PU [a] [b]

-- | <a>xpSeqWhile</a>. (<i>compat</i>)
xpList :: PU [a] b -> PU [a] [b]

-- | Like <a>xpList</a>, but only succeed during unpickling if at least a
--   minimum number of elements are unpickled.
xpListMinLen :: Int -> PU [a] b -> PU [a] [b]

-- | Combines 2 picklers.
xp2Tuple :: PU [a] b1 -> PU [a] b2 -> PU [a] (b1, b2)

-- | <a>xp2Tuple</a>. (<i>compat</i>)
xpPair :: PU [a] b1 -> PU [a] b2 -> PU [a] (b1, b2)

-- | <a>xp2Tuple</a>.
(<#>) :: PU [a] b1 -> PU [a] b2 -> PU [a] (b1, b2)

-- | Combines 3 picklers.
xp3Tuple :: PU [a] a1 -> PU [a] a2 -> PU [a] a3 -> PU [a] (a1, a2, a3)

-- | <a>xp3Tuple</a>. (<i>compat</i>)
xpTriple :: PU [a] a1 -> PU [a] a2 -> PU [a] a3 -> PU [a] (a1, a2, a3)

-- | Combines 4 picklers.
xp4Tuple :: PU [a] a1 -> PU [a] a2 -> PU [a] a3 -> PU [a] a4 -> PU [a] (a1, a2, a3, a4)

-- | Combines 5 picklers.
xp5Tuple :: PU [a] a1 -> PU [a] a2 -> PU [a] a3 -> PU [a] a4 -> PU [a] a5 -> PU [a] (a1, a2, a3, a4, a5)

-- | You guessed it ... Combines 6 picklers.
xp6Tuple :: PU [a] a1 -> PU [a] a2 -> PU [a] a3 -> PU [a] a4 -> PU [a] a5 -> PU [a] a6 -> PU [a] (a1, a2, a3, a4, a5, a6)

-- | Apply a bijection before pickling / after unpickling.
xpWrap :: (a -> b) -> (b -> a) -> PU t a -> PU t b

-- | Ignore input/output and replace with constant values.
xpConst :: a -> PU t () -> PU t a

-- | Like xpWrap, except it strips <tt>Right</tt> (and treats <tt>Left</tt>
--   as a failure) during unpickling.
--   
--   Not to be confused with <a>xpEither</a>.
xpWrapEither :: Show e => (a -> Either e b) -> (b -> a) -> PU t a -> PU t b

-- | Like xpWrap, but strips <tt>Just</tt> (and treats <tt>Nothing</tt> as
--   a failure) during unpickling.
xpWrapMaybe :: (a -> Maybe b) -> (b -> a) -> PU t a -> PU t b

-- | Like xpWrap, but strips <tt>Just</tt> (and treats <tt>Nothing</tt> as
--   a failure) during unpickling, with specified error message for
--   <tt>Nothing</tt> value.
xpWrapMaybe_ :: String -> (a -> Maybe b) -> (b -> a) -> PU t a -> PU t b

-- | Test predicate when unpickling. Fails with given error message when
--   the predicate return false.
--   
--   <i>NB</i>: The predicate will only be tested while <i>unpickling</i>.
--   When pickling, this is a noop.
xpAssert :: Text -> (a -> Bool) -> PU t a -> PU t a

-- | Instead of failing the pickler will return no result.
xpMayFail :: PU t a -> PU t a

-- | Unlift a pickler on <a>Node</a> values to a pickler on <a>Element</a>
--   values. Nodes generated during pickling that are not <a>Element</a>
--   values will be silently discarded.
xpUnliftElems :: PU [Node] a -> PU [Element] a

-- | Noop when pickling.
--   
--   When unpickling, only give access to the first element.
xpIsolate :: PU [t] a -> PU [t] a

-- | When unpickling, don't consume the matched element(s), noop when
--   pickling.
xpPeek :: PU t a -> PU t a

-- | Run unpickler and consume and discard remaining elements.
--   
--   When pickling, this is a noop.
xpClean :: PU t a -> PU t a
data UnpickleError
ErrorMessage :: Text -> UnpickleError
TraceStep :: (Text, Text) -> UnpickleError -> UnpickleError
Variants :: [UnpickleError] -> UnpickleError
ppUnpickleError :: UnpickleError -> String
(<++>) :: (Text, Text) -> UnpickleError -> UnpickleError
infixl 6 <++>

-- | Add a back trace level to the error report.
(<?+>) :: (Text, Text) -> PU t a -> PU t a
infixr 1 <?+>

-- | Override the last backtrace level in the error report.
(<?>) :: (Text, Text) -> PU t a -> PU t a
infixr 0 <?>
(<??>) :: Text -> PU t a -> PU t a
data UnresolvedEntityException
UnresolvedEntityException :: UnresolvedEntityException

-- | Merge successive <tt>NodeContent</tt> values.
flattenContent :: [Node] -> [Node]
tErr :: Text -> UnpickleResult t a -> UnpickleResult t a

-- | Try to extract the remainig elements, fail if there are none.
getRest :: UnpickleResult [a] b -> UnpickleResult [a] (b, [a])
