packages feed

pipes-csv (empty) → 1.0.0

raw patch · 4 files changed

+155/−0 lines, 4 filesdep +basedep +bytestringdep +cassavasetup-changed

Dependencies added: base, bytestring, cassava, pipes, text

Files

+ LICENSE view
@@ -0,0 +1,21 @@+The MIT License (MIT)++Copyright (c) 2013 William Casarin++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.
+ Pipes/Csv.hs view
@@ -0,0 +1,105 @@+{-| This module allows constant-space CSV parsing.++    It feeds 'ByteString's into cassavas incremental CSV parser to attain true+    constant-space record streaming.+-}++{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE OverloadedStrings #-}++module Pipes.Csv (+  feedParser,+  feedHeaderParser,+  decode,+  decodeWith,+  decodeByName,+  decodeByNameWith+) where++import qualified Data.Csv.Incremental as CI+import qualified Data.ByteString as B++import Data.Csv.Incremental (Parser(..), HeaderParser(..))+import Data.Csv (DecodeOptions, FromRecord,+                 FromNamedRecord, defaultDecodeOptions)+import Data.ByteString (ByteString)+import Pipes++-- | Create a Record 'Producer' by feeding 'ByteString's into a 'Parser'+feedParser :: Monad m+           => Parser a+           -> Producer ByteString m ()+           -> Producer (Either String a) m ()+feedParser parser source = case parser of+    Fail _ e  -> yield (Left e)+    Done es   -> each es+    Some es k -> each es >> cont k source+    Partial k -> cont k source+  where+    cont = continue feedParser+++-- | Create a NamedRecord 'Producer' by feeding 'ByteString's into a 'Parser'+feedHeaderParser :: (Monad m, FromNamedRecord a)+                 => HeaderParser (Parser a)+                 -> Producer ByteString m ()+                 -> Producer (Either String a) m ()+feedHeaderParser headerParser source = case headerParser of+    FailH bs e -> yield (Left e)+    PartialH k -> cont k source+    DoneH _ p  -> feedParser p source+  where+    cont = continue feedHeaderParser+++-- | Handle continuations properly within a Producer+continue :: (Monad (t m), Monad m, MonadTrans t)+         => (a -> Producer ByteString m () -> t m b)+         -> (ByteString -> a)+         -> Producer ByteString m ()+         -> t m b+continue feed k producer = do+  x <- lift (next producer)+  case x of+    Left () -> feed (k B.empty) (return ())+    Right (bs, producer') ->+      if (B.null bs)+      then continue feed k producer'+      else feed (k bs) producer'++++-- | Equivalent to @'decodeWith' 'defaultDecodeOptions'@.+decode :: (Monad m, FromRecord a)+       => Bool+       -> Producer ByteString m ()+       -> Producer (Either String a) m ()+decode = decodeWith defaultDecodeOptions+++-- | Create a 'Producer' that takes a 'ByteString' 'Producer' as input,+-- producing either errors or 'FromRecord's.+decodeWith :: (Monad m, FromRecord a)+           => DecodeOptions+           -> Bool+           -> Producer ByteString m ()+           -> Producer (Either String a) m ()+decodeWith opts skipHeader src = feedParser (CI.decodeWith opts skipHeader) src+++-- | Equivalent to @'decodeByNameWith' 'defaultDecodeOptions'@.+decodeByName :: (Monad m, FromNamedRecord a)+             => Producer ByteString m ()+             => Producer (Either String a) m ()+decodeByName = decodeByNameWith defaultDecodeOptions+++-- | Create a 'Producer' that takes a 'ByteString' 'Producer' as input,+-- producing either errors or 'FromNamedRecord's.+decodeByNameWith :: (Monad m, FromNamedRecord a)+                 => DecodeOptions+                 -> Producer ByteString m ()+                 -> Producer (Either String a) m ()+decodeByNameWith opts src = feedHeaderParser (CI.decodeByNameWith opts) src++
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ pipes-csv.cabal view
@@ -0,0 +1,27 @@+name:                pipes-csv+version:             1.0.0+synopsis: Fast, streaming csv parser+license:             MIT+license-file:        LICENSE+author:              William Casarin+maintainer:          will@casarin.me+category:            Pipes, CSV+build-type:          Simple+cabal-version:       >=1.10+Description:+  `pipes-csv` is a streaming csv parser built on top of `cassava` and `pipes`++source-repository head+  type: git+  location: https://github.com/jb55/pipes-csv++library+  ghc-options: -Wall -O2+  exposed-modules:   Pipes.Csv+  build-depends: base       >= 4.6  && < 4.7+               , text       >= 0.11 && < 0.12+               , bytestring >= 0.10 && < 0.11+               , cassava    >= 0.2  && < 0.3+               , pipes      >= 4    && < 5+  default-language:    Haskell2010+