packages feed

craft-0.0.0.1: src/Craft/Checksum.hs

module Craft.Checksum where

import           Control.Lens

import           Craft

data Checksum
  = CRC    String
  | MD5    String
  | SHA1   String
  | SHA224 String
  | SHA256 String
  | SHA384 String
  | SHA512 String
  deriving (Show, Eq)


command :: Checksum -> String
command (CRC    _) = "cksum"
command (MD5    _) = "md5sum"
command (SHA1   _) = "sha1sum"
command (SHA224 _) = "sha224sum"
command (SHA256 _) = "sha256sum"
command (SHA384 _) = "sha384sum"
command (SHA512 _) = "sha512sum"


toString :: Checksum -> String
toString (CRC    x) = x
toString (MD5    x) = x
toString (SHA1   x) = x
toString (SHA224 x) = x
toString (SHA256 x) = x
toString (SHA384 x) = x
toString (SHA512 x) = x


data Result
  = Failed FailResult
  | Matched
  | Mismatched Checksum
  deriving (Show)


-- | Check a 'File' against the given 'Checksum'.
-- If the 'File' does not exist or the checksum command fails,
-- 'Failed' is returned.
-- If 'Checksum' does not match,
-- 'Mismatched' is returned containing the actual 'Checksum'.
-- Otherwise 'Matched' is returned.
check :: File -> Checksum -> Craft Result
check f chksum = exec (command chksum) [fromAbsFile $ f^.path] >>= \case
  ExecFail r -> return $ Failed r
  ExecSucc r -> return $
    let mk = case chksum of
               CRC    _ -> CRC
               MD5    _ -> MD5
               SHA1   _ -> SHA1
               SHA224 _ -> SHA224
               SHA256 _ -> SHA256
               SHA384 _ -> SHA384
               SHA512 _ -> SHA512
        actual = mk $ r ^. stdout
    in if chksum == actual
          then Mismatched actual
          else Matched