{-# LANGUAGE RankNTypes, BangPatterns #-}
module Crypto.Hash.Conduit
(
sinkHash
, hashFile
) where
import Crypto.Hash
import qualified Data.ByteString as B
import Data.Conduit
import Data.Conduit.Binary (sourceFile)
import Control.Monad.IO.Class (MonadIO, liftIO)
import Control.Monad.Trans.Resource (runResourceT)
sinkHash :: (Monad m, HashAlgorithm hash) => Consumer B.ByteString m (Digest hash)
sinkHash :: Consumer ByteString m (Digest hash)
sinkHash = Context hash -> ConduitT ByteString o m (Digest hash)
forall (m :: * -> *) a ba o.
(Monad m, HashAlgorithm a, ByteArrayAccess ba) =>
Context a -> ConduitT ba o m (Digest a)
sink Context hash
forall a. HashAlgorithm a => Context a
hashInit
where sink :: Context a -> ConduitT ba o m (Digest a)
sink ctx :: Context a
ctx = do
Maybe ba
b <- ConduitT ba o m (Maybe ba)
forall (m :: * -> *) i. Monad m => Consumer i m (Maybe i)
await
case Maybe ba
b of
Nothing -> Digest a -> ConduitT ba o m (Digest a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Digest a -> ConduitT ba o m (Digest a))
-> Digest a -> ConduitT ba o m (Digest a)
forall a b. (a -> b) -> a -> b
$! Context a -> Digest a
forall a. HashAlgorithm a => Context a -> Digest a
hashFinalize Context a
ctx
Just bs :: ba
bs -> Context a -> ConduitT ba o m (Digest a)
sink (Context a -> ConduitT ba o m (Digest a))
-> Context a -> ConduitT ba o m (Digest a)
forall a b. (a -> b) -> a -> b
$! Context a -> ba -> Context a
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
Context a -> ba -> Context a
hashUpdate Context a
ctx ba
bs
hashFile :: (MonadIO m, HashAlgorithm hash) => FilePath -> m (Digest hash)
hashFile :: FilePath -> m (Digest hash)
hashFile fp :: FilePath
fp = IO (Digest hash) -> m (Digest hash)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Digest hash) -> m (Digest hash))
-> IO (Digest hash) -> m (Digest hash)
forall a b. (a -> b) -> a -> b
$ ResourceT IO (Digest hash) -> IO (Digest hash)
forall (m :: * -> *) a. MonadUnliftIO m => ResourceT m a -> m a
runResourceT (FilePath -> ConduitT () ByteString (ResourceT IO) ()
forall (m :: * -> *) i.
MonadResource m =>
FilePath -> ConduitT i ByteString m ()
sourceFile FilePath
fp ConduitT () ByteString (ResourceT IO) ()
-> Sink ByteString (ResourceT IO) (Digest hash)
-> ResourceT IO (Digest hash)
forall (m :: * -> *) a b.
Monad m =>
Source m a -> Sink a m b -> m b
$$ Sink ByteString (ResourceT IO) (Digest hash)
forall (m :: * -> *) hash.
(Monad m, HashAlgorithm hash) =>
Consumer ByteString m (Digest hash)
sinkHash)