module Crypto.Hash.ADT (
    Context(..)
  , HashAlgorithm(..)
  , Digest (..)
  ) where

import           Data.ByteString (ByteString)
import           Data.Int

data Context a = Context {
      forall a. Context a -> Int64
ctxTotalBytesRead :: {-# UNPACK #-} !Int64
    , forall a. Context a -> Int
ctxBufferRead     :: {-# UNPACK #-} !Int
    , forall a. Context a -> ByteString
ctxBuffer         :: {-# UNPACK #-} !ByteString
    , forall a. Context a -> a
ctxHashValueAcc   :: !a
    } deriving Int -> Context a -> ShowS
forall a. Show a => Int -> Context a -> ShowS
forall a. Show a => [Context a] -> ShowS
forall a. Show a => Context a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Context a] -> ShowS
$cshowList :: forall a. Show a => [Context a] -> ShowS
show :: Context a -> String
$cshow :: forall a. Show a => Context a -> String
showsPrec :: Int -> Context a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Context a -> ShowS
Show

instance Functor Context where
  fmap :: forall a b. (a -> b) -> Context a -> Context b
fmap a -> b
f (Context Int64
t Int
r ByteString
b a
v) = forall a. Int64 -> Int -> ByteString -> a -> Context a
Context Int64
t Int
r ByteString
b (a -> b
f a
v)

newtype Digest a = Digest String deriving Int -> Digest a -> ShowS
forall a. Int -> Digest a -> ShowS
forall a. [Digest a] -> ShowS
forall a. Digest a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Digest a] -> ShowS
$cshowList :: forall a. [Digest a] -> ShowS
show :: Digest a -> String
$cshow :: forall a. Digest a -> String
showsPrec :: Int -> Digest a -> ShowS
$cshowsPrec :: forall a. Int -> Digest a -> ShowS
Show

-- | Hash algorithm interface
--
-- provides classic init\/update\/final API. however,
-- user should call higher level API such as hash or hashLazy.
class HashAlgorithm a where
    hashBlockSize :: a -> Int
    hashDigestSize :: a -> Int
    hashInit   :: Context a
    hashUpdate :: Context a -> ByteString -> Context a
    hashFinal  :: Context a -> a