module XmlParser
  ( -- * Execution
    parseByteString,
    parseLazyByteString,
    parseFile,
    parseElementAst,

    -- * Parsers by context

    -- ** Element
    AstParser.Element,
    AstParser.elementName,
    AstParser.elementNameIs,
    AstParser.children,
    AstParser.childrenByName,
    AstParser.attributesByName,
    AstParser.astElement,

    -- ** Nodes
    AstParser.Nodes,
    AstParser.elementNode,
    AstParser.contentNode,

    -- ** ByName
    AstParser.ByName,
    AstParser.byName,

    -- ** Content
    AstParser.Content,
    AstParser.textContent,
    AstParser.narrowedContent,
    AstParser.refinedContent,
    AstParser.enumContent,
    AstParser.attoparsedContent,
    AstParser.qNameContent,
  )
where

import qualified Data.ByteString.Lazy as Lbs
import qualified Text.XML as XmlConduit
import qualified XmlParser.AstParser as AstParser
import XmlParser.Prelude
import qualified XmlParser.XmlConduitWrapper as XmlConduitWrapper

-- |
-- Parse XML bytestring.
parseByteString :: AstParser.Element a -> ByteString -> Either Text a
parseByteString :: Element a -> ByteString -> Either Text a
parseByteString Element a
astParser ByteString
input =
  ByteString -> Either Text Document
XmlConduitWrapper.parseByteString ByteString
input Either Text Document
-> (Document -> Either Text a) -> Either Text a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Element a -> Document -> Either Text a
forall a. Element a -> Document -> Either Text a
parseDocumentAst Element a
astParser

-- |
-- Parse XML lazy bytestring.
parseLazyByteString :: AstParser.Element a -> Lbs.ByteString -> Either Text a
parseLazyByteString :: Element a -> ByteString -> Either Text a
parseLazyByteString Element a
astParser ByteString
input =
  ByteString -> Either Text Document
XmlConduitWrapper.parseLazyByteString ByteString
input Either Text Document
-> (Document -> Either Text a) -> Either Text a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Element a -> Document -> Either Text a
forall a. Element a -> Document -> Either Text a
parseDocumentAst Element a
astParser

-- |
-- Parse XML file.
parseFile :: AstParser.Element a -> FilePath -> IO (Either Text a)
parseFile :: Element a -> FilePath -> IO (Either Text a)
parseFile Element a
astParser FilePath
path =
  (Either Text Document -> Either Text a)
-> IO (Either Text Document) -> IO (Either Text a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Either Text Document
-> (Document -> Either Text a) -> Either Text a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Element a -> Document -> Either Text a
forall a. Element a -> Document -> Either Text a
parseDocumentAst Element a
astParser) (IO (Either Text Document) -> IO (Either Text a))
-> IO (Either Text Document) -> IO (Either Text a)
forall a b. (a -> b) -> a -> b
$
    FilePath -> IO (Either Text Document)
XmlConduitWrapper.parseFile FilePath
path

parseDocumentAst :: AstParser.Element a -> XmlConduit.Document -> Either Text a
parseDocumentAst :: Element a -> Document -> Either Text a
parseDocumentAst Element a
astParser =
  Element a -> Element -> Either Text a
forall a. Element a -> Element -> Either Text a
parseElementAst Element a
astParser (Element -> Either Text a)
-> (Document -> Element) -> Document -> Either Text a
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Document -> Element
XmlConduit.documentRoot

-- |
-- Parse an \"xml-conduit\" element AST.
parseElementAst :: AstParser.Element a -> XmlConduit.Element -> Either Text a
parseElementAst :: Element a -> Element -> Either Text a
parseElementAst Element a
astParser =
  (ElementError -> Text) -> Either ElementError a -> Either Text a
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first ElementError -> Text
AstParser.renderElementError (Either ElementError a -> Either Text a)
-> (Element -> Either ElementError a) -> Element -> Either Text a
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Element a -> Element -> Either ElementError a
forall a. Element a -> Element -> Either ElementError a
AstParser.parseElement Element a
astParser