{-# LANGUAGE GeneralizedNewtypeDeriving #-}

-- | Functions to extract data from parsed XML.
--
-- = Example
--
-- Suppose you have an xml file of books like this:
--
-- > <?xml version="1.0"?>
-- > <library>
-- >   <book id="1" isbn="23234-1">
-- >     <author>John Doe</author>
-- >     <title>Some book</title>
-- >   </book>
-- >   <book id="2">
-- >     <author>You</author>
-- >     <title>The Great Event</title>
-- >   </book>
-- >   ...
-- > </library>
--
-- And a data type for a book:
--
-- > data Book = Book { bookId        :: Int
-- >                  , isbn          :: Maybe String
-- >                  , author, title :: String
-- >                  }
--
-- You can parse the xml file into a generic tree structure using
-- 'Text.XML.Light.Input.parseXMLDoc' from the `xml` package.
--
-- Using this library one can define extractors to extract Books from
-- the generic tree.
-- 
-- @
--    book = 'element' "book" $ do
--             i <- 'attribAs' "id" 'Text.XML.Light.Extractors.Extra.integer'
--             s <- 'optional' ('attrib' "isbn")
--             'children' $ do
--               a <- 'element' "author" $ 'contents' $ 'text'
--               t <- 'element' "title" $ 'contents' $ 'text'
--               return Book { bookId = i, author = a, title = t, isbn = s }
--
--    library = 'element' "library" $ 'children' $ 'only' $ 'many' book
--
--    extractLibrary :: 'XML.Element' -> 'Either' 'ExtractionErr' [Book]
--    extractLibrary = 'extractDocContents' library
-- @
--
-- = Notes
--
--  * The 'only' combinator can be used to exhaustively extract contents.
--
--  * The "Control.Applicative" module contains some useful
--    combinators like 'optional', 'many' and '<|>'.
--
--  * The "Text.XML.Light.Extractors.ShowErr" contains some
--    predefined functions to convert error values to strings.
--
module Text.XML.Light.Extractors
  ( 
  -- * Errors
    Path
  , Err(..)
  , ExtractionErr(..)
    
  -- * Element extraction
  , ElementExtractor
  , extractElement
  , attrib
  , attribAs
  , children
  , contents
  
  -- * Contents extraction
  , ContentsExtractor
  , extractContents
  , extractDocContents
  , element
  , text
  , textAs
  , choice
  , anyContent
  , eoc
  , only

  -- * Utils
  , showExtractionErr
  , eitherMessageOrValue
  , integer
  , float
  ) 
where

import Control.Applicative

import           Text.XML.Light.Types as XML

import           Text.XML.Light.Extractors.Extra
import           Text.XML.Light.Extractors.ShowErr  (showExtractionErr)
import           Text.XML.Light.Extractors.Internal (ExtractionErr, Err, Path)
import qualified Text.XML.Light.Extractors.Internal as Internal
import           Text.XML.Light.Extractors.Internal.Result hiding (throwError, throwFatal)

--------------------------------------------------------------------------------

newtype ElementExtractor a = ElementExtractor (Internal.ElementExtractor a)
 deriving (Functor ElementExtractor
a -> ElementExtractor a
Functor ElementExtractor
-> (forall a. a -> ElementExtractor a)
-> (forall a b.
    ElementExtractor (a -> b)
    -> ElementExtractor a -> ElementExtractor b)
-> (forall a b c.
    (a -> b -> c)
    -> ElementExtractor a -> ElementExtractor b -> ElementExtractor c)
-> (forall a b.
    ElementExtractor a -> ElementExtractor b -> ElementExtractor b)
-> (forall a b.
    ElementExtractor a -> ElementExtractor b -> ElementExtractor a)
-> Applicative ElementExtractor
ElementExtractor a -> ElementExtractor b -> ElementExtractor b
ElementExtractor a -> ElementExtractor b -> ElementExtractor a
ElementExtractor (a -> b)
-> ElementExtractor a -> ElementExtractor b
(a -> b -> c)
-> ElementExtractor a -> ElementExtractor b -> ElementExtractor c
forall a. a -> ElementExtractor a
forall a b.
ElementExtractor a -> ElementExtractor b -> ElementExtractor a
forall a b.
ElementExtractor a -> ElementExtractor b -> ElementExtractor b
forall a b.
ElementExtractor (a -> b)
-> ElementExtractor a -> ElementExtractor b
forall a b c.
(a -> b -> c)
-> ElementExtractor a -> ElementExtractor b -> ElementExtractor c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: ElementExtractor a -> ElementExtractor b -> ElementExtractor a
$c<* :: forall a b.
ElementExtractor a -> ElementExtractor b -> ElementExtractor a
*> :: ElementExtractor a -> ElementExtractor b -> ElementExtractor b
$c*> :: forall a b.
ElementExtractor a -> ElementExtractor b -> ElementExtractor b
liftA2 :: (a -> b -> c)
-> ElementExtractor a -> ElementExtractor b -> ElementExtractor c
$cliftA2 :: forall a b c.
(a -> b -> c)
-> ElementExtractor a -> ElementExtractor b -> ElementExtractor c
<*> :: ElementExtractor (a -> b)
-> ElementExtractor a -> ElementExtractor b
$c<*> :: forall a b.
ElementExtractor (a -> b)
-> ElementExtractor a -> ElementExtractor b
pure :: a -> ElementExtractor a
$cpure :: forall a. a -> ElementExtractor a
$cp1Applicative :: Functor ElementExtractor
Applicative, Applicative ElementExtractor
ElementExtractor a
Applicative ElementExtractor
-> (forall a. ElementExtractor a)
-> (forall a.
    ElementExtractor a -> ElementExtractor a -> ElementExtractor a)
-> (forall a. ElementExtractor a -> ElementExtractor [a])
-> (forall a. ElementExtractor a -> ElementExtractor [a])
-> Alternative ElementExtractor
ElementExtractor a -> ElementExtractor a -> ElementExtractor a
ElementExtractor a -> ElementExtractor [a]
ElementExtractor a -> ElementExtractor [a]
forall a. ElementExtractor a
forall a. ElementExtractor a -> ElementExtractor [a]
forall a.
ElementExtractor a -> ElementExtractor a -> ElementExtractor a
forall (f :: * -> *).
Applicative f
-> (forall a. f a)
-> (forall a. f a -> f a -> f a)
-> (forall a. f a -> f [a])
-> (forall a. f a -> f [a])
-> Alternative f
many :: ElementExtractor a -> ElementExtractor [a]
$cmany :: forall a. ElementExtractor a -> ElementExtractor [a]
some :: ElementExtractor a -> ElementExtractor [a]
$csome :: forall a. ElementExtractor a -> ElementExtractor [a]
<|> :: ElementExtractor a -> ElementExtractor a -> ElementExtractor a
$c<|> :: forall a.
ElementExtractor a -> ElementExtractor a -> ElementExtractor a
empty :: ElementExtractor a
$cempty :: forall a. ElementExtractor a
$cp1Alternative :: Applicative ElementExtractor
Alternative, a -> ElementExtractor b -> ElementExtractor a
(a -> b) -> ElementExtractor a -> ElementExtractor b
(forall a b. (a -> b) -> ElementExtractor a -> ElementExtractor b)
-> (forall a b. a -> ElementExtractor b -> ElementExtractor a)
-> Functor ElementExtractor
forall a b. a -> ElementExtractor b -> ElementExtractor a
forall a b. (a -> b) -> ElementExtractor a -> ElementExtractor b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> ElementExtractor b -> ElementExtractor a
$c<$ :: forall a b. a -> ElementExtractor b -> ElementExtractor a
fmap :: (a -> b) -> ElementExtractor a -> ElementExtractor b
$cfmap :: forall a b. (a -> b) -> ElementExtractor a -> ElementExtractor b
Functor, Applicative ElementExtractor
a -> ElementExtractor a
Applicative ElementExtractor
-> (forall a b.
    ElementExtractor a
    -> (a -> ElementExtractor b) -> ElementExtractor b)
-> (forall a b.
    ElementExtractor a -> ElementExtractor b -> ElementExtractor b)
-> (forall a. a -> ElementExtractor a)
-> Monad ElementExtractor
ElementExtractor a
-> (a -> ElementExtractor b) -> ElementExtractor b
ElementExtractor a -> ElementExtractor b -> ElementExtractor b
forall a. a -> ElementExtractor a
forall a b.
ElementExtractor a -> ElementExtractor b -> ElementExtractor b
forall a b.
ElementExtractor a
-> (a -> ElementExtractor b) -> ElementExtractor b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> ElementExtractor a
$creturn :: forall a. a -> ElementExtractor a
>> :: ElementExtractor a -> ElementExtractor b -> ElementExtractor b
$c>> :: forall a b.
ElementExtractor a -> ElementExtractor b -> ElementExtractor b
>>= :: ElementExtractor a
-> (a -> ElementExtractor b) -> ElementExtractor b
$c>>= :: forall a b.
ElementExtractor a
-> (a -> ElementExtractor b) -> ElementExtractor b
$cp1Monad :: Applicative ElementExtractor
Monad)


newtype ContentsExtractor a = ContentsExtractor (Internal.ContentsExtractor a)
 deriving (Functor ContentsExtractor
a -> ContentsExtractor a
Functor ContentsExtractor
-> (forall a. a -> ContentsExtractor a)
-> (forall a b.
    ContentsExtractor (a -> b)
    -> ContentsExtractor a -> ContentsExtractor b)
-> (forall a b c.
    (a -> b -> c)
    -> ContentsExtractor a
    -> ContentsExtractor b
    -> ContentsExtractor c)
-> (forall a b.
    ContentsExtractor a -> ContentsExtractor b -> ContentsExtractor b)
-> (forall a b.
    ContentsExtractor a -> ContentsExtractor b -> ContentsExtractor a)
-> Applicative ContentsExtractor
ContentsExtractor a -> ContentsExtractor b -> ContentsExtractor b
ContentsExtractor a -> ContentsExtractor b -> ContentsExtractor a
ContentsExtractor (a -> b)
-> ContentsExtractor a -> ContentsExtractor b
(a -> b -> c)
-> ContentsExtractor a
-> ContentsExtractor b
-> ContentsExtractor c
forall a. a -> ContentsExtractor a
forall a b.
ContentsExtractor a -> ContentsExtractor b -> ContentsExtractor a
forall a b.
ContentsExtractor a -> ContentsExtractor b -> ContentsExtractor b
forall a b.
ContentsExtractor (a -> b)
-> ContentsExtractor a -> ContentsExtractor b
forall a b c.
(a -> b -> c)
-> ContentsExtractor a
-> ContentsExtractor b
-> ContentsExtractor c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: ContentsExtractor a -> ContentsExtractor b -> ContentsExtractor a
$c<* :: forall a b.
ContentsExtractor a -> ContentsExtractor b -> ContentsExtractor a
*> :: ContentsExtractor a -> ContentsExtractor b -> ContentsExtractor b
$c*> :: forall a b.
ContentsExtractor a -> ContentsExtractor b -> ContentsExtractor b
liftA2 :: (a -> b -> c)
-> ContentsExtractor a
-> ContentsExtractor b
-> ContentsExtractor c
$cliftA2 :: forall a b c.
(a -> b -> c)
-> ContentsExtractor a
-> ContentsExtractor b
-> ContentsExtractor c
<*> :: ContentsExtractor (a -> b)
-> ContentsExtractor a -> ContentsExtractor b
$c<*> :: forall a b.
ContentsExtractor (a -> b)
-> ContentsExtractor a -> ContentsExtractor b
pure :: a -> ContentsExtractor a
$cpure :: forall a. a -> ContentsExtractor a
$cp1Applicative :: Functor ContentsExtractor
Applicative, Applicative ContentsExtractor
ContentsExtractor a
Applicative ContentsExtractor
-> (forall a. ContentsExtractor a)
-> (forall a.
    ContentsExtractor a -> ContentsExtractor a -> ContentsExtractor a)
-> (forall a. ContentsExtractor a -> ContentsExtractor [a])
-> (forall a. ContentsExtractor a -> ContentsExtractor [a])
-> Alternative ContentsExtractor
ContentsExtractor a -> ContentsExtractor a -> ContentsExtractor a
ContentsExtractor a -> ContentsExtractor [a]
ContentsExtractor a -> ContentsExtractor [a]
forall a. ContentsExtractor a
forall a. ContentsExtractor a -> ContentsExtractor [a]
forall a.
ContentsExtractor a -> ContentsExtractor a -> ContentsExtractor a
forall (f :: * -> *).
Applicative f
-> (forall a. f a)
-> (forall a. f a -> f a -> f a)
-> (forall a. f a -> f [a])
-> (forall a. f a -> f [a])
-> Alternative f
many :: ContentsExtractor a -> ContentsExtractor [a]
$cmany :: forall a. ContentsExtractor a -> ContentsExtractor [a]
some :: ContentsExtractor a -> ContentsExtractor [a]
$csome :: forall a. ContentsExtractor a -> ContentsExtractor [a]
<|> :: ContentsExtractor a -> ContentsExtractor a -> ContentsExtractor a
$c<|> :: forall a.
ContentsExtractor a -> ContentsExtractor a -> ContentsExtractor a
empty :: ContentsExtractor a
$cempty :: forall a. ContentsExtractor a
$cp1Alternative :: Applicative ContentsExtractor
Alternative, a -> ContentsExtractor b -> ContentsExtractor a
(a -> b) -> ContentsExtractor a -> ContentsExtractor b
(forall a b.
 (a -> b) -> ContentsExtractor a -> ContentsExtractor b)
-> (forall a b. a -> ContentsExtractor b -> ContentsExtractor a)
-> Functor ContentsExtractor
forall a b. a -> ContentsExtractor b -> ContentsExtractor a
forall a b. (a -> b) -> ContentsExtractor a -> ContentsExtractor b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> ContentsExtractor b -> ContentsExtractor a
$c<$ :: forall a b. a -> ContentsExtractor b -> ContentsExtractor a
fmap :: (a -> b) -> ContentsExtractor a -> ContentsExtractor b
$cfmap :: forall a b. (a -> b) -> ContentsExtractor a -> ContentsExtractor b
Functor, Applicative ContentsExtractor
a -> ContentsExtractor a
Applicative ContentsExtractor
-> (forall a b.
    ContentsExtractor a
    -> (a -> ContentsExtractor b) -> ContentsExtractor b)
-> (forall a b.
    ContentsExtractor a -> ContentsExtractor b -> ContentsExtractor b)
-> (forall a. a -> ContentsExtractor a)
-> Monad ContentsExtractor
ContentsExtractor a
-> (a -> ContentsExtractor b) -> ContentsExtractor b
ContentsExtractor a -> ContentsExtractor b -> ContentsExtractor b
forall a. a -> ContentsExtractor a
forall a b.
ContentsExtractor a -> ContentsExtractor b -> ContentsExtractor b
forall a b.
ContentsExtractor a
-> (a -> ContentsExtractor b) -> ContentsExtractor b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> ContentsExtractor a
$creturn :: forall a. a -> ContentsExtractor a
>> :: ContentsExtractor a -> ContentsExtractor b -> ContentsExtractor b
$c>> :: forall a b.
ContentsExtractor a -> ContentsExtractor b -> ContentsExtractor b
>>= :: ContentsExtractor a
-> (a -> ContentsExtractor b) -> ContentsExtractor b
$c>>= :: forall a b.
ContentsExtractor a
-> (a -> ContentsExtractor b) -> ContentsExtractor b
$cp1Monad :: Applicative ContentsExtractor
Monad)

--------------------------------------------------------------------------------
 
-- | @extractElement p element@ extracts @element@ with @p@.
extractElement :: ElementExtractor a -> XML.Element -> Either ExtractionErr a
extractElement :: ElementExtractor a -> Element -> Either ExtractionErr a
extractElement (ElementExtractor ElementExtractor a
p) Element
elem = Result ExtractionErr a -> Either ExtractionErr a
forall a b. Result a b -> Either a b
toEither (Result ExtractionErr a -> Either ExtractionErr a)
-> Result ExtractionErr a -> Either ExtractionErr a
forall a b. (a -> b) -> a -> b
$ ElementExtractor a -> Element -> Path -> Result ExtractionErr a
forall a.
ElementExtractor a -> Element -> Path -> Result ExtractionErr a
Internal.runElementExtractor ElementExtractor a
p Element
elem []


-- | @attrib name@ extracts the value of attribute @name@.
attrib :: String -> ElementExtractor String
attrib :: String -> ElementExtractor String
attrib = ElementExtractor String -> ElementExtractor String
forall a. ElementExtractor a -> ElementExtractor a
ElementExtractor (ElementExtractor String -> ElementExtractor String)
-> (String -> ElementExtractor String)
-> String
-> ElementExtractor String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ElementExtractor String
Internal.attrib


-- | @attribAs name f@ extracts the value of attribute @name@ and runs
-- it through a conversion/validation function.
--
-- The conversion function takes a string with the value and returns
-- either a description of the expected format of the value or the
-- converted value.
attribAs :: String -> (String -> Either String a) -> ElementExtractor a
attribAs :: String -> (String -> Either String a) -> ElementExtractor a
attribAs String
name = ElementExtractor a -> ElementExtractor a
forall a. ElementExtractor a -> ElementExtractor a
ElementExtractor (ElementExtractor a -> ElementExtractor a)
-> ((String -> Either String a) -> ElementExtractor a)
-> (String -> Either String a)
-> ElementExtractor a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> (String -> Either String a) -> ElementExtractor a
forall a.
String -> (String -> Either String a) -> ElementExtractor a
Internal.attribAs String
name)


-- | @children p@ extract only child elements with @p@.
children :: ContentsExtractor a -> ElementExtractor a
children :: ContentsExtractor a -> ElementExtractor a
children (ContentsExtractor ContentsExtractor a
p) = ElementExtractor a -> ElementExtractor a
forall a. ElementExtractor a -> ElementExtractor a
ElementExtractor (ContentsExtractor a -> ElementExtractor a
forall a. ContentsExtractor a -> ElementExtractor a
Internal.children ContentsExtractor a
p)


-- | @contents p@ extract contents with @p@.
contents :: ContentsExtractor a -> ElementExtractor a
contents :: ContentsExtractor a -> ElementExtractor a
contents (ContentsExtractor ContentsExtractor a
p) = ElementExtractor a -> ElementExtractor a
forall a. ElementExtractor a -> ElementExtractor a
ElementExtractor (ContentsExtractor a -> ElementExtractor a
forall a. ContentsExtractor a -> ElementExtractor a
Internal.contents ContentsExtractor a
p)

--------------------------------------------------------------------------------

-- | @extractContents p contents@ extracts the contents with @p@.
extractContents :: ContentsExtractor a -> [XML.Content] -> Either ExtractionErr a
extractContents :: ContentsExtractor a -> [Content] -> Either ExtractionErr a
extractContents (ContentsExtractor ContentsExtractor a
p) [Content]
cs =
  Result ExtractionErr a -> Either ExtractionErr a
forall a b. Result a b -> Either a b
toEither ((a, Ctx) -> a
forall a b. (a, b) -> a
fst ((a, Ctx) -> a)
-> Result ExtractionErr (a, Ctx) -> Result ExtractionErr a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ContentsExtractor a
-> [Content] -> Int -> Path -> Result ExtractionErr (a, Ctx)
forall a.
ContentsExtractor a
-> [Content] -> Int -> Path -> Result ExtractionErr (a, Ctx)
Internal.runContentsExtractor ContentsExtractor a
p [Content]
cs Int
1 [])


-- | Using 'Text.XML.Light.Input.parseXMLDoc' produces a single
-- 'Element'. Such an element can be extracted using this function.
extractDocContents :: ContentsExtractor a -> XML.Element -> Either ExtractionErr a
extractDocContents :: ContentsExtractor a -> Element -> Either ExtractionErr a
extractDocContents ContentsExtractor a
p = ContentsExtractor a -> [Content] -> Either ExtractionErr a
forall a.
ContentsExtractor a -> [Content] -> Either ExtractionErr a
extractContents ContentsExtractor a
p ([Content] -> Either ExtractionErr a)
-> (Element -> [Content]) -> Element -> Either ExtractionErr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Content -> [Content]
forall (m :: * -> *) a. Monad m => a -> m a
return (Content -> [Content])
-> (Element -> Content) -> Element -> [Content]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Element -> Content
Elem


-- | @only p@ fails if there is more contents than extracted by @p@.
--
-- > only p = p <* eoc
only :: ContentsExtractor a -> ContentsExtractor a
only :: ContentsExtractor a -> ContentsExtractor a
only ContentsExtractor a
p = ContentsExtractor a
p ContentsExtractor a -> ContentsExtractor () -> ContentsExtractor a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ContentsExtractor ()
eoc


-- | Succeeds only when there is no more content.
eoc :: ContentsExtractor ()
eoc :: ContentsExtractor ()
eoc = ContentsExtractor () -> ContentsExtractor ()
forall a. ContentsExtractor a -> ContentsExtractor a
ContentsExtractor ContentsExtractor ()
Internal.eoc


-- | @element name p@ extracts a @name@ element with @p@.
element :: String -> ElementExtractor a -> ContentsExtractor a
element :: String -> ElementExtractor a -> ContentsExtractor a
element String
name (ElementExtractor ElementExtractor a
a) = ContentsExtractor a -> ContentsExtractor a
forall a. ContentsExtractor a -> ContentsExtractor a
ContentsExtractor (ContentsExtractor a -> ContentsExtractor a)
-> ContentsExtractor a -> ContentsExtractor a
forall a b. (a -> b) -> a -> b
$ String -> ElementExtractor a -> ContentsExtractor a
forall a. String -> ElementExtractor a -> ContentsExtractor a
Internal.element String
name ElementExtractor a
a


-- | Extracts text.
text :: ContentsExtractor String
text :: ContentsExtractor String
text = ContentsExtractor String -> ContentsExtractor String
forall a. ContentsExtractor a -> ContentsExtractor a
ContentsExtractor ContentsExtractor String
Internal.text


-- | Extracts text applied to a conversion function.
textAs :: (String -> Either Err a) -> ContentsExtractor a
textAs :: (String -> Either Err a) -> ContentsExtractor a
textAs = ContentsExtractor a -> ContentsExtractor a
forall a. ContentsExtractor a -> ContentsExtractor a
ContentsExtractor (ContentsExtractor a -> ContentsExtractor a)
-> ((String -> Either Err a) -> ContentsExtractor a)
-> (String -> Either Err a)
-> ContentsExtractor a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> Either Err a) -> ContentsExtractor a
forall a. (String -> Either Err a) -> ContentsExtractor a
Internal.textAs


-- | Extracts first matching.
choice :: [ContentsExtractor a] -> ContentsExtractor a
choice :: [ContentsExtractor a] -> ContentsExtractor a
choice = (ContentsExtractor a -> ContentsExtractor a -> ContentsExtractor a)
-> ContentsExtractor a
-> [ContentsExtractor a]
-> ContentsExtractor a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ContentsExtractor a -> ContentsExtractor a -> ContentsExtractor a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>) ContentsExtractor a
forall (f :: * -> *) a. Alternative f => f a
empty


-- | Extracts one 'Content' item.
anyContent :: ContentsExtractor Content
anyContent :: ContentsExtractor Content
anyContent = ContentsExtractor Content -> ContentsExtractor Content
forall a. ContentsExtractor a -> ContentsExtractor a
ContentsExtractor ContentsExtractor Content
Internal.anyContent


-- | Convenience function to convert extraction errors to string
-- messages using 'showExtractionErr'.
--
-- > eitherMessageOrValue = either (Left . showExtractionErr) Right
eitherMessageOrValue :: Either ExtractionErr a -> Either String a
eitherMessageOrValue :: Either ExtractionErr a -> Either String a
eitherMessageOrValue = (ExtractionErr -> Either String a)
-> (a -> Either String a)
-> Either ExtractionErr a
-> Either String a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (String -> Either String a
forall a b. a -> Either a b
Left (String -> Either String a)
-> (ExtractionErr -> String) -> ExtractionErr -> Either String a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExtractionErr -> String
showExtractionErr) a -> Either String a
forall a b. b -> Either a b
Right