{-# OPTIONS_GHC -fno-cse #-}
module Darcs.Patch.Prim.Named
( NamedPrim
, PrimPatchId
, namedPrim
, positivePrimPatchIds
, anonymousNamedPrim
, unsafePrimPatchId
, prop_primPatchIdNonZero
) where
import Control.Monad ( mzero )
import qualified Data.ByteString.Char8 as BC
import qualified Data.ByteString.Lazy as BL
import qualified Data.Binary as Binary
import Crypto.Random ( getRandomBytes )
import System.IO.Unsafe ( unsafePerformIO )
import Darcs.Prelude hiding ( take )
import Darcs.Patch.Ident ( PatchId, SignedId(..), StorableId(..) )
import Darcs.Patch.Info ( PatchInfo, makePatchname )
import Darcs.Patch.Prim.WithName ( PrimWithName(..) )
import Darcs.Patch.Show ( ShowPatchFor(..) )
import Darcs.Test.TestOnly
import Darcs.Util.Hash ( SHA1, sha1Show, sha1Read )
import Darcs.Util.Parser
import Darcs.Util.Printer
data PrimPatchId = PrimPatchId !Int !SHA1
deriving (Eq, Ord, Show)
unsafePrimPatchId :: TestOnly => Int -> SHA1 -> PrimPatchId
unsafePrimPatchId = PrimPatchId
prop_primPatchIdNonZero :: PrimPatchId -> Bool
prop_primPatchIdNonZero (PrimPatchId i _) = i /= 0
instance SignedId PrimPatchId where
positiveId (PrimPatchId i _) = i > 0
invertId (PrimPatchId i h) = PrimPatchId (- i) h
positivePrimPatchIds :: PatchInfo -> [PrimPatchId]
positivePrimPatchIds info = map (flip PrimPatchId (makePatchname info)) [1..]
type NamedPrim = PrimWithName PrimPatchId
namedPrim :: PrimPatchId -> p wX wY -> NamedPrim p wX wY
namedPrim = PrimWithName
type instance PatchId (NamedPrim p) = PrimPatchId
instance StorableId PrimPatchId where
readId = do
lexString (BC.pack "hash")
i <- int
skipSpace
x <- take 40
liftMaybe $ PrimPatchId i <$> sha1Read x
where
liftMaybe = maybe mzero return
showId ForStorage (PrimPatchId i h) =
text "hash" <+> text (show i) <+> packedString (sha1Show h)
showId ForDisplay _ = mempty
{-# NOINLINE anonymousNamedPrim #-}
anonymousNamedPrim :: p wX wY -> NamedPrim p wX wY
anonymousNamedPrim p =
unsafePerformIO $ do
b20 <- getRandomBytes 20
b8 <- getRandomBytes 8
return $
PrimWithName
(PrimPatchId
(abs (Binary.decode $ BL.fromStrict b8))
(Binary.decode $ BL.fromStrict b20))
p