attoparsec-conduit (empty) → 0.0.0
raw patch · 5 files changed
+195/−0 lines, 5 filesdep +HUnitdep +QuickCheckdep +attoparsecsetup-changed
Dependencies added: HUnit, QuickCheck, attoparsec, base, blaze-builder, bytestring, conduit, hspec, text, transformers
Files
- Data/Conduit/Attoparsec.hs +80/−0
- LICENSE +30/−0
- Setup.lhs +7/−0
- attoparsec-conduit.cabal +43/−0
- test/main.hs +35/−0
+ Data/Conduit/Attoparsec.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE FlexibleContexts #-}++-- |+-- Copyright: 2011 Michael Snoyman, 2010 John Millikin+-- License: MIT+--+-- Turn an Attoparsec parser into a 'C.Sink'.+--+-- This code was taken from attoparsec-enumerator and adapted for conduits.+module Data.Conduit.Attoparsec+ ( ParseError (..)+ , AttoparsecInput+ , sinkParser+ ) where++import Control.Exception (Exception)+import Data.Typeable (Typeable)+import qualified Data.ByteString as B+import qualified Data.Text as T++import qualified Data.Attoparsec.ByteString+import qualified Data.Attoparsec.Text+import qualified Data.Attoparsec.Types as A+import qualified Data.Conduit as C+import Control.Monad.Trans.Class (lift)++-- | The context and message from a 'A.Fail' value.+data ParseError = ParseError+ { errorContexts :: [String]+ , errorMessage :: String+ } | DivergentParser+ deriving (Show, Typeable)++instance Exception ParseError++-- | A class of types which may be consumed by an Attoparsec parser.+class AttoparsecInput a where+ parseA :: A.Parser a b -> a -> A.IResult a b+ feedA :: A.IResult a b -> a -> A.IResult a b+ empty :: a+ isNull :: a -> Bool+ notEmpty :: [a] -> [a]++instance AttoparsecInput B.ByteString where+ parseA = Data.Attoparsec.ByteString.parse+ feedA = Data.Attoparsec.ByteString.feed+ empty = B.empty+ isNull = B.null+ notEmpty = filter (not . B.null)++instance AttoparsecInput T.Text where+ parseA = Data.Attoparsec.Text.parse+ feedA = Data.Attoparsec.Text.feed+ empty = T.empty+ isNull = T.null+ notEmpty = filter (not . T.null)++-- | Convert an Attoparsec 'A.Parser' into a 'C.Sink'. The parser will+-- be streamed bytes until it returns 'A.Done' or 'A.Fail'.+--+-- If parsing fails, a 'ParseError' will be thrown with 'C.resourceThrow'.+sinkParser :: (AttoparsecInput a, C.ResourceThrow m) => A.Parser a b -> C.Sink a m b+sinkParser p0 = C.sinkState+ (parseA p0)+ push+ close+ where+ push parser c =+ case parser c of+ A.Done leftover x ->+ let lo = if isNull leftover then Nothing else Just leftover+ in return (parser, C.Done lo x)+ A.Fail _ contexts msg -> lift $ C.resourceThrow $ ParseError contexts msg+ A.Partial p -> return (p, C.Processing)+ close parser = do+ case feedA (parser empty) empty of+ A.Done _leftover y -> return y+ A.Fail _ contexts msg -> lift $ C.resourceThrow $ ParseError contexts msg+ A.Partial _ -> lift $ C.resourceThrow DivergentParser
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2011, Michael Snoyman++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.++ * Neither the name of Michael Snoyman nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"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 COPYRIGHT+OWNER OR CONTRIBUTORS 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.lhs view
@@ -0,0 +1,7 @@+#!/usr/bin/env runhaskell++> module Main where+> import Distribution.Simple++> main :: IO ()+> main = defaultMain
+ attoparsec-conduit.cabal view
@@ -0,0 +1,43 @@+Name: attoparsec-conduit+Version: 0.0.0+Synopsis: Turn attoparsec parsers into sinks.+Description: Turn attoparsec parsers into sinks.+License: BSD3+License-file: LICENSE+Author: Michael Snoyman+Maintainer: michael@snoyman.com+Category: Data, Conduit+Build-type: Simple+Cabal-version: >=1.8+Homepage: http://github.com/snoyberg/conduit+extra-source-files: test/main.hs++Library+ Exposed-modules: Data.Conduit.Attoparsec+ Build-depends: base >= 4 && < 5+ , transformers >= 0.2.2 && < 0.3+ , bytestring >= 0.9+ , attoparsec >= 0.10+ , text >= 0.11+ , conduit >= 0.0 && < 0.1+ ghc-options: -Wall++test-suite test+ hs-source-dirs: test+ main-is: main.hs+ type: exitcode-stdio-1.0+ cpp-options: -DTEST+ build-depends: conduit+ , base+ , hspec+ , HUnit+ , QuickCheck+ , bytestring+ , blaze-builder+ , transformers+ , text+ ghc-options: -Wall++source-repository head+ type: git+ location: git://github.com/snoyberg/conduit.git
+ test/main.hs view
@@ -0,0 +1,35 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE CPP #-}+import Test.Hspec.Monadic+{-+import Test.Hspec.HUnit ()+import Test.Hspec.QuickCheck (prop)+import Test.HUnit++import qualified Data.Conduit as C+import qualified Data.Conduit.List as CL+import qualified Data.Conduit.Lazy as CLazy+import qualified Data.Conduit.Text as CT+import Data.Conduit.Blaze (builderToByteString)+import Data.Conduit (runResourceT)+import Control.Monad.ST (runST)+import Data.Monoid+import qualified Data.ByteString as S+import qualified Data.IORef as I+import Blaze.ByteString.Builder (fromByteString, toLazyByteString, insertLazyByteString)+import qualified Data.ByteString.Lazy as L+import Data.ByteString.Lazy.Char8 ()+import Data.Maybe (catMaybes)+import Control.Monad.Trans.Writer (Writer)+import qualified Data.Text as T+import qualified Data.Text.Lazy as TL+import qualified Data.Text.Lazy.Encoding as TLE+import Control.Monad.Trans.Resource (runExceptionT_, withIO, resourceForkIO)+import Control.Concurrent (threadDelay, killThread)+import Control.Monad.IO.Class (liftIO)+import Control.Applicative (pure, (<$>), (<*>))+-}++main :: IO ()+main = hspecX $ do+ return ()