module Darcs.Patch.Prim.V1.Core
( Prim(..),
DirPatchType(..), FilePatchType(..),
isIdentity,
comparePrim,
)
where
import Prelude ()
import Darcs.Prelude
import qualified Data.ByteString as B (ByteString)
import Darcs.Util.Path ( FileName, fn2fp, fp2fn, normPath )
import Darcs.Patch.Witnesses.Eq ( Eq2(..), EqCheck(..) )
import Darcs.Patch.Witnesses.Unsafe ( unsafeCoerceP )
import Darcs.Patch.Debug ( PatchDebug(..) )
import Darcs.Patch.FileHunk ( FileHunk(..), IsHunk(..) )
import Darcs.Patch.Invert ( Invert(..) )
import Darcs.Patch.Inspect ( PatchInspect(..) )
import Darcs.Patch.Permutations ()
import Darcs.Patch.Prim.Class ( PrimConstruct(..), PrimClassify(..) )
data Prim wX wY where
Move :: !FileName -> !FileName -> Prim wX wY
DP :: !FileName -> !(DirPatchType wX wY) -> Prim wX wY
FP :: !FileName -> !(FilePatchType wX wY) -> Prim wX wY
ChangePref :: !String -> !String -> !String -> Prim wX wY
data FilePatchType wX wY
= RmFile
| AddFile
| Hunk !Int [B.ByteString] [B.ByteString]
| TokReplace !String !String !String
| Binary B.ByteString B.ByteString
deriving (Eq,Ord)
data DirPatchType wX wY = RmDir | AddDir
deriving (Eq,Ord)
instance Eq2 FilePatchType where
unsafeCompare a b = a == unsafeCoerceP b
instance Eq2 DirPatchType where
unsafeCompare a b = a == unsafeCoerceP b
isIdentity :: Prim wX wY -> EqCheck wX wY
isIdentity (FP _ (Binary old new)) | old == new = unsafeCoerceP IsEq
isIdentity (FP _ (Hunk _ old new)) | old == new = unsafeCoerceP IsEq
isIdentity (FP _ (TokReplace _ old new)) | old == new = unsafeCoerceP IsEq
isIdentity (Move old new) | old == new = unsafeCoerceP IsEq
isIdentity _ = NotEq
instance PrimClassify Prim where
primIsAddfile (FP _ AddFile) = True
primIsAddfile _ = False
primIsRmfile (FP _ RmFile) = True
primIsRmfile _ = False
primIsAdddir (DP _ AddDir) = True
primIsAdddir _ = False
primIsRmdir (DP _ RmDir) = True
primIsRmdir _ = False
primIsMove (Move _ _) = True
primIsMove _ = False
primIsHunk (FP _ (Hunk _ _ _)) = True
primIsHunk _ = False
primIsTokReplace (FP _ (TokReplace _ _ _)) = True
primIsTokReplace _ = False
primIsBinary (FP _ (Binary _ _)) = True
primIsBinary _ = False
primIsSetpref (ChangePref _ _ _) = True
primIsSetpref _ = False
is_filepatch (FP f _) = Just f
is_filepatch _ = Nothing
evalargs :: (a -> b -> c) -> a -> b -> c
evalargs f x y = (f $! x) $! y
instance PrimConstruct Prim where
addfile f = FP (fp2fn $ nFn f) AddFile
rmfile f = FP (fp2fn $ nFn f) RmFile
adddir d = DP (fp2fn $ nFn d) AddDir
rmdir d = DP (fp2fn $ nFn d) RmDir
move f f' = Move (fp2fn $ nFn f) (fp2fn $ nFn f')
changepref p f t = ChangePref p f t
hunk f line old new = evalargs FP (fp2fn $ nFn f) (Hunk line old new)
tokreplace f tokchars old new =
evalargs FP (fp2fn $ nFn f) (TokReplace tokchars old new)
binary f old new = FP (fp2fn $! nFn f) $ Binary old new
primFromHunk (FileHunk fn line before after) = FP fn (Hunk line before after)
anIdentity = let fp = "./dummy" in move fp fp
nFn :: FilePath -> FilePath
nFn f = "./"++(fn2fp $ normPath $ fp2fn f)
instance IsHunk Prim where
isHunk (FP fn (Hunk line before after)) = Just (FileHunk fn line before after)
isHunk _ = Nothing
instance Invert Prim where
invert (FP f RmFile) = FP f AddFile
invert (FP f AddFile) = FP f RmFile
invert (FP f (Hunk line old new)) = FP f $ Hunk line new old
invert (FP f (TokReplace t o n)) = FP f $ TokReplace t n o
invert (FP f (Binary o n)) = FP f $ Binary n o
invert (DP d RmDir) = DP d AddDir
invert (DP d AddDir) = DP d RmDir
invert (Move f f') = Move f' f
invert (ChangePref p f t) = ChangePref p t f
instance PatchInspect Prim where
listTouchedFiles (Move f1 f2) = map fn2fp [f1, f2]
listTouchedFiles (FP f _) = [fn2fp f]
listTouchedFiles (DP d _) = [fn2fp d]
listTouchedFiles (ChangePref _ _ _) = []
hunkMatches f (FP _ (Hunk _ remove add)) = anyMatches remove || anyMatches add
where anyMatches = foldr ((||) . f) False
hunkMatches _ (FP _ _) = False
hunkMatches _ (DP _ _) = False
hunkMatches _ (ChangePref _ _ _) = False
hunkMatches _ (Move _ _) = False
instance PatchDebug Prim
instance Eq2 Prim where
unsafeCompare (Move a b) (Move c d) = a == c && b == d
unsafeCompare (DP d1 p1) (DP d2 p2)
= d1 == d2 && p1 `unsafeCompare` p2
unsafeCompare (FP f1 fp1) (FP f2 fp2)
= f1 == f2 && fp1 `unsafeCompare` fp2
unsafeCompare (ChangePref a1 b1 c1) (ChangePref a2 b2 c2)
= c1 == c2 && b1 == b2 && a1 == a2
unsafeCompare _ _ = False
instance Eq (Prim wX wY) where
(==) = unsafeCompare
comparePrim :: Prim wX wY -> Prim wW wZ -> Ordering
comparePrim (Move a b) (Move c d) = compare (a, b) (c, d)
comparePrim (Move _ _) _ = LT
comparePrim _ (Move _ _) = GT
comparePrim (DP d1 p1) (DP d2 p2) = compare (d1, p1) $ unsafeCoerceP (d2, p2)
comparePrim (DP _ _) _ = LT
comparePrim _ (DP _ _) = GT
comparePrim (FP f1 fp1) (FP f2 fp2) = compare (f1, fp1) $ unsafeCoerceP (f2, fp2)
comparePrim (FP _ _) _ = LT
comparePrim _ (FP _ _) = GT
comparePrim (ChangePref a1 b1 c1) (ChangePref a2 b2 c2)
= compare (c1, b1, a1) (c2, b2, a2)