packages feed

conduit 1.0.1 → 1.0.2

raw patch · 3 files changed

+67/−2 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.Conduit.Text: LengthExceeded :: Int -> TextException
+ Data.Conduit.Text: linesBounded :: MonadThrow m => Int -> Conduit Text m Text

Files

Data/Conduit/Text.hs view
@@ -21,6 +21,7 @@     , ascii     , iso8859_1     , lines+    , linesBounded     , TextException (..)     ) where @@ -43,7 +44,7 @@ import Data.Conduit import qualified Data.Conduit.List as CL import Control.Monad.Trans.Class (lift)-import Control.Monad (unless)+import Control.Monad (unless,when)  -- | A specific character encoding. --@@ -64,6 +65,9 @@     showsPrec d c = showParen (d > 10) $         showString "Codec " . shows (codecName c) +++ -- | Emit each line separately -- -- Since 0.4.1@@ -86,6 +90,46 @@       where         (first', second) = T.break (== '\n') more +++-- | Variant of the lines function with an integer parameter.+-- The text length of any emitted line+-- never exceeds the value of the paramater. Whenever+-- this is about to happen a LengthExceeded exception+-- is thrown. This function should be used instead+-- of the lines function whenever we are dealing with+-- user input (e.g. a file upload) because we can't be sure that+-- user input won't have extraordinarily large lines which would+-- require large amounts of memory if consumed.+linesBounded :: MonadThrow m => Int -> Conduit T.Text m T.Text+linesBounded maxLineLen =+    loop 0 id+  where+    loop len front = await >>= maybe (finish front) (go len front)++    finish front =+        let final = front T.empty+         in unless (T.null final) (yield final)+    go len sofar more =+        case T.uncons second of+            Just (_, second') -> do+                let toYield = sofar first'+                    len' = len + T.length first'+                when (len' > maxLineLen)+                    (lift $ monadThrow (LengthExceeded maxLineLen))+                yield toYield+                go 0 id second'+            Nothing -> do+                let len' = len + T.length more+                when (len' > maxLineLen) $+                    (lift $ monadThrow (LengthExceeded maxLineLen))+                let rest = sofar more+                loop len' $ T.append rest+      where+        (first', second) = T.break (== '\n') more+++ -- | Convert text into bytes, using the provided codec. If the codec is -- not capable of representing an input character, an exception will be thrown. --@@ -123,6 +167,7 @@ -- Since 0.3.0 data TextException = DecodeException Codec Word8                    | EncodeException Codec Char+                   | LengthExceeded Int                    | TextException Exc.SomeException     deriving (Show, Typeable) instance Exc.Exception TextException
conduit.cabal view
@@ -1,5 +1,5 @@ Name:                conduit-Version:             1.0.1+Version:             1.0.2 Synopsis:            Streaming data processing library. Description:     @conduit@ is a solution to the streaming data problem, allowing for production, transformation, and consumption of streams of data in constant memory. It is an alternative to lazy I\/O which guarantees deterministic resource handling, and fits in the same general solution space as @enumerator@\/@iteratee@ and @pipes@. For a tutorial, please visit <https://haskell.fpcomplete.com/user/snoyberg/library-documentation/conduit-overview>.
test/main.hs view
@@ -401,6 +401,26 @@             x <- CL.sourceList ["foobarbaz", error "ignore me"] C.$$ CT.decode CT.utf8 C.=$ CL.head             x `shouldBe` Just "foobarbaz" +    describe "text lines bounded" $ do+        it "works across split lines" $+            (CL.sourceList [T.pack "abc", T.pack "d\nef"] C.$= CT.linesBounded 80 C.$$ CL.consume) ==+                [[T.pack "abcd", T.pack "ef"]]+        it "works with multiple lines in an item" $+            (CL.sourceList [T.pack "ab\ncd\ne"] C.$= CT.linesBounded 80 C.$$ CL.consume) ==+                [[T.pack "ab", T.pack "cd", T.pack "e"]]+        it "works with ending on a newline" $+            (CL.sourceList [T.pack "ab\n"] C.$= CT.linesBounded 80 C.$$ CL.consume) ==+                [[T.pack "ab"]]+        it "works with ending a middle item on a newline" $+            (CL.sourceList [T.pack "ab\n", T.pack "cd\ne"] C.$= CT.linesBounded 80 C.$$ CL.consume) ==+                [[T.pack "ab", T.pack "cd", T.pack "e"]]+        it "is not too eager" $ do+            x <- CL.sourceList ["foobarbaz", error "ignore me"] C.$$ CT.decode CT.utf8 C.=$ CL.head+            x `shouldBe` Just "foobarbaz"+        it "throws an exception when lines are too long" $ do+            x <- C.runExceptionT $ CL.sourceList ["hello\nworld"] C.$$ CT.linesBounded 4 C.=$ CL.consume+            show x `shouldBe` show (Left $ CT.LengthExceeded 4 :: Either CT.TextException ())+     describe "binary isolate" $ do         it "works" $ do             bss <- runResourceT $ CL.sourceList (replicate 1000 "X")