packages feed

pipes-cellular (empty) → 0.0.0.1

raw patch · 7 files changed

+302/−0 lines, 7 filesdep +basedep +bytestringdep +data-cellsetup-changed

Dependencies added: base, bytestring, data-cell, pipes

Files

+ LICENSE view
@@ -0,0 +1,28 @@++  Pipes-based combinators for cellular data processing+  ====================================================++    Copyright © 2015 Patryk Zadarnowski «pat@jantar.org».+    All rights reserved.++  Redistribution and use in source and binary forms, with or without+  modification, are permitted provided that the following conditions+  are met: ➀ Redistributions of source code must retain the above+  copyright notice, this list of conditions and the following disclaimer.+  ➁ Redistributions in binary form must reproduce the above copyright notice,+  this list of conditions and the following disclaimer in the documentation+  and/or other materials provided with the distribution. ➂ The name of any+  author may not be used to endorse or promote products derived from this+  software without their specific prior written permission.++  THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,+  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY+  AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO EVENT SHALL+  THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,+  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,+  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA OR PROFITS;+  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,+  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR+  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF+  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+
+ Setup.hs view
@@ -0,0 +1,3 @@+#! /usr/bin/env runhaskell+import Distribution.Simple+main = defaultMain
+ pipes-cellular.cabal view
@@ -0,0 +1,47 @@+name:           pipes-cellular+version:        0.0.0.1+synopsis:       Pipes-based combinators for cellular data processing+homepage:       https://github.com/zadarnowski/pipes-cellular+category:       Control, Pipes+stability:      alpha++author:         Patryk Zadarnowski+maintainer:     Patryk Zadarnowski <pat@jantar.org>++copyright:      Copyright (c) 2015 Patryk Zadarnowski++description:++    This library provides a number of miscellaneous utilities+    for pipes-based processing of cellular data.++cabal-version:  >= 1.18+build-type:     Simple+license:        BSD3+license-file:   LICENSE++source-repository head+  type:         git+  location:     https://github.com/zadarnowski/pipes-cellular.git++source-repository this+  type:         git+  location:     https://github.com/zadarnowski/pipes-cellular.git+  tag:          0.0.0.1++library+  hs-source-dirs:   src+  default-language: Haskell2010+  ghc-options:      -Wall -fno-warn-unused-do-bind -fno-warn-missing-signatures++  exposed-modules:+    Pipes.ByteString.Chunks+    Pipes.Cell+    Pipes.Maybe+    Pipes.Either++  build-depends:+    base        >= 4.8 && < 5,+    bytestring  >= 0.10.6.0,+    data-cell   >= 1.0.0.2,+    pipes       >= 4.1.5
+ src/Pipes/ByteString/Chunks.lhs view
@@ -0,0 +1,108 @@+> -- | Module:    Pipes.ByteString.Chunks+> -- Description: Chunked lazy bytestring pipes+> -- Copyright:   © 2015 Patryk Zadarnowski <pat@jantar.org>+> -- License:     BSD3+> -- Maintainer:  pat@jantar.org+> -- Stability:   experimental+> -- Portability: portable+> --+> -- When binary data is streamed through a pipe, it's often partitioned+> -- arbitrarily into /packets/ with no semantic significance, beyond+> -- facilitation of processing in constant space. This is similar to+> -- the chunking mechanism within lazy bytestrings, and, accordingly,+> -- it's often convenient to unify the two mechanisms, by converting+> -- between pipes over lazy bytestrings and pipes over strict chunks+> -- these bytestrings. This module provides efficient implementations+> -- of these conversions.++> module Pipes.ByteString.Chunks (+>   toChunks, fromChunks+> ) where++> import Data.ByteString (ByteString)+> import Data.Int+> import Pipes++> import qualified Data.ByteString as ByteString+> import qualified Data.ByteString.Lazy as Lazy+> import qualified Pipes.Prelude as Pipes++> -- | An infinite pipe that converts lazy bytestring+> --   input into strict bytestring chunk output.++> toChunks :: Monad m => Pipe Lazy.ByteString ByteString m r+> toChunks = Pipes.map Lazy.toChunks >-> Pipes.concat++> -- | An infinite pipe that converts strict bytestrings+> --   into lazy bytestrings with the specified minimum+> --   and maximum size, without copying any data.++> fromChunks :: Monad m => Int64 -> Int64 -> Pipe ByteString Lazy.ByteString m r+> fromChunks m n+>   | (m > n || n <= 0) = error ("fromChunks: invalid string size range: [" ++ show m ++ ".." ++ show n ++ "]")+>   | (m <= 0) = fromMaxChunks n+>   | (n >= fromIntegral (maxBound::Int)) = fromMinChunks m+>   | (m == n) = fromExactChunks n+>   | otherwise = loop m n []+>  where+>   loop rm rn cs = do+>     c <- await+>     loop' rm rn cs c (fromIntegral (ByteString.length c))+>   loop' rm rn cs c cl =+>     if cl == 0 then+>       loop rm rn cs -- skip empty chunks+>     else+>       if cl < rm then+>         loop (rm - cl) (rn - cl) (c:cs)+>       else if cl <= rn then+>         yield (Lazy.fromChunks (reverse (c:cs))) >> loop m n []+>       else+>         let (c1, c2) = ByteString.splitAt (fromIntegral rn) c+>         in yield (Lazy.fromChunks (reverse (c1:cs))) >> loop' m n [] c2 (cl - rn)++> fromMaxChunks :: Monad m => Int64 -> Pipe ByteString Lazy.ByteString m r+> fromMaxChunks n+>   | (n <= 0) = error ("Pipes.fromChunks: invalid maximum chunk size: " ++ show n)+>   | (n >= fromIntegral (maxBound::Int)) = Pipes.map Lazy.fromStrict+>   | otherwise = loop+>  where+>   loop = do+>     c <- await+>     loop' c (fromIntegral (ByteString.length c))+>   loop' c cl+>     | (cl <= n) = yield (Lazy.fromStrict c) >> loop+>     | otherwise = let (c1, c2) = ByteString.splitAt n' c in yield (Lazy.fromStrict c1) >> loop' c2 (cl - n)+>   n' = fromIntegral n++> fromMinChunks :: Monad m => Int64 -> Pipe ByteString Lazy.ByteString m r+> fromMinChunks n+>   | (n > 0) = loop n []+>   | otherwise = Pipes.map Lazy.fromStrict+>  where+>   loop r cs = do+>     c <- await+>     loop' r cs c (fromIntegral (ByteString.length c))+>   loop' r cs c cl =+>     if cl == 0 then+>       loop r cs -- skip empty chunks+>     else+>       if cl < r then+>         loop (r - cl) (c:cs)+>       else+>         yield (Lazy.fromChunks (reverse (c:cs))) >> loop 0 []++> fromExactChunks :: Monad m => Int64 -> Pipe ByteString Lazy.ByteString m r+> fromExactChunks n+>   | (n > 0) = loop n []+>   | otherwise = error ("Pipes.fromChunks: invalid chunk size: " ++ show n)+>  where+>   loop r cs = do+>     c <- await+>     loop' r cs c (fromIntegral (ByteString.length c))+>   loop' r cs c cl =+>     if cl == 0 then+>       loop r cs -- skip empty chunks+>     else case compare cl r of+>       LT -> loop (r - cl) (c:cs)+>       EQ -> yield (Lazy.fromChunks (reverse (c:cs))) >> loop 0 []+>       GT -> let (c1, c2) = ByteString.splitAt (fromIntegral r) c in yield (Lazy.fromChunks (reverse (c1:cs))) >> loop' 0 [] c2 (cl - r)
+ src/Pipes/Cell.lhs view
@@ -0,0 +1,41 @@+> -- | Module:    Pipes.Cell+> -- Description: Convertions between cell-based and row-based representations of tabular data+> -- Copyright:   © 2015 Patryk Zadarnowski <pat@jantar.org>+> -- License:     BSD3+> -- Maintainer:  pat@jantar.org+> -- Stability:   experimental+> -- Portability: portable+> --+> -- Pipes converting between cellular and traditional tabular data.++> module Pipes.Cell (+>   toRows, fromRows,+> ) where++> import Control.Monad+> import Data.Cell+> import Pipes++> -- | An infinite pipe that converts a stream of cells into a stream of rows,+> --   with each row represented by a non-empty list of cell values.++> toRows :: (Monad m, Monoid a) => Pipe (Cell a) [a] m ()+> toRows = go [] []+>  where+>   go row cell = do+>     Cell part d <- await+>     let cell' = part:cell+>     case d of+>       EOP -> go row cell'+>       EOC -> go (mconcat (reverse cell') : row) []+>       EOR -> yield (reverse (mconcat (reverse cell') : row)) >> go [] []+>       EOT -> yield (reverse (mconcat (reverse cell') : row)) >> return ()++> -- | An infinite pipe that converts a stream of rows to a stream of cells.++> fromRows :: Monad m => Pipe [a] (Cell a) m r+> fromRows = forever (await >>= fromRow)+>  where+>   fromRow (x:xs) = yield (Cell x (if null xs then EOR else EOC)) >> fromRow xs+>   fromRow [] = return ()+
+ src/Pipes/Either.lhs view
@@ -0,0 +1,45 @@+> -- | Module:    Pipes.Either+> -- Description: Utilities for conversion between finite and infinite pipes+> -- Copyright:   © 2015 Patryk Zadarnowski <pat@jantar.org>+> -- License:     BSD3+> -- Maintainer:  pat@jantar.org+> -- Stability:   experimental+> -- Portability: portable+> --+> -- Conversion between finite and infinite pipe using the 'Either' type.++> module Pipes.Either (+>   catWhileLeft, catWhileRight,+>   extendWithLeft, extendWithRight,+> ) where++> import Control.Monad+> import Pipes.Core++> -- | A pipe that receives and forwards all 'Left' values in its input+> --   up to the first occurence of a 'Right r' value, returning the value @r@.++> catWhileLeft :: Monad m => Pipe (Either a r) a m r+> catWhileLeft = go+>  where go = request () >>= either (respond >=> const go) return++> -- | A pipe that receives and forwards all 'Right' values in its input+> --   up to the first occurence of a 'Left r' value, returning the value @r@.++> catWhileRight :: Monad m => Pipe (Either r a) a m r+> catWhileRight = go+>  where go = request () >>= either return (respond >=> const go)++> -- | Converts a finite pipe into an infinite pipe, in which the original+> --   pipe's values are followed by an infinite stream of 'Left r'.++> extendWithLeft :: Monad m => Pipe a b m r -> Pipe a (Either r b) m r'+> extendWithLeft p = (p //> respond . Right) >>= forever . respond . Left++> -- | Converts a finite pipe into an infinite pipe, in which the original+> --   pipe's values are followed by an infinite stream of 'Right r'.++> extendWithRight :: Monad m => Pipe a b m r -> Pipe a (Either b r) m r'+> extendWithRight p = (p //> respond . Left) >>= forever . respond . Right++
+ src/Pipes/Maybe.lhs view
@@ -0,0 +1,30 @@+> -- | Module:    Pipes.Maybe+> -- Description: Utilities for conversion between finite and infinite pipes+> -- Copyright:   © 2015 Patryk Zadarnowski <pat@jantar.org>+> -- License:     BSD3+> -- Maintainer:  pat@jantar.org+> -- Stability:   experimental+> -- Portability: portable+> --+> -- Conversion between finite and infinite pipe using the 'Either' type.++> module Pipes.Maybe (+>   catWhileJust, extendWithNothing+> ) where++> import Control.Monad+> import Pipes.Core++> -- | A pipe that receives and forwards all 'Just' values in its input+> --   up to the first occurence of 'Nothing'.++> catWhileJust :: Monad m => Pipe (Maybe a) a m ()+> catWhileJust = go+>  where go = request () >>= maybe (return ()) (respond >=> const go)++> -- | Converts a finite pipe into an infinite pipe, in which the original+> --   pipe's values are followed by an infinite stream of 'Nothing'.++> extendWithNothing :: Monad m => Pipe a b m r -> Pipe a (Maybe b) m r'+> extendWithNothing p = (p //> respond . Just) >> forever (respond Nothing)+