{-# LANGUAGE RankNTypes #-}
module Text.XML.Expat.StreamParser.Conduit where
import Text.XML.Expat.StreamParser
import Text.XML.Expat.SAX
import Data.List.Class
import Control.Monad.ListT (ListT(..))
import Data.Conduit
import Data.Text
import Data.ByteString
import Data.Functor.Identity

-- | An EventParser in the ConduitT monad.
type ConduitEventParser e o m a =
  (forall i.EventParser (ListT (ConduitT i o m)) e (ConduitT i o m) a)

-- | Convert an EventParser in the ConduitT monad to a ConduitT that
-- takes bytestrings and produces the result of the parser.  You can
-- use `lift . yield` to stream values as a side effect in the
-- ConduitT monad, or `lift effect` to run any effect in the ConduitT
-- monad.
streamParserToConduit :: Monad m
                      => ParseOptions Text Text
                      -> ConduitEventParser e o m a
                      -> ConduitT ByteString o m (Either (EventParseError e,
                                                          Maybe
                                                          XMLParseLocation)
                                                  a)
streamParserToConduit :: ParseOptions Text Text
-> ConduitEventParser e o m a
-> ConduitT
     ByteString
     o
     m
     (Either (EventParseError e, Maybe XMLParseLocation) a)
streamParserToConduit ParseOptions Text Text
opts ConduitEventParser e o m a
parser =
  EventParser
  (ListT (ConduitT ByteString o m))
  e
  (ItemM (ListT (ConduitT ByteString o m)))
  a
-> ListT (ConduitT ByteString o m) EventLoc
-> ItemM
     (ListT (ConduitT ByteString o m))
     (Either (EventParseError e, Maybe XMLParseLocation) a)
forall (l :: * -> *) e a.
List l =>
EventParser l e (ItemM l) a
-> l EventLoc
-> ItemM l (Either (EventParseError e, Maybe XMLParseLocation) a)
runEventParser EventParser
  (ListT (ConduitT ByteString o m))
  e
  (ItemM (ListT (ConduitT ByteString o m)))
  a
ConduitEventParser e o m a
parser (ListT (ConduitT ByteString o m) EventLoc
 -> ItemM
      (ListT (ConduitT ByteString o m))
      (Either (EventParseError e, Maybe XMLParseLocation) a))
-> ListT (ConduitT ByteString o m) EventLoc
-> ItemM
     (ListT (ConduitT ByteString o m))
     (Either (EventParseError e, Maybe XMLParseLocation) a)
forall a b. (a -> b) -> a -> b
$ ParseOptions Text Text
-> ListT (ConduitT ByteString o m) ByteString
-> ListT (ConduitT ByteString o m) EventLoc
forall tag text (l :: * -> *).
(GenericXMLString tag, GenericXMLString text, List l) =>
ParseOptions tag text
-> l ByteString -> l (SAXEvent tag text, XMLParseLocation)
parseLocationsG ParseOptions Text Text
opts ListT (ConduitT ByteString o m) ByteString
forall a o. ListT (ConduitT a o m) a
bsStream
  where
    bsStream :: ListT (ConduitT a o m) a
bsStream = ConduitT a o m (ListItem (ListT (ConduitT a o m)) a)
-> ListT (ConduitT a o m) a
forall (m :: * -> *) a. m (ListItem (ListT m) a) -> ListT m a
ListT (ConduitT a o m (ListItem (ListT (ConduitT a o m)) a)
 -> ListT (ConduitT a o m) a)
-> ConduitT a o m (ListItem (ListT (ConduitT a o m)) a)
-> ListT (ConduitT a o m) a
forall a b. (a -> b) -> a -> b
$ do
      Maybe a
next <- ConduitT a o m (Maybe a)
forall (m :: * -> *) i. Monad m => Consumer i m (Maybe i)
await
      case Maybe a
next of
        Maybe a
Nothing -> ListItem (ListT (ConduitT a o m)) a
-> ConduitT a o m (ListItem (ListT (ConduitT a o m)) a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ListItem (ListT (ConduitT a o m)) a
forall (l :: * -> *) a. ListItem l a
Nil
        Just a
el -> ListItem (ListT (ConduitT a o m)) a
-> ConduitT a o m (ListItem (ListT (ConduitT a o m)) a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ListItem (ListT (ConduitT a o m)) a
 -> ConduitT a o m (ListItem (ListT (ConduitT a o m)) a))
-> ListItem (ListT (ConduitT a o m)) a
-> ConduitT a o m (ListItem (ListT (ConduitT a o m)) a)
forall a b. (a -> b) -> a -> b
$ a
-> ListT (ConduitT a o m) a -> ListItem (ListT (ConduitT a o m)) a
forall (l :: * -> *) a. a -> l a -> ListItem l a
Cons a
el ListT (ConduitT a o m) a
bsStream