-- due to recent generic-arbitrary
{-# OPTIONS_GHC -fconstraint-solver-iterations=0 #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module System.Nix.Arbitrary.Hash where

import Data.ByteString (ByteString)
import Data.ByteString.Arbitrary ()
import Crypto.Hash (Digest, MD5(..), SHA1(..), SHA256(..), SHA512(..))
import Data.Dependent.Sum (DSum((:=>)))
import Data.Some (Some(Some))
import System.Nix.Hash (HashAlgo(..))

import Test.QuickCheck (Arbitrary(arbitrary), oneof)

import qualified Crypto.Hash

-- * Arbitrary @Digest@s

instance Arbitrary (Digest MD5) where
  arbitrary :: Gen (Digest MD5)
arbitrary = forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
Crypto.Hash.hash @ByteString (ByteString -> Digest MD5) -> Gen ByteString -> Gen (Digest MD5)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen ByteString
forall a. Arbitrary a => Gen a
arbitrary

instance Arbitrary (Digest SHA1) where
  arbitrary :: Gen (Digest SHA1)
arbitrary = forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
Crypto.Hash.hash @ByteString (ByteString -> Digest SHA1) -> Gen ByteString -> Gen (Digest SHA1)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen ByteString
forall a. Arbitrary a => Gen a
arbitrary

instance Arbitrary (Digest SHA256) where
  arbitrary :: Gen (Digest SHA256)
arbitrary = forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
Crypto.Hash.hash @ByteString (ByteString -> Digest SHA256)
-> Gen ByteString -> Gen (Digest SHA256)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen ByteString
forall a. Arbitrary a => Gen a
arbitrary

instance Arbitrary (Digest SHA512) where
  arbitrary :: Gen (Digest SHA512)
arbitrary = forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
Crypto.Hash.hash @ByteString (ByteString -> Digest SHA512)
-> Gen ByteString -> Gen (Digest SHA512)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen ByteString
forall a. Arbitrary a => Gen a
arbitrary

-- * Arbitrary @DSum HashAlgo Digest@s

instance Arbitrary (DSum HashAlgo Digest)  where
  arbitrary :: Gen (DSum HashAlgo Digest)
arbitrary = [Gen (DSum HashAlgo Digest)] -> Gen (DSum HashAlgo Digest)
forall a. HasCallStack => [Gen a] -> Gen a
oneof
    [ (HashAlgo MD5
HashAlgo_MD5 HashAlgo MD5 -> Digest MD5 -> DSum HashAlgo Digest
forall {k} (tag :: k -> *) (f :: k -> *) (a :: k).
tag a -> f a -> DSum tag f
:=>)    (Digest MD5 -> DSum HashAlgo Digest)
-> Gen (Digest MD5) -> Gen (DSum HashAlgo Digest)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (Digest MD5)
forall a. Arbitrary a => Gen a
arbitrary
    , (HashAlgo SHA1
HashAlgo_SHA1 HashAlgo SHA1 -> Digest SHA1 -> DSum HashAlgo Digest
forall {k} (tag :: k -> *) (f :: k -> *) (a :: k).
tag a -> f a -> DSum tag f
:=>)   (Digest SHA1 -> DSum HashAlgo Digest)
-> Gen (Digest SHA1) -> Gen (DSum HashAlgo Digest)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (Digest SHA1)
forall a. Arbitrary a => Gen a
arbitrary
    , (HashAlgo SHA256
HashAlgo_SHA256 HashAlgo SHA256 -> Digest SHA256 -> DSum HashAlgo Digest
forall {k} (tag :: k -> *) (f :: k -> *) (a :: k).
tag a -> f a -> DSum tag f
:=>) (Digest SHA256 -> DSum HashAlgo Digest)
-> Gen (Digest SHA256) -> Gen (DSum HashAlgo Digest)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (Digest SHA256)
forall a. Arbitrary a => Gen a
arbitrary
    , (HashAlgo SHA512
HashAlgo_SHA512 HashAlgo SHA512 -> Digest SHA512 -> DSum HashAlgo Digest
forall {k} (tag :: k -> *) (f :: k -> *) (a :: k).
tag a -> f a -> DSum tag f
:=>) (Digest SHA512 -> DSum HashAlgo Digest)
-> Gen (Digest SHA512) -> Gen (DSum HashAlgo Digest)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (Digest SHA512)
forall a. Arbitrary a => Gen a
arbitrary
    ]

instance Arbitrary (Some HashAlgo)  where
  arbitrary :: Gen (Some HashAlgo)
arbitrary =
    [Gen (Some HashAlgo)] -> Gen (Some HashAlgo)
forall a. HasCallStack => [Gen a] -> Gen a
oneof
    ([Gen (Some HashAlgo)] -> Gen (Some HashAlgo))
-> [Gen (Some HashAlgo)] -> Gen (Some HashAlgo)
forall a b. (a -> b) -> a -> b
$ Some HashAlgo -> Gen (Some HashAlgo)
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
    (Some HashAlgo -> Gen (Some HashAlgo))
-> [Some HashAlgo] -> [Gen (Some HashAlgo)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [
      HashAlgo MD5 -> Some HashAlgo
forall {k} (tag :: k -> *) (a :: k). tag a -> Some tag
Some HashAlgo MD5
HashAlgo_MD5
    , HashAlgo SHA1 -> Some HashAlgo
forall {k} (tag :: k -> *) (a :: k). tag a -> Some tag
Some HashAlgo SHA1
HashAlgo_SHA1
    , HashAlgo SHA256 -> Some HashAlgo
forall {k} (tag :: k -> *) (a :: k). tag a -> Some tag
Some HashAlgo SHA256
HashAlgo_SHA256
    , HashAlgo SHA512 -> Some HashAlgo
forall {k} (tag :: k -> *) (a :: k). tag a -> Some tag
Some HashAlgo SHA512
HashAlgo_SHA512
    ]