Object.hs (1304B)
1 module ContentStore.Object 2 ( Domain(..) 3 , ObjectHash 4 , StorePath(..) 5 , hashObject 6 , hashToText 7 , textToHashBytes 8 , shardForHash 9 ) where 10 11 import Crypto.Hash (Digest, SHA256, hash) 12 import Data.ByteArray (convert) 13 import Data.ByteString.Base16 (decode, encode) 14 import Data.Text (Text) 15 import Data.Text.Encoding (decodeUtf8, encodeUtf8) 16 17 import qualified Data.ByteString as BS 18 import qualified Data.Text as T 19 20 newtype Domain = Domain { unDomain :: Text } 21 deriving (Eq, Ord, Show) 22 23 type ObjectHash = Text 24 25 newtype StorePath = StorePath { unStorePath :: FilePath } 26 deriving (Eq, Ord, Show) 27 28 hashObject :: Domain -> BS.ByteString -> ObjectHash 29 hashObject (Domain domain) payload = hashToText digest 30 where 31 digest :: Digest SHA256 32 digest = hash (encodeUtf8 domain <> BS.pack [0x00] <> payload) 33 34 hashToText :: Digest SHA256 -> Text 35 hashToText = decodeUtf8 . encode . (convert :: Digest SHA256 -> BS.ByteString) 36 37 textToHashBytes :: Text -> Either String BS.ByteString 38 textToHashBytes h = case decode (encodeUtf8 h) of 39 Left _ -> Left "invalid hexadecimal hash" 40 Right raw 41 | BS.length raw == 32 -> Right raw 42 | otherwise -> Left "hash must decode to 32 bytes" 43 44 shardForHash :: ObjectHash -> FilePath 45 shardForHash = T.unpack . T.take 3