packages feed

xml-conduit 1.7.1.2 → 1.8.0

raw patch · 9 files changed

+297/−303 lines, 9 filesdep −blaze-builderdep ~bytestringdep ~conduitdep ~conduit-extraPVP ok

version bump matches the API change (PVP)

Dependencies removed: blaze-builder

Dependency ranges changed: bytestring, conduit, conduit-extra, resourcet

API changes (from Hackage documentation)

- Text.XML: fromEvents :: MonadThrow m => Consumer EventPos m Document
+ Text.XML: fromEvents :: MonadThrow m => ConduitT EventPos o m Document
- Text.XML: renderBytes :: (PrimMonad base, MonadBase base m) => RenderSettings -> Document -> ConduitM a ByteString m ()
+ Text.XML: renderBytes :: PrimMonad m => RenderSettings -> Document -> ConduitT i ByteString m ()
- Text.XML: sinkDoc :: MonadThrow m => ParseSettings -> Consumer ByteString m Document
+ Text.XML: sinkDoc :: MonadThrow m => ParseSettings -> ConduitT ByteString o m Document
- Text.XML: sinkTextDoc :: MonadThrow m => ParseSettings -> Consumer Text m Document
+ Text.XML: sinkTextDoc :: MonadThrow m => ParseSettings -> ConduitT Text o m Document
- Text.XML.Stream.Parse: choose :: Monad m => [ConduitM Event o m (Maybe a)] -> ConduitM Event o m (Maybe a)
+ Text.XML.Stream.Parse: choose :: Monad m => [ConduitT Event o m (Maybe a)] -> ConduitT Event o m (Maybe a)
- Text.XML.Stream.Parse: content :: MonadThrow m => Consumer Event m Text
+ Text.XML.Stream.Parse: content :: MonadThrow m => ConduitT Event o m Text
- Text.XML.Stream.Parse: contentMaybe :: MonadThrow m => Consumer Event m (Maybe Text)
+ Text.XML.Stream.Parse: contentMaybe :: MonadThrow m => ConduitT Event o m (Maybe Text)
- Text.XML.Stream.Parse: detectUtf :: MonadThrow m => Conduit ByteString m Text
+ Text.XML.Stream.Parse: detectUtf :: MonadThrow m => ConduitT ByteString Text m ()
- Text.XML.Stream.Parse: ignoreAllTreesContent :: MonadThrow m => ConduitM Event o m (Maybe ())
+ Text.XML.Stream.Parse: ignoreAllTreesContent :: MonadThrow m => ConduitT Event o m (Maybe ())
- Text.XML.Stream.Parse: ignoreAnyTreeContent :: MonadThrow m => ConduitM Event o m (Maybe ())
+ Text.XML.Stream.Parse: ignoreAnyTreeContent :: MonadThrow m => ConduitT Event o m (Maybe ())
- Text.XML.Stream.Parse: ignoreEmptyTag :: MonadThrow m => NameMatcher a -> ConduitM Event o m (Maybe ())
+ Text.XML.Stream.Parse: ignoreEmptyTag :: MonadThrow m => NameMatcher a -> ConduitT Event o m (Maybe ())
- Text.XML.Stream.Parse: ignoreTag :: MonadThrow m => NameMatcher a -> ConduitM Event o m (Maybe ())
+ Text.XML.Stream.Parse: ignoreTag :: MonadThrow m => NameMatcher a -> ConduitT Event o m (Maybe ())
- Text.XML.Stream.Parse: ignoreTree :: MonadThrow m => NameMatcher a -> ConduitM Event o m (Maybe ())
+ Text.XML.Stream.Parse: ignoreTree :: MonadThrow m => NameMatcher a -> ConduitT Event o m (Maybe ())
- Text.XML.Stream.Parse: ignoreTreeContent :: MonadThrow m => NameMatcher a -> ConduitM Event o m (Maybe ())
+ Text.XML.Stream.Parse: ignoreTreeContent :: MonadThrow m => NameMatcher a -> ConduitT Event o m (Maybe ())
- Text.XML.Stream.Parse: many :: Monad m => ConduitM Event o m (Maybe a) -> ConduitM Event o m [a]
+ Text.XML.Stream.Parse: many :: Monad m => ConduitT Event o m (Maybe a) -> ConduitT Event o m [a]
- Text.XML.Stream.Parse: many' :: MonadThrow m => ConduitM Event o m (Maybe a) -> ConduitM Event o m [a]
+ Text.XML.Stream.Parse: many' :: MonadThrow m => ConduitT Event o m (Maybe a) -> ConduitT Event o m [a]
- Text.XML.Stream.Parse: manyIgnore :: Monad m => ConduitM Event o m (Maybe a) -> ConduitM Event o m (Maybe b) -> ConduitM Event o m [a]
+ Text.XML.Stream.Parse: manyIgnore :: Monad m => ConduitT Event o m (Maybe a) -> ConduitT Event o m (Maybe b) -> ConduitT Event o m [a]
- Text.XML.Stream.Parse: manyIgnoreYield :: MonadThrow m => ConduitM Event b m (Maybe b) -> ConduitM Event b m (Maybe ()) -> Conduit Event m b
+ Text.XML.Stream.Parse: manyIgnoreYield :: MonadThrow m => ConduitT Event b m (Maybe b) -> ConduitT Event b m (Maybe ()) -> ConduitT Event b m ()
- Text.XML.Stream.Parse: manyYield :: Monad m => ConduitM a b m (Maybe b) -> Conduit a m b
+ Text.XML.Stream.Parse: manyYield :: Monad m => ConduitT a b m (Maybe b) -> ConduitT a b m ()
- Text.XML.Stream.Parse: manyYield' :: MonadThrow m => ConduitM Event b m (Maybe b) -> Conduit Event m b
+ Text.XML.Stream.Parse: manyYield' :: MonadThrow m => ConduitT Event b m (Maybe b) -> ConduitT Event b m ()
- Text.XML.Stream.Parse: many_ :: MonadThrow m => ConduitM Event o m (Maybe a) -> ConduitM Event o m ()
+ Text.XML.Stream.Parse: many_ :: MonadThrow m => ConduitT Event o m (Maybe a) -> ConduitT Event o m ()
- Text.XML.Stream.Parse: orE :: Monad m => Consumer Event m (Maybe a) -> Consumer Event m (Maybe a) -> Consumer Event m (Maybe a)
+ Text.XML.Stream.Parse: orE :: Monad m => ConduitT Event o m (Maybe a) -> ConduitT Event o m (Maybe a) -> ConduitT Event o m (Maybe a)
- Text.XML.Stream.Parse: parseBytes :: MonadThrow m => ParseSettings -> Conduit ByteString m Event
+ Text.XML.Stream.Parse: parseBytes :: MonadThrow m => ParseSettings -> ConduitT ByteString Event m ()
- Text.XML.Stream.Parse: parseBytesPos :: MonadThrow m => ParseSettings -> Conduit ByteString m EventPos
+ Text.XML.Stream.Parse: parseBytesPos :: MonadThrow m => ParseSettings -> ConduitT ByteString EventPos m ()
- Text.XML.Stream.Parse: parseFile :: MonadResource m => ParseSettings -> FilePath -> Producer m Event
+ Text.XML.Stream.Parse: parseFile :: MonadResource m => ParseSettings -> FilePath -> ConduitT i Event m ()
- Text.XML.Stream.Parse: parseLBS :: MonadThrow m => ParseSettings -> ByteString -> Producer m Event
+ Text.XML.Stream.Parse: parseLBS :: MonadThrow m => ParseSettings -> ByteString -> ConduitT i Event m ()
- Text.XML.Stream.Parse: parseText :: MonadThrow m => ParseSettings -> Conduit Text m EventPos
+ Text.XML.Stream.Parse: parseText :: MonadThrow m => ParseSettings -> ConduitT Text EventPos m ()
- Text.XML.Stream.Parse: parseText' :: MonadThrow m => ParseSettings -> Conduit Text m Event
+ Text.XML.Stream.Parse: parseText' :: MonadThrow m => ParseSettings -> ConduitT Text Event m ()
- Text.XML.Stream.Parse: parseTextPos :: MonadThrow m => ParseSettings -> Conduit Text m EventPos
+ Text.XML.Stream.Parse: parseTextPos :: MonadThrow m => ParseSettings -> ConduitT Text EventPos m ()
- Text.XML.Stream.Parse: tag :: MonadThrow m => NameMatcher a -> (a -> AttrParser b) -> (b -> ConduitM Event o m c) -> ConduitM Event o m (Maybe c)
+ Text.XML.Stream.Parse: tag :: MonadThrow m => NameMatcher a -> (a -> AttrParser b) -> (b -> ConduitT Event o m c) -> ConduitT Event o m (Maybe c)
- Text.XML.Stream.Parse: tag' :: MonadThrow m => NameMatcher a -> AttrParser b -> (b -> ConduitM Event o m c) -> ConduitM Event o m (Maybe c)
+ Text.XML.Stream.Parse: tag' :: MonadThrow m => NameMatcher a -> AttrParser b -> (b -> ConduitT Event o m c) -> ConduitT Event o m (Maybe c)
- Text.XML.Stream.Parse: tagIgnoreAttrs :: MonadThrow m => NameMatcher a -> ConduitM Event o m b -> ConduitM Event o m (Maybe b)
+ Text.XML.Stream.Parse: tagIgnoreAttrs :: MonadThrow m => NameMatcher a -> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
- Text.XML.Stream.Parse: tagNoAttr :: MonadThrow m => NameMatcher a -> ConduitM Event o m b -> ConduitM Event o m (Maybe b)
+ Text.XML.Stream.Parse: tagNoAttr :: MonadThrow m => NameMatcher a -> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
- Text.XML.Stream.Parse: takeAllTreesContent :: MonadThrow m => ConduitM Event Event m (Maybe ())
+ Text.XML.Stream.Parse: takeAllTreesContent :: MonadThrow m => ConduitT Event Event m (Maybe ())
- Text.XML.Stream.Parse: takeAnyTreeContent :: MonadThrow m => ConduitM Event Event m (Maybe ())
+ Text.XML.Stream.Parse: takeAnyTreeContent :: MonadThrow m => ConduitT Event Event m (Maybe ())
- Text.XML.Stream.Parse: takeContent :: MonadThrow m => ConduitM Event Event m (Maybe ())
+ Text.XML.Stream.Parse: takeContent :: MonadThrow m => ConduitT Event Event m (Maybe ())
- Text.XML.Stream.Parse: takeTree :: MonadThrow m => NameMatcher a -> AttrParser b -> ConduitM Event Event m (Maybe ())
+ Text.XML.Stream.Parse: takeTree :: MonadThrow m => NameMatcher a -> AttrParser b -> ConduitT Event Event m (Maybe ())
- Text.XML.Stream.Parse: takeTreeContent :: MonadThrow m => NameMatcher a -> AttrParser b -> ConduitM Event Event m (Maybe ())
+ Text.XML.Stream.Parse: takeTreeContent :: MonadThrow m => NameMatcher a -> AttrParser b -> ConduitT Event Event m (Maybe ())
- Text.XML.Stream.Render: content :: (Monad m) => Text -> Source m Event
+ Text.XML.Stream.Render: content :: (Monad m) => Text -> ConduitT i Event m ()
- Text.XML.Stream.Render: prettify :: Monad m => Conduit (Flush Event) m (Flush Event)
+ Text.XML.Stream.Render: prettify :: Monad m => ConduitT (Flush Event) (Flush Event) m ()
- Text.XML.Stream.Render: renderBuilder :: Monad m => RenderSettings -> Conduit Event m Builder
+ Text.XML.Stream.Render: renderBuilder :: Monad m => RenderSettings -> ConduitT Event Builder m ()
- Text.XML.Stream.Render: renderBuilderFlush :: Monad m => RenderSettings -> Conduit (Flush Event) m (Flush Builder)
+ Text.XML.Stream.Render: renderBuilderFlush :: Monad m => RenderSettings -> ConduitT (Flush Event) (Flush Builder) m ()
- Text.XML.Stream.Render: renderBytes :: (PrimMonad base, MonadBase base m) => RenderSettings -> ConduitM Event ByteString m ()
+ Text.XML.Stream.Render: renderBytes :: PrimMonad m => RenderSettings -> ConduitT Event ByteString m ()
- Text.XML.Stream.Render: renderText :: (MonadThrow m, MonadBase base m, PrimMonad base) => RenderSettings -> ConduitM Event Text m ()
+ Text.XML.Stream.Render: renderText :: (PrimMonad m, MonadThrow m) => RenderSettings -> ConduitT Event Text m ()
- Text.XML.Stream.Render: tag :: (Monad m) => Name -> Attributes -> Source m Event -> Source m Event
+ Text.XML.Stream.Render: tag :: (Monad m) => Name -> Attributes -> ConduitT i Event m () -> ConduitT i Event m ()
- Text.XML.Unresolved: elementFromEvents :: MonadThrow m => Consumer EventPos m (Maybe Element)
+ Text.XML.Unresolved: elementFromEvents :: MonadThrow m => ConduitT EventPos o m (Maybe Element)
- Text.XML.Unresolved: fromEvents :: MonadThrow m => Consumer EventPos m Document
+ Text.XML.Unresolved: fromEvents :: MonadThrow m => ConduitT EventPos o m Document
- Text.XML.Unresolved: renderBuilder :: Monad m => RenderSettings -> Document -> Producer m Builder
+ Text.XML.Unresolved: renderBuilder :: Monad m => RenderSettings -> Document -> ConduitT i Builder m ()
- Text.XML.Unresolved: renderBytes :: (MonadBase base m, PrimMonad base) => RenderSettings -> Document -> ConduitM a ByteString m ()
+ Text.XML.Unresolved: renderBytes :: PrimMonad m => RenderSettings -> Document -> ConduitT i ByteString m ()
- Text.XML.Unresolved: renderText :: (PrimMonad base, MonadBase base m, MonadThrow m) => RenderSettings -> Document -> ConduitM a Text m ()
+ Text.XML.Unresolved: renderText :: (MonadThrow m, PrimMonad m) => RenderSettings -> Document -> ConduitT i Text m ()
- Text.XML.Unresolved: sinkDoc :: MonadThrow m => ParseSettings -> Consumer ByteString m Document
+ Text.XML.Unresolved: sinkDoc :: MonadThrow m => ParseSettings -> ConduitT ByteString o m Document
- Text.XML.Unresolved: sinkTextDoc :: MonadThrow m => ParseSettings -> Consumer Text m Document
+ Text.XML.Unresolved: sinkTextDoc :: MonadThrow m => ParseSettings -> ConduitT Text o m Document

Files

ChangeLog.md view
@@ -1,3 +1,7 @@+## 1.8.0++* Upgrade to conduit 1.3.0+ ## 1.7.1  * Add `psDecodeIllegalCharacters` field in `ParseSettings` to specify how illegal characters references should be decoded
Text/XML.hs view
@@ -74,13 +74,12 @@     , fromXMLElement     ) where +import           Conduit import           Control.Applicative          ((<$>)) import           Control.DeepSeq              (NFData (rnf)) import           Control.Exception            (Exception, SomeException, handle,                                                throw, throwIO)-import           Control.Monad.ST             (runST)-import           Control.Monad.Trans.Resource (MonadThrow, monadThrow,-                                               runExceptionT, runResourceT)+import           Control.Monad.Trans.Resource (MonadThrow, throwM) import           Data.ByteString              (ByteString) import qualified Data.ByteString.Lazy         as L import           Data.Data                    (Data)@@ -104,7 +103,6 @@ import qualified Text.XML.Unresolved          as D  import           Control.Monad.Trans.Class    (lift)-import           Data.Conduit import qualified Data.Conduit.Binary          as CB import           Data.Conduit.Lazy            (lazyConsume) import qualified Data.Conduit.List            as CL@@ -228,7 +226,7 @@ readFile :: ParseSettings -> FilePath -> IO Document readFile ps fp = handle     (throwIO . InvalidXMLFile fp)-    (runResourceT $ CB.sourceFile fp $$ sinkDoc ps)+    (runConduitRes $ CB.sourceFile fp .| sinkDoc ps)  data XMLException = InvalidXMLFile FilePath SomeException     deriving Typeable@@ -243,48 +241,48 @@ instance Exception XMLException  parseLBS :: ParseSettings -> L.ByteString -> Either SomeException Document-parseLBS ps lbs = runST-                $ runExceptionT-                $ CL.sourceList (L.toChunks lbs)-           $$ sinkDoc ps+parseLBS ps lbs+  = runConduit+  $ CL.sourceList (L.toChunks lbs)+ .| sinkDoc ps  parseLBS_ :: ParseSettings -> L.ByteString -> Document parseLBS_ ps = either throw id . parseLBS ps  sinkDoc :: MonadThrow m         => ParseSettings-        -> Consumer ByteString m Document-sinkDoc ps = P.parseBytesPos ps =$= fromEvents+        -> ConduitT ByteString o m Document+sinkDoc ps = P.parseBytesPos ps .| fromEvents  parseText :: ParseSettings -> TL.Text -> Either SomeException Document-parseText ps tl = runST-                $ runExceptionT-                $ CL.sourceList (TL.toChunks tl)-           $$ sinkTextDoc ps+parseText ps tl+  = runConduit+  $ CL.sourceList (TL.toChunks tl)+ .| sinkTextDoc ps  parseText_ :: ParseSettings -> TL.Text -> Document parseText_ ps = either throw id . parseText ps  sinkTextDoc :: MonadThrow m             => ParseSettings-            -> Consumer Text m Document-sinkTextDoc ps = P.parseTextPos ps =$= fromEvents+            -> ConduitT Text o m Document+sinkTextDoc ps = P.parseTextPos ps .| fromEvents -fromEvents :: MonadThrow m => Consumer P.EventPos m Document+fromEvents :: MonadThrow m => ConduitT P.EventPos o m Document fromEvents = do     d <- D.fromEvents-    either (lift . monadThrow . UnresolvedEntityException) return $ fromXMLDocument d+    either (lift . throwM . UnresolvedEntityException) return $ fromXMLDocument d  data UnresolvedEntityException = UnresolvedEntityException (Set Text)     deriving (Show, Typeable) instance Exception UnresolvedEntityException ---renderBytes :: MonadUnsafeIO m => R.RenderSettings -> Document -> Producer m ByteString+renderBytes :: PrimMonad m => D.RenderSettings -> Document -> ConduitT i ByteString m () renderBytes rs doc = D.renderBytes rs $ toXMLDocument' rs doc  writeFile :: R.RenderSettings -> FilePath -> Document -> IO () writeFile rs fp doc =-    runResourceT $ renderBytes rs doc $$ CB.sinkFile fp+    runConduitRes $ renderBytes rs doc .| CB.sinkFile fp  renderLBS :: R.RenderSettings -> Document -> L.ByteString renderLBS rs doc =
Text/XML/Cursor.hs view
@@ -60,7 +60,7 @@  import           Control.Exception            (Exception) import           Control.Monad-import           Control.Monad.Trans.Resource (MonadThrow, monadThrow)+import           Control.Monad.Trans.Resource (MonadThrow, throwM) import           Data.Function                (on) import qualified Data.Map                     as Map import           Data.Maybe                   (maybeToList)@@ -214,9 +214,9 @@         _                            -> []  force :: (Exception e, MonadThrow f) => e -> [a] -> f a-force e []    = monadThrow e+force e []    = throwM e force _ (x:_) = return x  forceM :: (Exception e, MonadThrow f) => e -> [f a] -> f a-forceM e []    = monadThrow e+forceM e []    = throwM e forceM _ (x:_) = x
Text/XML/Stream/Parse.hs view
@@ -35,7 +35,7 @@ -- > data Person = Person Int Text -- >     deriving Show -- >--- > parsePerson :: MonadThrow m => Consumer Event m (Maybe Person)+-- > parsePerson :: MonadThrow m => ConduitT Event o m (Maybe Person) -- > parsePerson = tag' "person" (requireAttr "age") $ \age -> do -- >     name <- content -- >     return $ Person (read $ unpack age) name@@ -72,7 +72,7 @@ -- > -- > data Person = Person Int Text deriving Show -- >--- > parsePerson :: MonadThrow m => Consumer Event m (Maybe Person)+-- > parsePerson :: MonadThrow m => ConduitT Event o m (Maybe Person) -- > parsePerson = tag' "person" (requireAttr "age") $ \age -> do -- >     name <- content -- >     return $ Person (read $ unpack age) name@@ -81,7 +81,7 @@ -- > parsePeople = void $ tagNoAttr "people" $ manyYield parsePerson -- > -- > main = runResourceT $--- >     parseFile def "people.xml" $$ parsePeople =$ CL.mapM_ (lift . print)+-- >     parseFile def "people.xml" $$ parsePeople .| CL.mapM_ (lift . print) -- -- Previous versions of this module contained a number of more sophisticated -- functions written by Aristid Breitkreuz and Dmitry Olshansky. To keep this@@ -166,10 +166,11 @@ import           Control.Exception            (Exception (..), SomeException) import           Control.Monad                (ap, liftM, void) import           Control.Monad.Fix            (fix)+import           Control.Monad.IO.Class       (liftIO) import           Control.Monad.Trans.Class    (lift) import           Control.Monad.Trans.Maybe    (MaybeT (..)) import           Control.Monad.Trans.Resource (MonadResource, MonadThrow (..),-                                               monadThrow)+                                               throwM) import           Data.Attoparsec.Text         (Parser, anyChar, char, manyTill,                                                skipWhile, string, takeWhile,                                                takeWhile1, try)@@ -177,11 +178,9 @@ import qualified Data.ByteString              as S import qualified Data.ByteString.Lazy         as L import           Data.Char                    (isSpace)-import           Data.Conduit-import           Data.Conduit.Attoparsec      (PositionRange, conduitParser)-import           Data.Conduit.Binary          (sourceFile)-import qualified Data.Conduit.List            as CL+import           Conduit import qualified Data.Conduit.Text            as CT+import           Data.Conduit.Attoparsec      (PositionRange, conduitParser) import           Data.Default.Class           (Default (..)) import           Data.List                    (intercalate) import           Data.List                    (foldl')@@ -271,7 +270,7 @@ -- first checks for BOMs, removing them as necessary, and then check for the -- equivalent of <?xml for each of UTF-8, UTF-16LE/BE, and UTF-32LE/BE. It -- defaults to assuming UTF-8.-detectUtf :: MonadThrow m => Conduit S.ByteString m T.Text+detectUtf :: MonadThrow m => ConduitT S.ByteString T.Text m () detectUtf =     conduit id   where@@ -307,7 +306,7 @@ checkXMLDecl :: MonadThrow m              => S.ByteString              -> Maybe CT.Codec-             -> Conduit S.ByteString m T.Text+             -> ConduitT S.ByteString T.Text m () checkXMLDecl bs (Just codec) = leftover bs >> CT.decode codec checkXMLDecl bs0 Nothing =     loop [] (AT.parse (parseToken def)) bs0@@ -343,15 +342,15 @@ -- to do the actual parsing. parseBytes :: MonadThrow m            => ParseSettings-           -> Conduit S.ByteString m Event+           -> ConduitT S.ByteString Event m () parseBytes = mapOutput snd . parseBytesPos  parseBytesPos :: MonadThrow m               => ParseSettings-              -> Conduit S.ByteString m EventPos-parseBytesPos ps = detectUtf =$= parseTextPos ps+              -> ConduitT S.ByteString EventPos m ()+parseBytesPos ps = detectUtf .| parseTextPos ps -dropBOM :: Monad m => Conduit T.Text m T.Text+dropBOM :: Monad m => ConduitT T.Text T.Text m () dropBOM =     await >>= maybe (return ()) push   where@@ -374,13 +373,13 @@ -- Since 1.2.4 parseText' :: MonadThrow m            => ParseSettings-           -> Conduit T.Text m Event+           -> ConduitT T.Text Event m () parseText' = mapOutput snd . parseTextPos  {-# DEPRECATED parseText "Please use 'parseText'' or 'parseTextPos'." #-} parseText :: MonadThrow m           => ParseSettings-          -> Conduit T.Text m EventPos+          -> ConduitT T.Text EventPos m () parseText = parseTextPos  -- | Same as 'parseText'', but includes the position of each event.@@ -388,12 +387,12 @@ -- Since 1.2.4 parseTextPos :: MonadThrow m           => ParseSettings-          -> Conduit T.Text m EventPos+          -> ConduitT T.Text EventPos m () parseTextPos de =     dropBOM-        =$= tokenize-        =$= toEventC de-        =$= addBeginEnd+        .| tokenize+        .| toEventC de+        .| addBeginEnd   where     tokenize = conduitToken de     addBeginEnd = yield (Nothing, EventBeginDocument) >> addEnd@@ -401,7 +400,7 @@         (yield (Nothing, EventEndDocument))         (\e -> yield e >> addEnd) -toEventC :: Monad m => ParseSettings -> Conduit (PositionRange, Token) m EventPos+toEventC :: Monad m => ParseSettings -> ConduitT (PositionRange, Token) EventPos m () toEventC ps =     go [] []   where@@ -446,7 +445,7 @@         , psDecodeIllegalCharacters = const Nothing         } -conduitToken :: MonadThrow m => ParseSettings -> Conduit T.Text m (PositionRange, Token)+conduitToken :: MonadThrow m => ParseSettings -> ConduitT T.Text (PositionRange, Token) m () conduitToken = conduitParser . parseToken  parseToken :: ParseSettings -> Parser Token@@ -667,13 +666,13 @@ -- | Grabs the next piece of content if available. This function skips over any -- comments and instructions and concatenates all content until the next start -- or end tag.-contentMaybe :: MonadThrow m => Consumer Event m (Maybe Text)+contentMaybe :: MonadThrow m => ConduitT Event o m (Maybe Text) contentMaybe = do-    x <- CL.peek+    x <- peekC     case pc' x of-        Ignore      -> CL.drop 1 >> contentMaybe-        IsContent t -> CL.drop 1 >> fmap Just (takeContents (t:))-        IsError e   -> lift $ monadThrow $ InvalidEntity e x+        Ignore      -> dropC 1 >> contentMaybe+        IsContent t -> dropC 1 >> fmap Just (takeContents (t:))+        IsError e   -> lift $ throwM $ InvalidEntity e x         NotContent  -> return Nothing   where     pc' Nothing  = NotContent@@ -690,16 +689,16 @@     pc EventInstruction{} = Ignore     pc EventComment{} = Ignore     takeContents front = do-        x <- CL.peek+        x <- peekC         case pc' x of-            Ignore      -> CL.drop 1 >> takeContents front-            IsContent t -> CL.drop 1 >> takeContents (front . (:) t)-            IsError e   -> lift $ monadThrow $ InvalidEntity e x+            Ignore      -> dropC 1 >> takeContents front+            IsContent t -> dropC 1 >> takeContents (front . (:) t)+            IsError e   -> lift $ throwM $ InvalidEntity e x             NotContent  -> return $ T.concat $ front []  -- | Grabs the next piece of content. If none if available, returns 'T.empty'. -- This is simply a wrapper around 'contentMaybe'.-content :: MonadThrow m => Consumer Event m Text+content :: MonadThrow m => ConduitT Event o m Text content = fromMaybe T.empty <$> contentMaybe  @@ -733,9 +732,9 @@     -> (a -> AttrParser b) -- ^ Given the value returned by the name checker, this function will                            --   be used to get an @AttrParser@ appropriate for the specific tag.                            --   If the @AttrParser@ fails, the function will also return @Nothing@-    -> (b -> ConduitM Event o m c) -- ^ Handler function to handle the attributes and children+    -> (b -> ConduitT Event o m c) -- ^ Handler function to handle the attributes and children                                    --   of a tag, given the value return from the @AttrParser@-    -> ConduitM Event o m (Maybe c)+    -> ConduitT Event o m (Maybe c) tag nameMatcher attrParser f = do   (x, leftovers) <- dropWS []   res <- case x of@@ -748,7 +747,7 @@           case a of             Just (EventEndElement name')               | name == name' -> return (Just z')-            _ -> lift $ monadThrow $ InvalidEndElement name a+            _ -> lift $ throwM $ InvalidEndElement name a       Nothing -> return Nothing     _ -> return Nothing @@ -776,29 +775,29 @@         case runAttrParser p as of             Left e          -> Left e             Right ([], x)   -> Right x-            Right (attr, _) -> Left $ toException $ UnparsedAttributes attr+            Right (attr', _) -> Left $ toException $ UnparsedAttributes attr'  -- | A simplified version of 'tag' where the 'NameMatcher' result isn't forwarded to the attributes parser. -- -- Since 1.5.0 tag' :: MonadThrow m-     => NameMatcher a -> AttrParser b -> (b -> ConduitM Event o m c)-     -> ConduitM Event o m (Maybe c)+     => NameMatcher a -> AttrParser b -> (b -> ConduitT Event o m c)+     -> ConduitT Event o m (Maybe c) tag' a b = tag a (const b)  -- | A further simplified tag parser, which requires that no attributes exist. tagNoAttr :: MonadThrow m           => NameMatcher a -- ^ Check if this is a correct tag name-          -> ConduitM Event o m b -- ^ Handler function to handle the children of the matched tag-          -> ConduitM Event o m (Maybe b)+          -> ConduitT Event o m b -- ^ Handler function to handle the children of the matched tag+          -> ConduitT Event o m (Maybe b) tagNoAttr name f = tag' name (return ()) $ const f   -- | A further simplified tag parser, which ignores all attributes, if any exist tagIgnoreAttrs :: MonadThrow m                => NameMatcher a -- ^ Check if this is a correct tag name-               -> ConduitM Event o m b -- ^ Handler function to handle the children of the matched tag-               -> ConduitM Event o m (Maybe b)+               -> ConduitT Event o m b -- ^ Handler function to handle the children of the matched tag+               -> ConduitT Event o m (Maybe b) tagIgnoreAttrs name f = tag' name ignoreAttrs $ const f  @@ -810,14 +809,14 @@ -- Since 1.5.0 ignoreEmptyTag :: MonadThrow m           => NameMatcher a -- ^ Check if this is a correct tag name-          -> ConduitM Event o m (Maybe ())+          -> ConduitT Event o m (Maybe ()) ignoreEmptyTag nameMatcher = tagIgnoreAttrs nameMatcher (return ())   {-# DEPRECATED ignoreTag "Please use 'ignoreEmptyTag'." #-} ignoreTag :: MonadThrow m           => NameMatcher a -- ^ Check if this is a correct tag name-          -> ConduitM Event o m (Maybe ())+          -> ConduitT Event o m (Maybe ()) ignoreTag = ignoreEmptyTag  @@ -828,21 +827,21 @@ -- Since 1.5.0 ignoreTreeContent :: MonadThrow m                   => NameMatcher a -- ^ Check if this is a correct tag name-                  -> ConduitM Event o m (Maybe ())+                  -> ConduitT Event o m (Maybe ()) ignoreTreeContent namePred = tagIgnoreAttrs namePred (void $ many ignoreAnyTreeContent)  {-# DEPRECATED ignoreTree "Please use 'ignoreTreeContent'." #-} ignoreTree :: MonadThrow m            => NameMatcher a -- ^ Check if this is a correct tag name-           -> ConduitM Event o m (Maybe ())+           -> ConduitT Event o m (Maybe ()) ignoreTree = ignoreTreeContent  -- | Like 'ignoreTreeContent', but matches any name and also ignores content events.-ignoreAnyTreeContent :: MonadThrow m => ConduitM Event o m (Maybe ())+ignoreAnyTreeContent :: MonadThrow m => ConduitT Event o m (Maybe ()) ignoreAnyTreeContent = (void <$> contentMaybe) `orE` ignoreTreeContent anyName  {-# DEPRECATED ignoreAllTreesContent "Please use 'ignoreAnyTreeContent'." #-}-ignoreAllTreesContent :: MonadThrow m => ConduitM Event o m (Maybe ())+ignoreAllTreesContent :: MonadThrow m => ConduitT Event o m (Maybe ()) ignoreAllTreesContent = ignoreAnyTreeContent  -- | Get the value of the first parser which returns 'Just'. If no parsers@@ -850,16 +849,16 @@ -- -- > orE a b = choose [a, b] orE :: Monad m-    => Consumer Event m (Maybe a) -- ^ The first (preferred) parser-    -> Consumer Event m (Maybe a) -- ^ The second parser, only executed if the first parser fails-    -> Consumer Event m (Maybe a)+    => ConduitT Event o m (Maybe a) -- ^ The first (preferred) parser+    -> ConduitT Event o m (Maybe a) -- ^ The second parser, only executed if the first parser fails+    -> ConduitT Event o m (Maybe a) orE a b = a >>= \x -> maybe b (const $ return x) x  -- | Get the value of the first parser which returns 'Just'. If no parsers -- succeed (i.e., return 'Just'), this function returns 'Nothing'. choose :: Monad m-       => [ConduitM Event o m (Maybe a)] -- ^ List of parsers that will be tried in order.-       -> ConduitM Event o m (Maybe a)   -- ^ Result of the first parser to succeed, or @Nothing@+       => [ConduitT Event o m (Maybe a)] -- ^ List of parsers that will be tried in order.+       -> ConduitT Event o m (Maybe a)   -- ^ Result of the first parser to succeed, or @Nothing@                                          --   if no parser succeeded choose []     = return Nothing choose (i:is) = i >>= maybe (choose is) (return . Just)@@ -879,15 +878,15 @@ parseFile :: MonadResource m           => ParseSettings           -> FilePath-          -> Producer m Event-parseFile ps fp = sourceFile fp =$= parseBytes ps+          -> ConduitT i Event m ()+parseFile ps fp = sourceFile fp .| transPipe liftIO (parseBytes ps)  -- | Parse an event stream from a lazy 'L.ByteString'. parseLBS :: MonadThrow m          => ParseSettings          -> L.ByteString-         -> Producer m Event-parseLBS ps lbs = CL.sourceList (L.toChunks lbs) =$= parseBytes ps+         -> ConduitT i Event m ()+parseLBS ps lbs = sourceLazy lbs .| parseBytes ps  data XmlException = XmlException     { xmlErrorMessage :: String@@ -1021,24 +1020,24 @@  -- | Keep parsing elements as long as the parser returns 'Just'. many :: Monad m-     => ConduitM Event o m (Maybe a)-     -> ConduitM Event o m [a]+     => ConduitT Event o m (Maybe a)+     -> ConduitT Event o m [a] many i = manyIgnore i $ return Nothing  -- | Like 'many' but discards the results without building an intermediate list. -- -- Since 1.5.0 many_ :: MonadThrow m-      => ConduitM Event o m (Maybe a)-      -> ConduitM Event o m ()+      => ConduitT Event o m (Maybe a)+      -> ConduitT Event o m () many_ consumer = manyIgnoreYield (return Nothing) (void <$> consumer)  -- | Keep parsing elements as long as the parser returns 'Just' --   or the ignore parser returns 'Just'. manyIgnore :: Monad m-           => ConduitM Event o m (Maybe a)-           -> ConduitM Event o m (Maybe b)-           -> ConduitM Event o m [a]+           => ConduitT Event o m (Maybe a)+           -> ConduitT Event o m (Maybe b)+           -> ConduitT Event o m [a] manyIgnore i ignored = go id where   go front = i >>= maybe (onFail front) (\y -> go $ front . (:) y)   -- onFail is called if the main parser fails@@ -1047,25 +1046,25 @@ -- | Like @many@, but any tags and content the consumer doesn't match on --   are silently ignored. many' :: MonadThrow m-      => ConduitM Event o m (Maybe a)-      -> ConduitM Event o m [a]+      => ConduitT Event o m (Maybe a)+      -> ConduitT Event o m [a] many' consumer = manyIgnore consumer ignoreAllTreesContent   -- | Like 'many', but uses 'yield' so the result list can be streamed --   to downstream conduits without waiting for 'manyYield' to finish manyYield :: Monad m-          => ConduitM a b m (Maybe b)-          -> Conduit a m b+          => ConduitT a b m (Maybe b)+          -> ConduitT a b m () manyYield consumer = fix $ \loop ->   consumer >>= maybe (return ()) (\x -> yield x >> loop)  -- | Like 'manyIgnore', but uses 'yield' so the result list can be streamed --   to downstream conduits without waiting for 'manyIgnoreYield' to finish manyIgnoreYield :: MonadThrow m-                => ConduitM Event b m (Maybe b) -- ^ Consuming parser that generates the result stream-                -> ConduitM Event b m (Maybe ()) -- ^ Ignore parser that consumes elements to be ignored-                -> Conduit Event m b+                => ConduitT Event b m (Maybe b) -- ^ Consuming parser that generates the result stream+                -> ConduitT Event b m (Maybe ()) -- ^ Ignore parser that consumes elements to be ignored+                -> ConduitT Event b m () manyIgnoreYield consumer ignoreParser = fix $ \loop ->   consumer >>= maybe (onFail loop) (\x -> yield x >> loop)   where onFail loop = ignoreParser >>= maybe (return ()) (const loop)@@ -1073,8 +1072,8 @@ -- | Like 'many'', but uses 'yield' so the result list can be streamed --   to downstream conduits without waiting for 'manyYield'' to finish manyYield' :: MonadThrow m-           => ConduitM Event b m (Maybe b)-           -> Conduit Event m b+           => ConduitT Event b m (Maybe b)+           -> ConduitT Event b m () manyYield' consumer = manyIgnoreYield consumer ignoreAllTreesContent  @@ -1083,7 +1082,7 @@ -- Returns @Just ()@ if a content 'Event' was consumed, @Nothing@ otherwise. -- -- Since 1.5.0-takeContent :: MonadThrow m => ConduitM Event Event m (Maybe ())+takeContent :: MonadThrow m => ConduitT Event Event m (Maybe ()) takeContent = do   event <- await   case event of@@ -1103,7 +1102,7 @@ -- Returns @Just ()@ if an element was consumed, 'Nothing' otherwise. -- -- Since 1.5.0-takeTree :: MonadThrow m => NameMatcher a -> AttrParser b -> ConduitM Event Event m (Maybe ())+takeTree :: MonadThrow m => NameMatcher a -> AttrParser b -> ConduitT Event Event m (Maybe ()) takeTree nameMatcher attrParser = do   event <- await   case event of@@ -1115,7 +1114,7 @@           endEvent <- await           case endEvent of             Just e'@(EventEndElement name') | name == name' -> yield e' >> return (Just ())-            _ -> lift $ monadThrow $ InvalidEndElement name endEvent+            _ -> lift $ throwM $ InvalidEndElement name endEvent         _ -> leftover e >> return Nothing       _ -> leftover e >> return Nothing @@ -1130,27 +1129,27 @@ takeTreeContent :: MonadThrow m                 => NameMatcher a                 -> AttrParser b-                -> ConduitM Event Event m (Maybe ())+                -> ConduitT Event Event m (Maybe ()) takeTreeContent nameMatcher attrParser = runMaybeT $ MaybeT (takeTree nameMatcher attrParser) <|> MaybeT takeContent  -- | Like 'takeTreeContent', without checking for tag name or attributes. ----- >>> runResourceT $ parseLBS def "text<a></a>" $$ takeAnyTreeContent =$= consume+-- >>> runResourceT $ parseLBS def "text<a></a>" $$ takeAnyTreeContent .| consume -- Just [ EventContent (ContentText "text") ] ----- >>> runResourceT $ parseLBS def "</a><b></b>" $$ takeAnyTreeContent =$= consume+-- >>> runResourceT $ parseLBS def "</a><b></b>" $$ takeAnyTreeContent .| consume -- Just [ ] ----- >>> runResourceT $ parseLBS def "<b><c></c></b></a>text" $$ takeAnyTreeContent =$= consume+-- >>> runResourceT $ parseLBS def "<b><c></c></b></a>text" $$ takeAnyTreeContent .| consume -- Just [ EventBeginElement "b" [], EventBeginElement "c" [], EventEndElement "c", EventEndElement "b" ] -- -- Since 1.5.0 takeAnyTreeContent :: MonadThrow m-                => ConduitM Event Event m (Maybe ())+                => ConduitT Event Event m (Maybe ()) takeAnyTreeContent = takeTreeContent anyName ignoreAttrs  {-# DEPRECATED takeAllTreesContent "Please use 'takeAnyTreeContent'." #-}-takeAllTreesContent :: MonadThrow m => ConduitM Event Event m (Maybe ())+takeAllTreesContent :: MonadThrow m => ConduitT Event Event m (Maybe ()) takeAllTreesContent = takeAnyTreeContent  
Text/XML/Stream/Render.hs view
@@ -30,14 +30,11 @@     , optionalAttr     ) where -import           Blaze.ByteString.Builder import           Control.Applicative          ((<$>)) import           Control.Monad.Trans.Resource (MonadThrow) import           Data.ByteString              (ByteString)-import           Data.Conduit-import           Data.Conduit.Blaze           (builderToByteString)-import qualified Data.Conduit.List            as CL-import qualified Data.Conduit.Text            as CT+import           Data.ByteString.Builder      (Builder)+import           Conduit import           Data.Default.Class           (Default (def)) import           Data.List                    (foldl') import           Data.Map                     (Map)@@ -56,17 +53,14 @@ -- optimally sized 'ByteString's with minimal buffer copying. -- -- The output is UTF8 encoded.---renderBytes :: Monad m => RenderSettings -> Conduit Event m ByteString-renderBytes rs = renderBuilder rs =$= builderToByteString+renderBytes :: PrimMonad m => RenderSettings -> ConduitT Event ByteString m ()+renderBytes rs = renderBuilder rs .| builderToByteString  -- | Render a stream of 'Event's into a stream of 'Text's. This function -- wraps around 'renderBuilder', 'builderToByteString' and 'renderBytes', so it -- produces optimally sized 'Text's with minimal buffer copying.-{--renderText :: (MonadThrow m)-           => RenderSettings -> Conduit Event m Text--}-renderText rs = renderBytes rs =$= CT.decode CT.utf8+renderText :: (PrimMonad m, MonadThrow m) => RenderSettings -> ConduitT Event Text m ()+renderText rs = renderBytes rs .| decodeUtf8C  data RenderSettings = RenderSettings     { rsPretty     :: Bool@@ -118,7 +112,7 @@   where     order elt attrMap =       let initialAttrs = fromMaybe [] $ lookup elt orderSpec-          mkPair attr = (,) attr <$> Map.lookup attr attrMap+          mkPair attr' = (,) attr' <$> Map.lookup attr' attrMap           otherAttrMap =             Map.filterWithKey (const . not . (`elem` initialAttrs)) attrMap       in mapMaybe mkPair initialAttrs ++ Map.toAscList otherAttrMap@@ -126,8 +120,8 @@ -- | Render a stream of 'Event's into a stream of 'Builder's. Builders are from -- the blaze-builder package, and allow the create of optimally sized -- 'ByteString's with minimal buffer copying.-renderBuilder :: Monad m => RenderSettings -> Conduit Event m Builder-renderBuilder settings = CL.map Chunk =$= renderBuilder' yield' settings+renderBuilder :: Monad m => RenderSettings -> ConduitT Event Builder m ()+renderBuilder settings = mapC Chunk .| renderBuilder' yield' settings   where     yield' Flush = return ()     yield' (Chunk bs) = yield bs@@ -136,18 +130,26 @@ -- events at needed point are rendered. -- -- @since 1.3.5-renderBuilderFlush :: Monad m => RenderSettings -> Conduit (Flush Event) m (Flush Builder)+renderBuilderFlush :: Monad m => RenderSettings -> ConduitT (Flush Event) (Flush Builder) m () renderBuilderFlush = renderBuilder' yield -renderBuilder' :: Monad m => (Flush Builder -> Producer m o) -> RenderSettings -> Conduit (Flush Event) m o+renderBuilder'+  :: Monad m+  => (Flush Builder -> ConduitT (Flush Event) o m ())+  -> RenderSettings+  -> ConduitT (Flush Event) o m () renderBuilder' yield' settings =     if rsPretty settings-    then prettify =$= renderEvent'+    then prettify .| renderEvent'     else renderEvent'   where     renderEvent' = renderEvent yield' settings -renderEvent :: Monad m => (Flush Builder -> Producer m o) -> RenderSettings -> Conduit (Flush Event) m o+renderEvent+  :: Monad m+  => (Flush Builder -> ConduitT (Flush Event) o m ())+  -> RenderSettings+  -> ConduitT (Flush Event) o m () renderEvent yield' RenderSettings { rsPretty = isPretty, rsNamespaces = namespaces0, rsUseCDATA = useCDATA, rsXMLDeclaration = useXMLDecl } =     loop []   where@@ -157,11 +159,11 @@     go nslevels (Chunk e) =         case e of             EventBeginElement n1 as -> do-                mnext <- CL.peek+                mnext <- peekC                 isClosed <-                     case mnext of                         Just (Chunk (EventEndElement n2)) | n1 == n2 -> do-                            CL.drop 1+                            dropC 1                             return True                         _ -> return False                 let (token, nslevels') = mkBeginToken isPretty isClosed namespaces0 nslevels n1 as@@ -291,10 +293,10 @@  -- | Convert a stream of 'Event's into a prettified one, adding extra -- whitespace. Note that this can change the meaning of your XML.-prettify :: Monad m => Conduit (Flush Event) m (Flush Event)+prettify :: Monad m => ConduitT (Flush Event) (Flush Event) m () prettify = prettify' 0 -prettify' :: Monad m => Int -> Conduit (Flush Event) m (Flush Event)+prettify' :: Monad m => Int -> ConduitT (Flush Event) (Flush Event) m () prettify' level =     await >>= maybe (return ()) goC   where@@ -310,10 +312,10 @@     go e@EventBeginElement{} = do         yield' before         yield' e-        mnext <- CL.peek+        mnext <- peekC         case mnext of             Just (Chunk next@EventEndElement{}) -> do-                CL.drop 1+                dropC 1                 yield' next                 yield' after                 prettify' level@@ -357,13 +359,13 @@     go e@EventEndDoctype{} = yield' e >> yield' after >> prettify' level      takeContents front = do-        me <- CL.peek+        me <- peekC         case me of             Just (Chunk (EventContent c)) -> do-                CL.drop 1+                dropC 1                 takeContents $ front . (c:)             Just (Chunk (EventCDATA t)) -> do-                CL.drop 1+                dropC 1                 takeContents $ front . (ContentText t:)             _ -> return $ front [] @@ -389,15 +391,15 @@   -- | Generate a complete XML 'Element'.-tag :: (Monad m) => Name -> Attributes -> Source m Event  -- ^ 'Element''s subnodes.-                                       -> Source m Event-tag name (Attributes a) content = do+tag :: (Monad m) => Name -> Attributes -> ConduitT i Event m ()  -- ^ 'Element''s subnodes.+                                       -> ConduitT i Event m ()+tag name (Attributes a) content' = do   yield $ EventBeginElement name a-  content+  content'   yield $ EventEndElement name  -- | Generate a textual 'EventContent'.-content :: (Monad m) => Text -> Source m Event+content :: (Monad m) => Text -> ConduitT i Event m () content = yield . EventContent . ContentText  -- | A list of attributes.
Text/XML/Stream/Token.hs view
@@ -11,21 +11,20 @@ import Data.XML.Types (Instruction (..), Content (..), ExternalID (..)) import qualified Data.Text as T import Data.Text (Text)+import Data.Text.Encoding (encodeUtf8Builder, encodeUtf8BuilderEscaped) import Data.String (IsString (fromString))-import Blaze.ByteString.Builder-    (Builder, fromByteString, writeByteString, copyByteString)-import Blaze.ByteString.Builder.Internal.Write (fromWriteList)-import Blaze.ByteString.Builder.Char.Utf8 (writeChar, fromText)-import Data.Monoid (mconcat, mempty, mappend)-import Data.ByteString.Char8 ()+import Data.ByteString.Builder (Builder)+import qualified Data.ByteString.Builder.Prim as E+import Data.ByteString.Builder.Prim ((>*<), (>$<), condB)+import Data.Monoid (mconcat, mempty, (<>)) import Data.Map (Map)-import qualified Blaze.ByteString.Builder.Char8 as BC8 import qualified Data.Set as Set import Data.List (foldl') import Control.Arrow (first)+import Data.Word (Word8)  oneSpace :: Builder-oneSpace = copyByteString " "+oneSpace = " "  data Token = TokenXMLDeclaration [TAttribute]            | TokenInstruction Instruction@@ -38,113 +37,113 @@     deriving Show tokenToBuilder :: Token -> Builder tokenToBuilder (TokenXMLDeclaration attrs) =-    fromByteString "<?xml"-    `mappend` foldAttrs oneSpace attrs (fromByteString "?>")-tokenToBuilder (TokenInstruction (Instruction target data_)) = mconcat-    [ fromByteString "<?"-    , fromText target-    , fromByteString " "-    , fromText data_-    , fromByteString "?>"-    ]+    "<?xml" <>+    foldAttrs oneSpace attrs <>+    "?>"+tokenToBuilder (TokenInstruction (Instruction target data_)) =+    "<?" <>+    encodeUtf8Builder target <>+    " " <>+    encodeUtf8Builder data_ <>+    "?>" tokenToBuilder (TokenBeginElement name attrs' isEmpty indent) =-      copyByteString "<"-    `mappend` tnameToText name-    `mappend` foldAttrs+    "<" <>+    tnameToText name <>+    foldAttrs         (if indent == 0 || lessThan3 attrs             then oneSpace-            else BC8.fromString ('\n' : replicate indent ' '))-        attrs-        (if isEmpty then fromByteString "/>" else fromByteString ">")+            else mconcat $ ("\n" : replicate indent " "))+        attrs <>+    (if isEmpty then "/>" else ">")   where     attrs = nubAttrs $ map (first splitTName) attrs'     lessThan3 [] = True     lessThan3 [_] = True     lessThan3 [_, _] = True     lessThan3 _ = False-tokenToBuilder (TokenEndElement name) = mconcat-    [ fromByteString "</"-    , tnameToText name-    , fromByteString ">"-    ]+tokenToBuilder (TokenEndElement name) = "</" <> tnameToText name <> ">" tokenToBuilder (TokenContent c) = contentToText c-tokenToBuilder (TokenCDATA t) = -    copyByteString "<![CDATA["-    `mappend` escCDATA t-    `mappend` copyByteString "]]>"-tokenToBuilder (TokenComment t) = mconcat [fromByteString "<!--", fromText t, fromByteString "-->"]-tokenToBuilder (TokenDoctype name eid _) = mconcat-    [ fromByteString "<!DOCTYPE "-    , fromText name-    , go eid-    , fromByteString ">"-    ]+tokenToBuilder (TokenCDATA t) = "<![CDATA[" <> escCDATA t <> "]]>"+tokenToBuilder (TokenComment t) = "<!--" <> encodeUtf8Builder t <> "-->"+tokenToBuilder (TokenDoctype name eid _) =+    "<!DOCTYPE " <>+    encodeUtf8Builder name <>+    go eid <>+    ">"   where     go Nothing = mempty-    go (Just (SystemID uri)) = mconcat-        [ fromByteString " SYSTEM \""-        , fromText uri-        , fromByteString "\""-        ]-    go (Just (PublicID pid uri)) = mconcat-        [ fromByteString " PUBLIC \""-        , fromText pid-        , fromByteString "\" \""-        , fromText uri-        , fromByteString "\""-        ]+    go (Just (SystemID uri)) = " SYSTEM \"" <> encodeUtf8Builder uri <> "\""+    go (Just (PublicID pid uri)) =+        " PUBLIC \"" <>+        encodeUtf8Builder pid <>+        "\" \"" <>+        encodeUtf8Builder uri <>+        "\""  data TName = TName (Maybe Text) Text     deriving (Show, Eq, Ord)  tnameToText :: TName -> Builder-tnameToText (TName Nothing name) = fromText name-tnameToText (TName (Just prefix) name) = mconcat [fromText prefix, fromByteString ":", fromText name]+tnameToText (TName Nothing name) = encodeUtf8Builder name+tnameToText (TName (Just prefix) name) =+  encodeUtf8Builder prefix <> ":" <> encodeUtf8Builder name  contentToText :: Content -> Builder-contentToText (ContentText t) =-    fromWriteList go $ T.unpack t+contentToText (ContentText t) = encodeUtf8BuilderEscaped charUtf8XmlEscaped t+contentToText (ContentEntity e) = "&" <> encodeUtf8Builder e <> ";"++{-# INLINE charUtf8XmlEscaped #-}+charUtf8XmlEscaped :: E.BoundedPrim Word8+charUtf8XmlEscaped =+    condB (>  _gt) (E.liftFixedToBounded E.word8) $+    condB (== _lt) (fixed4 (_am,(_l,(_t,_sc)))) $       -- &lt;+    condB (== _gt) (fixed4 (_am,(_g,(_t,_sc)))) $       -- &gt;+    condB (== _am) (fixed5 (_am,(_a,(_m,(_p,_sc))))) $  -- &amp;+    condB (== _dq) (fixed5 (_am,(_ha,(_3,(_4,_sc))))) $ -- &#34;+    condB (== _sq) (fixed5 (_am,(_ha,(_3,(_9,_sc))))) $ -- &#39;+    (E.liftFixedToBounded E.word8)         -- fallback for Chars smaller than '>'   where-    go '<' = writeByteString "&lt;"-    go '>' = writeByteString "&gt;"-    go '&' = writeByteString "&amp;"-    -- Not escaping quotes, since this is only called outside of attributes-    go c   = writeChar c-contentToText (ContentEntity e) = mconcat-    [ fromByteString "&"-    , fromText e-    , fromByteString ";"-    ]+    _gt = 62 -- >+    _lt = 60 -- <+    _am = 38 -- &+    _dq = 34 -- "+    _sq = 39 -- '+    _l  = 108 -- l+    _t  = 116 -- t+    _g  = 103 -- g+    _a  = 97  -- a+    _m  = 109 -- m+    _p  = 112 -- p+    _3  = 51  -- 3+    _4  = 52  -- 4+    _ha = 35  -- #, hash+    _9  = 57  -- 9+    _sc = 59  -- ;+    {-# INLINE fixed4 #-}+    fixed4 x = E.liftFixedToBounded $ const x >$<+      E.word8 >*< E.word8 >*< E.word8 >*< E.word8 +    {-# INLINE fixed5 #-}+    fixed5 x = E.liftFixedToBounded $ const x >$<+      E.word8 >*< E.word8 >*< E.word8 >*< E.word8 >*< E.word8+ type TAttribute = (TName, [Content])  foldAttrs :: Builder -- ^ before           -> [TAttribute]           -> Builder-          -> Builder-foldAttrs before attrs rest' =-    foldr go rest' attrs+foldAttrs before =+    foldMap go   where-    go (key, val) rest =-      before-      `mappend` tnameToText key-      `mappend` copyByteString "=\""-      `mappend` foldr go' (fromByteString "\"" `mappend` rest) val-    go' (ContentText t) rest =-        fromWriteList h (T.unpack t) `mappend` rest-      where-        h '<' = writeByteString "&lt;"-        h '>' = writeByteString "&gt;"-        h '&' = writeByteString "&amp;"-        h '"' = writeByteString "&quot;"-        -- Not escaping single quotes, since our attributes are always double-        -- quoted-        h c   = writeChar c-    go' (ContentEntity t) rest =-        fromByteString "&"-        `mappend` fromText t-        `mappend` fromByteString ";"-        `mappend` rest+    go (key, val) =+      before <>+      tnameToText key <>+      "=\"" <>+      foldMap go' val <>+      "\""+    go' (ContentText t) =+      encodeUtf8BuilderEscaped charUtf8XmlEscaped t+    go' (ContentEntity t) = "&" <> encodeUtf8Builder t <> ";"  instance IsString TName where     fromString = TName Nothing . T.pack@@ -171,6 +170,6 @@     | otherwise = TName (Just a) $ T.drop 1 b   where     (a, b) = T.break (== ':') t-    + escCDATA :: Text -> Builder-escCDATA s = fromText (T.replace "]]>" "]]]]><![CDATA[>" s)+escCDATA s = encodeUtf8Builder (T.replace "]]>" "]]]]><![CDATA[>" s)
Text/XML/Unresolved.hs view
@@ -43,18 +43,15 @@     , R.rsNamespaces     ) where -import           Blaze.ByteString.Builder     (Builder)+import           Conduit import           Control.Applicative          ((<$>), (<*>)) import           Control.Exception            (Exception, SomeException, throw) import           Control.Monad                (when)-import           Control.Monad.ST             (runST) import           Control.Monad.Trans.Class    (lift)-import           Control.Monad.Trans.Resource (MonadThrow, monadThrow,-                                               runExceptionT, runResourceT) import           Data.ByteString              (ByteString)+import           Data.ByteString.Builder      (Builder) import qualified Data.ByteString.Lazy         as L import           Data.Char                    (isSpace)-import           Data.Conduit import qualified Data.Conduit.Binary          as CB import           Data.Conduit.Lazy            (lazyConsume) import qualified Data.Conduit.List            as CL@@ -72,16 +69,16 @@ import qualified Text.XML.Stream.Render       as R  readFile :: P.ParseSettings -> FilePath -> IO Document-readFile ps fp = runResourceT $ CB.sourceFile fp $$ sinkDoc ps+readFile ps fp = runConduitRes $ CB.sourceFile fp .| sinkDoc ps  sinkDoc :: MonadThrow m         => P.ParseSettings-        -> Consumer ByteString m Document-sinkDoc ps = P.parseBytesPos ps =$= fromEvents+        -> ConduitT ByteString o m Document+sinkDoc ps = P.parseBytesPos ps .| fromEvents  writeFile :: R.RenderSettings -> FilePath -> Document -> IO () writeFile rs fp doc =-    runResourceT $ renderBytes rs doc $$ CB.sinkFile fp+    runConduitRes $ renderBytes rs doc .| CB.sinkFile fp  renderLBS :: R.RenderSettings -> Document -> L.ByteString renderLBS rs doc =@@ -93,9 +90,7 @@                  $ renderBytes rs doc  parseLBS :: P.ParseSettings -> L.ByteString -> Either SomeException Document-parseLBS ps lbs =-    runST $ runExceptionT-          $ CL.sourceList (L.toChunks lbs) $$ sinkDoc ps+parseLBS ps lbs = runConduit $ CL.sourceList (L.toChunks lbs) .| sinkDoc ps  parseLBS_ :: P.ParseSettings -> L.ByteString -> Document parseLBS_ ps lbs = either throw id $ parseLBS ps lbs@@ -125,14 +120,14 @@ prettyShowName :: Name -> String prettyShowName = show -- FIXME -renderBuilder :: Monad m => R.RenderSettings -> Document -> Producer m Builder-renderBuilder rs doc = CL.sourceList (toEvents doc) =$= R.renderBuilder rs+renderBuilder :: Monad m => R.RenderSettings -> Document -> ConduitT i Builder m ()+renderBuilder rs doc = CL.sourceList (toEvents doc) .| R.renderBuilder rs ---renderBytes :: MonadUnsafeIO m => R.RenderSettings -> Document -> Producer m ByteString-renderBytes rs doc = CL.sourceList (toEvents doc) =$= R.renderBytes rs+renderBytes :: PrimMonad m => R.RenderSettings -> Document -> ConduitT i ByteString m ()+renderBytes rs doc = CL.sourceList (toEvents doc) .| R.renderBytes rs ---renderText :: (MonadThrow m, MonadUnsafeIO m) => R.RenderSettings -> Document -> Producer m Text-renderText rs doc = CL.sourceList (toEvents doc) =$= R.renderText rs+renderText :: (MonadThrow m, PrimMonad m) => R.RenderSettings -> Document -> ConduitT i Text m ()+renderText rs doc = CL.sourceList (toEvents doc) .| R.renderText rs  manyTries :: Monad m => m (Maybe a) -> m [a] manyTries f =@@ -148,7 +143,7 @@ dropReturn x = CL.drop 1 >> return x  -- | Parse a document from a stream of events.-fromEvents :: MonadThrow m => Consumer P.EventPos m Document+fromEvents :: MonadThrow m => ConduitT P.EventPos o m Document fromEvents = do     skip EventBeginDocument     d <- Document <$> goP <*> require elementFromEvents <*> goM@@ -156,9 +151,9 @@     y <- CL.head     case y of         Nothing -> return d-        Just (_, EventEndDocument) -> lift $ monadThrow MissingRootElement+        Just (_, EventEndDocument) -> lift $ throwM MissingRootElement         Just z ->-            lift $ monadThrow $ ContentAfterRoot z+            lift $ throwM $ ContentAfterRoot z   where     skip e = do         x <- CL.peek@@ -171,8 +166,8 @@                 my <- CL.head                 case my of                     Nothing -> error "Text.XML.Unresolved:impossible"-                    Just (_, EventEndDocument) -> lift $ monadThrow MissingRootElement-                    Just y -> lift $ monadThrow $ ContentAfterRoot y+                    Just (_, EventEndDocument) -> lift $ throwM MissingRootElement+                    Just y -> lift $ throwM $ ContentAfterRoot y     goP = Prologue <$> goM <*> goD <*> goM     goM = manyTries goM'     goM' = do@@ -200,13 +195,13 @@             --             -- Just (EventDeclaration _) -> dropTillDoctype             Just (_, EventEndDoctype) -> return ()-            Just epos -> lift $ monadThrow $ InvalidInlineDoctype epos-            Nothing -> lift $ monadThrow UnterminatedInlineDoctype+            Just epos -> lift $ throwM $ InvalidInlineDoctype epos+            Nothing -> lift $ throwM UnterminatedInlineDoctype  -- | Try to parse a document element (as defined in XML) from a stream of events. -- -- @since 1.3.5-elementFromEvents :: MonadThrow m => Consumer P.EventPos m (Maybe Element)+elementFromEvents :: MonadThrow m => ConduitT P.EventPos o m (Maybe Element) elementFromEvents = goE   where     goE = do@@ -220,7 +215,7 @@         y <- CL.head         if fmap snd y == Just (EventEndElement n)             then return $ Element n as $ compressNodes ns-            else lift $ monadThrow $ MissingEndElement n y+            else lift $ throwM $ MissingEndElement n y     goN = do         x <- CL.peek         case x of@@ -283,15 +278,15 @@ compressNodes (x:xs) = x : compressNodes xs  parseText :: ParseSettings -> TL.Text -> Either SomeException Document-parseText ps tl = runST-                $ runExceptionT-                $ CL.sourceList (TL.toChunks tl)-           $$ sinkTextDoc ps+parseText ps tl =+    runConduit+  $ CL.sourceList (TL.toChunks tl)+ .| sinkTextDoc ps  parseText_ :: ParseSettings -> TL.Text -> Document parseText_ ps = either throw id . parseText ps  sinkTextDoc :: MonadThrow m             => ParseSettings-            -> Consumer Text m Document-sinkTextDoc ps = P.parseTextPos ps =$= fromEvents+            -> ConduitT Text o m Document+sinkTextDoc ps = P.parseTextPos ps .| fromEvents
test/main.hs view
@@ -15,18 +15,15 @@ import qualified Text.XML.Stream.Parse        as P import qualified Text.XML.Unresolved          as D -import           Control.Applicative          ((<$>)) import           Control.Monad-import           Control.Monad.Trans.Class    (lift) import qualified Data.Set                     as Set import           Data.Text                    (Text) import qualified Data.Text                    as T import           Text.XML.Cursor              (($.//), ($/), ($//), ($|),                                                (&.//), (&/), (&//)) -import           Control.Monad.Trans.Resource (runResourceT) import qualified Control.Monad.Trans.Resource as C-import           Data.Conduit                 ((=$=))+import           Data.Conduit                 ((.|), runConduit, runConduitRes, ConduitT) import qualified Data.Conduit                 as C import qualified Data.Conduit.List            as CL import qualified Data.Map                     as Map@@ -139,7 +136,7 @@         ]  combinators :: Assertion-combinators = runResourceT $ P.parseLBS def input C.$$ do+combinators = runConduitRes $ P.parseLBS def input .| do     P.force "need hello" $ P.tag' "hello" (P.requireAttr "world") $ \world -> do         liftIO $ world @?= "true"         P.force "need child1" $ P.tagNoAttr "{mynamespace}child1" $ return ()@@ -186,7 +183,7 @@         testChooseElemOrTextIsChunkedText2  testChooseElemOrTextIsText :: Assertion-testChooseElemOrTextIsText = runResourceT $ P.parseLBS def input C.$$ do+testChooseElemOrTextIsText = runConduitRes $ P.parseLBS def input .| do     P.force "need hello" $ P.tagNoAttr "hello" $ do         x <- P.choose             [ P.tagNoAttr "failure" $ return "boom"@@ -203,7 +200,7 @@         ]  testChooseElemOrTextIsEncoded :: Assertion-testChooseElemOrTextIsEncoded = runResourceT $ P.parseLBS def input C.$$ do+testChooseElemOrTextIsEncoded = runConduitRes $ P.parseLBS def input .| do     P.force "need hello" $ P.tagNoAttr "hello" $ do         x <- P.choose             [ P.tagNoAttr "failure" $ return "boom"@@ -220,7 +217,7 @@         ]  testChooseElemOrTextIsEncodedNBSP :: Assertion-testChooseElemOrTextIsEncodedNBSP = runResourceT $ P.parseLBS def input C.$$ do+testChooseElemOrTextIsEncodedNBSP = runConduitRes $ P.parseLBS def input .| do     P.force "need hello" $ P.tagNoAttr "hello" $ do         x <- P.choose             [ P.tagNoAttr "failure" $ return "boom"@@ -238,7 +235,7 @@   testChooseElemOrTextIsWhiteSpace :: Assertion-testChooseElemOrTextIsWhiteSpace = runResourceT $ P.parseLBS def input C.$$ do+testChooseElemOrTextIsWhiteSpace = runConduitRes $ P.parseLBS def input .| do     P.force "need hello" $ P.tagNoAttr "hello" $ do         x <- P.choose             [ P.tagNoAttr "failure" $ return "boom"@@ -253,7 +250,7 @@         ]  testChooseTextOrElemIsWhiteSpace :: Assertion-testChooseTextOrElemIsWhiteSpace = runResourceT $ P.parseLBS def input C.$$ do+testChooseTextOrElemIsWhiteSpace = runConduitRes $ P.parseLBS def input .| do     P.force "need hello" $ P.tagNoAttr "hello" $ do         x <- P.choose             [ P.contentMaybe@@ -268,7 +265,7 @@         ]  testChooseElemOrTextIsChunkedText :: Assertion-testChooseElemOrTextIsChunkedText = runResourceT $ P.parseLBS def input C.$$ do+testChooseElemOrTextIsChunkedText = runConduitRes $ P.parseLBS def input .| do     P.force "need hello" $ P.tagNoAttr "hello" $ do         x <- P.choose             [ P.tagNoAttr "failure" $ return "boom"@@ -283,7 +280,7 @@         ]  testChooseElemOrTextIsChunkedText2 :: Assertion-testChooseElemOrTextIsChunkedText2 = runResourceT $ P.parseLBS def input C.$$ do+testChooseElemOrTextIsChunkedText2 = runConduitRes $ P.parseLBS def input .| do     P.force "need hello" $ P.tagNoAttr "hello" $ do         x <- P.choose             [ P.tagNoAttr "failure" $ return "boom"@@ -298,7 +295,7 @@         ]  testChooseElemOrTextIsElem :: Assertion-testChooseElemOrTextIsElem = runResourceT $ P.parseLBS def input C.$$ do+testChooseElemOrTextIsElem = runConduitRes $ P.parseLBS def input .| do     P.force "need hello" $ P.tagNoAttr "hello" $ do         x <- P.choose             [ P.tagNoAttr "success" $ return "success"@@ -315,7 +312,7 @@         ]  testChooseTextOrElemIsText :: Assertion-testChooseTextOrElemIsText = runResourceT $ P.parseLBS def input C.$$ do+testChooseTextOrElemIsText = runConduitRes $ P.parseLBS def input .| do     P.force "need hello" $ P.tagNoAttr "hello" $ do         x <- P.choose             [ P.contentMaybe@@ -332,7 +329,7 @@         ]  testChooseTextOrElemIsElem :: Assertion-testChooseTextOrElemIsElem = runResourceT $ P.parseLBS def input C.$$ do+testChooseTextOrElemIsElem = runConduitRes $ P.parseLBS def input .| do     P.force "need hello" $ P.tagNoAttr "hello" $ do         x <- P.choose             [ P.contentMaybe@@ -349,7 +346,7 @@         ]  testChooseEitherElem :: Assertion-testChooseEitherElem = runResourceT $ P.parseLBS def input C.$$ do+testChooseEitherElem = runConduitRes $ P.parseLBS def input .| do     P.force "need hello" $ P.tagNoAttr "hello" $ do         x <- P.choose             [ P.tagNoAttr "failure" $ return 1@@ -368,9 +365,9 @@ testManyYield :: Assertion testManyYield = do     -- Basically the same as testMany, but consume the streamed result-    result <- runResourceT $-        P.parseLBS def input C.$$ helloParser-        =$= CL.consume+    result <- runConduitRes $+        P.parseLBS def input .| helloParser+        .| CL.consume     length result @?= 5   where     helloParser = void $ P.tagNoAttr "hello" $ P.manyYield successParser@@ -389,12 +386,12 @@  testTakeContent :: Assertion testTakeContent = do-    result <- runResourceT $ P.parseLBS def input C.$$ rootParser+    result <- runConduitRes $ P.parseLBS def input .| rootParser     result @?= Just       [ EventContent (ContentText "Hello world !")       ]   where-    rootParser = P.tagNoAttr "root" $ void (P.takeContent >> P.takeContent) =$= CL.consume+    rootParser = P.tagNoAttr "root" $ void (P.takeContent >> P.takeContent) .| CL.consume     input = L.concat         [ "<?xml version='1.0'?>"         , "<!DOCTYPE foo []>\n"@@ -405,7 +402,7 @@  testTakeTree :: Assertion testTakeTree = do-    result <- runResourceT $ P.parseLBS def input C.$$ rootParser+    result <- runConduitRes $ P.parseLBS def input .| rootParser     result @?=       [ EventBeginDocument       , EventBeginDoctype "foo" Nothing@@ -417,7 +414,7 @@       , EventEndElement "a"       ]   where-    rootParser = void (P.takeTree "a" P.ignoreAttrs) =$= CL.consume+    rootParser = void (P.takeTree "a" P.ignoreAttrs) .| CL.consume     input = L.concat         [ "<?xml version='1.0'?>"         , "<!DOCTYPE foo []>\n"@@ -430,7 +427,7 @@  testTakeAnyTreeContent :: Assertion testTakeAnyTreeContent = do-    result <- runResourceT $ P.parseLBS def input C.$$ rootParser+    result <- runConduitRes $ P.parseLBS def input .| rootParser     result @?= Just       [ EventBeginElement "b" []       , EventContent (ContentText "Hello ")@@ -441,7 +438,7 @@       , EventEndElement "b"       ]   where-    rootParser = P.tagNoAttr "root" $ (P.takeAnyTreeContent >> void P.ignoreAnyTreeContent) =$= CL.consume+    rootParser = P.tagNoAttr "root" $ (P.takeAnyTreeContent >> void P.ignoreAnyTreeContent) .| CL.consume     input = L.concat         [ "<?xml version='1.0'?>"         , "<!DOCTYPE foo []>\n"@@ -452,7 +449,7 @@   testMany :: Assertion-testMany = runResourceT $ P.parseLBS def input C.$$ do+testMany = runConduitRes $ P.parseLBS def input .| do     P.force "need hello" $ P.tagNoAttr "hello" $ do         x <- P.many $ P.tagNoAttr "success" $ return ()         liftIO $ length x @?= 5@@ -470,7 +467,7 @@         ]  testMany' :: Assertion-testMany' = runResourceT $ P.parseLBS def input C.$$ do+testMany' = runConduitRes $ P.parseLBS def input .| do     P.force "need hello" $ P.tagNoAttr "hello" $ do         x <- P.many' $ P.tagNoAttr "success" $ return ()         liftIO $ length x @?= 5@@ -490,7 +487,7 @@         ]  testOrE :: IO ()-testOrE = runResourceT $ P.parseLBS def input C.$$ do+testOrE = runConduitRes $ runConduit $ P.parseLBS def input .| do     P.force "need hello" $ P.tagNoAttr "hello" $ do         x <- P.tagNoAttr "failure" (return 1) `P.orE`              P.tagNoAttr "success" (return 2)@@ -509,10 +506,11 @@         ]  testConduitParser :: Assertion-testConduitParser = runResourceT $ do-    x <- P.parseLBS def input-        C.$$ (P.force "need hello" $ P.tagNoAttr "hello" f)-        =$= CL.consume+testConduitParser = do+    x <-   runConduitRes+         $ P.parseLBS def input+        .| (P.force "need hello" $ P.tagNoAttr "hello" f)+        .| CL.consume     liftIO $ x @?= [1, 1, 1]   where     input = L.concat@@ -524,7 +522,7 @@         , "<item/>"         , "</hello>"         ]-    f :: C.MonadThrow m => C.Conduit Event m Int+    f :: C.MonadThrow m => ConduitT Event Int m ()     f = do         ma <- P.tagNoAttr "item" (return 1)         maybe (return ()) (\a -> C.yield a >> f) ma@@ -858,8 +856,8 @@             , "<bar a=\"a\" b=\"b\" c=\"c\"/>"             , "</foo>"             ]-        rs = def { Res.rsAttrOrder = \name m ->-                        case name of+        rs = def { Res.rsAttrOrder = \name' m ->+                        case name' of                             "foo" -> reverse $ Map.toAscList m                             _     -> Map.toAscList m                  }
xml-conduit.cabal view
@@ -1,5 +1,5 @@ name:            xml-conduit-version:         1.7.1.2+version:         1.8.0 license:         MIT license-file:    LICENSE author:          Michael Snoyman <michael@snoyman.com>, Aristid Breitkreuz <aristidb@googlemail.com>@@ -17,15 +17,14 @@  library     build-depends:   base                      >= 4        && < 5-                   , conduit                   >= 1.0      && < 1.3-                   , conduit-extra             >= 1.1-                   , resourcet                 >= 0.3      && < 1.2-                   , bytestring                >= 0.9+                   , conduit                   >= 1.3      && < 1.4+                   , conduit-extra             >= 1.3      && < 1.4+                   , resourcet                 >= 1.2      && < 1.3+                   , bytestring                >= 0.10.2                    , text                      >= 0.7                    , containers                >= 0.2                    , xml-types                 >= 0.3.4    && < 0.4                    , attoparsec                >= 0.10-                   , blaze-builder             >= 0.2      && < 0.5                    , transformers              >= 0.2      && < 0.6                    , data-default-class                    , monad-control             >= 0.3      && < 1.1