tricu

An interpreted language for exploring Tree Calculus
Log | Files | Refs | README | LICENSE

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