packages feed

binary-conduit (empty) → 1.0

raw patch · 5 files changed

+192/−0 lines, 5 filesdep +QuickCheckdep +basedep +binarysetup-changed

Dependencies added: QuickCheck, base, binary, bytestring, conduit, conduit-binary, hspec, quickcheck-assertions

Files

+ Data/Conduit/Serialization/Binary.hs view
@@ -0,0 +1,77 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE Rank2Types #-}+module Data.Conduit.Serialization.Binary+  ( conduitDecode+  , conduitEncode+  , conduitGet+  , conduitPut+  , sourcePut+  , sinkGet+  , ParseError(..)+  )+  where++import           Control.Exception+import           Data.Binary+import           Data.Binary.Get+import           Data.Binary.Put+import           Data.ByteString (ByteString)+import qualified Data.ByteString.Lazy as LBS++import           Data.Conduit+import qualified Data.Conduit.List    as CL+import           Data.Typeable+++data ParseError = ParseError+      { uncomsumed :: ByteString  -- ^ uncomsumed data+      , offset     :: ByteOffset  -- ^ current offset+      , content    :: String      -- ^ error content+      } deriving (Show, Typeable)++instance Exception ParseError++-- | Runs default 'Decoder' repeadetly on a input stream+conduitDecode :: (Binary b, MonadThrow m) => Conduit ByteString m b+conduitDecode = conduitGet get++-- | Runs default encoder on a input stream+conduitEncode :: (Binary b, MonadThrow m) => Conduit b m ByteString+conduitEncode = CL.map put =$= conduitPut++-- | Runs getter repeadetelly on a input stream+conduitGet :: (Binary b, MonadThrow m) => Get b -> Conduit ByteString m b+conduitGet g = start+  where +    start = do mx <- await+               case mx of+                  Nothing -> return ()+                  Just x -> conduit (runGetIncremental g `pushChunk` x)+    conduit p = await >>= go . flip (maybe pushEndOfInput (flip pushChunk)) p+        where+          go (Done bs _ v) = do yield v+                                go (runGetIncremental get `pushChunk` bs)+          go (Fail u o e)  = monadThrow (ParseError u o e)+          go (Partial _)   = start++-- | Runs putter repeadelty on a input stream+conduitPut :: MonadThrow m => Conduit Put m ByteString+conduitPut = conduit +  where +    conduit = do mx <- await+                 case mx of+                     Nothing -> return ()+                     Just x  -> do sourcePut x $$ CL.mapM_ yield+                                   conduit++-- | Create stream of strict bytestring from 'Put' value+sourcePut :: (MonadThrow m) => Put -> Producer m ByteString+sourcePut = CL.sourceList . LBS.toChunks . runPut++-- | Decode message from input stream+sinkGet :: (Binary b, MonadThrow m) => Get b -> Consumer ByteString m b+sinkGet f = sink (runGetIncremental f)+  where+      sink (Done bs _ v)  = leftover bs >> return v+      sink (Fail u o e)   = monadThrow (ParseError u o e)+      sink (Partial next) = await >>= sink . next
+ LICENSE view
@@ -0,0 +1,25 @@+Copyright (c) <year> <copyright holders>++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.++[Except as contained in this notice, the name of <copyright holders>+shall not be used in advertising or otherwise to promote the sale, use+or other dealings in this Software without prior written authorization+from <copyright holders>.]
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ binary-conduit.cabal view
@@ -0,0 +1,36 @@+name:                binary-conduit+version:             1.0+synopsis:            data serialization/deserialization conduit library+description:         The binary-conduit package.+      Allow binary serialization using iterative conduit interface.+license:             MIT+license-file:        LICENSE+author:              Alexander Vershilov+maintainer:          alexander.vershilov@gmail.com+copyright:           2013 Alexander Vershilov+category:            Conduit+stability:           Experimental+homepage:            http://github.com/qnikst/binary-conduit+bug-reports:         http://github.com/qnikst/binary-conduit/issues+build-type:          Simple+cabal-version:       >=1.8++library+  exposed-modules:     +    Data.Conduit.Serialization.Binary+  build-depends:       base >=4 && <5,+                       conduit >= 1.0 && < 1.1,+                       bytestring >= 0.9 && < 10.3,+                       binary >= 0.6 && < 0.8+  ghc-options: -Wall++test-suite test-binary-conduit+  type: exitcode-stdio-1.0+  main-is: Main.hs+  hs-source-dirs: test/+  build-depends: base, QuickCheck, quickcheck-assertions, conduit-binary, +    hspec, conduit, binary, bytestring++source-repository head+  type: git+  location: git://github.com/qnikst/binary-conduit/
+ test/Main.hs view
@@ -0,0 +1,52 @@+import Data.Binary+import Data.Binary.Put+import Data.ByteString+import qualified Data.ByteString.Lazy as LBS+import Data.Conduit+import qualified Data.Conduit.List as CL+import Data.Conduit.Serialization.Binary+import Test.Hspec+import Test.Hspec.QuickCheck+import Test.QuickCheck.Assertions+import Test.QuickCheck.Property+import Test.QuickCheck.Monadic+import Test.QuickCheck++-- | check conduitEncode =$= conduitDecode == id+prop_eq :: (Binary a,Eq a) => [a] -> Property+prop_eq xs = monadicIO $ do +    xs' <- runExceptionT  $ CL.sourceList xs +              $= enc xs+              =$= dec xs+              $$ CL.consume+    case xs' of+        Left e -> fail "exception"+        Right x -> assert $ x == xs+  where enc :: (Binary a, MonadThrow m) => [a] -> Conduit a m ByteString+        enc _ = conduitEncode +        dec :: (Binary a, MonadThrow m) => [a] -> Conduit ByteString m a+        dec _ = conduitDecode++prop_sink :: (Binary a,Eq a) => (a,a) -> Property+prop_sink (a,b) = monadicIO $ do+    Right (a',b') <- runExceptionT $ CL.sourceList [a,b]+                         $= enc a+                         $$ do a' <- sinkGet get+                               b' <- CL.consume+                               return (a',b')++    assert $ a == a'+    assert $ runPut (put b) == LBS.fromChunks b'+  where enc :: (Binary a, MonadThrow m) => a -> Conduit a m ByteString+        enc _ = conduitEncode +        dec :: (Binary a, MonadThrow m) => a -> Conduit ByteString m a+        dec _ = conduitDecode++main = hspec $ describe "conduitEncode =$= conduitDecode == id" $ do+    prop "int" $ (prop_eq :: [Int] -> Property)+    prop "string" $ (prop_eq :: [String] -> Property)+    prop "maybe int" $ (prop_eq :: [Maybe Int] -> Property)+    prop "either int string" $ (prop_eq :: [Either Int String] -> Property)+    prop "ab" $ (prop_sink :: (Int,Int) -> Property)+    prop "ab" $ (prop_sink :: (String,String) -> Property)+