{-# 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)
sinkHash :: (Monad m, HashAlgorithm hash) => ConduitT B.ByteString o m (Digest hash)
sinkHash :: forall (m :: * -> *) hash o.
(Monad m, HashAlgorithm hash) =>
ConduitT ByteString o m (Digest hash)
sinkHash = forall {m :: * -> *} {a} {ba} {o}.
(Monad m, HashAlgorithm a, ByteArrayAccess ba) =>
Context a -> ConduitT ba o m (Digest a)
sink forall a. HashAlgorithm a => Context a
hashInit
where sink :: Context a -> ConduitT ba o m (Digest a)
sink Context a
ctx = do
Maybe ba
b <- forall (m :: * -> *) i o. Monad m => ConduitT i o m (Maybe i)
await
case Maybe ba
b of
Maybe ba
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$! forall a. HashAlgorithm a => Context a -> Digest a
hashFinalize Context a
ctx
Just ba
bs -> Context a -> ConduitT ba o m (Digest a)
sink forall a b. (a -> b) -> a -> b
$! 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 :: forall (m :: * -> *) hash.
(MonadIO m, HashAlgorithm hash) =>
FilePath -> m (Digest hash)
hashFile FilePath
fp = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) r.
MonadUnliftIO m =>
ConduitT () Void (ResourceT m) r -> m r
runConduitRes (forall (m :: * -> *) i.
MonadResource m =>
FilePath -> ConduitT i ByteString m ()
sourceFile FilePath
fp forall (m :: * -> *) a b c r.
Monad m =>
ConduitT a b m () -> ConduitT b c m r -> ConduitT a c m r
.| forall (m :: * -> *) hash o.
(Monad m, HashAlgorithm hash) =>
ConduitT ByteString o m (Digest hash)
sinkHash)