1
1
{-# LANGUAGE AllowAmbiguousTypes #-}
2
2
{-# LANGUAGE CPP #-}
3
3
{-# LANGUAGE OverloadedStrings #-}
4
+ {-# LANGUAGE TemplateHaskell #-}
4
5
{-# OPTIONS_GHC -Wno-orphans #-}
5
6
{-|
6
7
Description : Cryptographic hashing interface for hnix-store, on top
7
8
of the cryptohash family of libraries.
8
9
-}
9
10
10
11
module System.Nix.Hash
11
- ( NamedAlgo (.. )
12
+ ( HashAlgo (.. )
13
+ , NamedAlgo (.. )
14
+ , algoToText
15
+ , textToAlgo
12
16
, SomeNamedDigest (.. )
13
17
, mkNamedDigest
14
18
@@ -23,6 +27,10 @@ module System.Nix.Hash
23
27
24
28
import Crypto.Hash (Digest , HashAlgorithm , MD5 (.. ), SHA1 (.. ), SHA256 (.. ), SHA512 (.. ))
25
29
import Data.ByteString (ByteString )
30
+ import Data.Constraint.Extras (Has (has ))
31
+ import Data.Constraint.Extras.TH (deriveArgDict )
32
+ import Data.Kind (Type )
33
+ import Data.Some (Some (Some ))
26
34
import Data.Text (Text )
27
35
import Data.Text.Lazy.Builder (Builder )
28
36
import System.Nix.Base (BaseEncoding (.. ))
@@ -67,6 +75,32 @@ instance Arbitrary (Digest SHA256) where
67
75
instance Arbitrary (Digest SHA512 ) where
68
76
arbitrary = Crypto.Hash. hash @ ByteString <$> arbitrary
69
77
78
+ data HashAlgo :: Type -> Type where
79
+ HashAlgo_MD5 :: HashAlgo MD5
80
+ HashAlgo_SHA1 :: HashAlgo SHA1
81
+ HashAlgo_SHA256 :: HashAlgo SHA256
82
+ HashAlgo_SHA512 :: HashAlgo SHA512
83
+
84
+ deriveArgDict ''HashAlgo
85
+
86
+ algoToText :: forall t . HashAlgo t -> Text
87
+ algoToText x = has @ NamedAlgo x (algoName @ t )
88
+
89
+ _hashAlgoValue :: HashAlgo a -> a
90
+ _hashAlgoValue = \ case
91
+ HashAlgo_MD5 -> MD5
92
+ HashAlgo_SHA1 -> SHA1
93
+ HashAlgo_SHA256 -> SHA256
94
+ HashAlgo_SHA512 -> SHA512
95
+
96
+ textToAlgo :: Text -> Either String (Some HashAlgo )
97
+ textToAlgo = \ case
98
+ " md5" -> Right $ Some HashAlgo_MD5
99
+ " sha1" -> Right $ Some HashAlgo_SHA1
100
+ " sha256" -> Right $ Some HashAlgo_SHA256
101
+ " sha512" -> Right $ Some HashAlgo_SHA512
102
+ name -> Left $ " Unknown hash name: " <> Data.Text. unpack name
103
+
70
104
-- | A digest whose 'NamedAlgo' is not known at compile time.
71
105
data SomeNamedDigest = forall a . NamedAlgo a => SomeDigest (Digest a )
72
106
0 commit comments