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 :: forall a. Element a -> ByteString -> Either Text a
parseByteString Element a
astParser ByteString
input =
  ByteString -> Either Text Document
XmlConduitWrapper.parseByteString ByteString
input forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= 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 :: forall a. Element a -> ByteString -> Either Text a
parseLazyByteString Element a
astParser ByteString
input =
  ByteString -> Either Text Document
XmlConduitWrapper.parseLazyByteString ByteString
input forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= 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 :: forall a. Element a -> FilePath -> IO (Either Text a)
parseFile Element a
astParser FilePath
path =
  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a. Element a -> Document -> Either Text a
parseDocumentAst Element a
astParser) 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 :: forall a. Element a -> Document -> Either Text a
parseDocumentAst Element a
astParser =
  forall a. Element a -> Element -> Either Text a
parseElementAst Element a
astParser 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 :: forall a. Element a -> Element -> Either Text a
parseElementAst Element a
astParser =
  forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first ElementError -> Text
AstParser.renderElementError forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall a. Element a -> Element -> Either ElementError a
AstParser.parseElement Element a
astParser