--  Copyright (C) 2002-2003,2007 David Roundy
--
--  This program is free software; you can redistribute it and/or modify
--  it under the terms of the GNU General Public License as published by
--  the Free Software Foundation; either version 2, or (at your option)
--  any later version.
--
--  This program is distributed in the hope that it will be useful,
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--  GNU General Public License for more details.
--
--  You should have received a copy of the GNU General Public License
--  along with this program; see the file COPYING.  If not, write to
--  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
--  Boston, MA 02110-1301, USA.

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 () -- for Invert instance of FL
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 (FilePatchType wX wY -> FilePatchType wX wY -> Bool
(FilePatchType wX wY -> FilePatchType wX wY -> Bool)
-> (FilePatchType wX wY -> FilePatchType wX wY -> Bool)
-> Eq (FilePatchType wX wY)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall wX wY. FilePatchType wX wY -> FilePatchType wX wY -> Bool
/= :: FilePatchType wX wY -> FilePatchType wX wY -> Bool
$c/= :: forall wX wY. FilePatchType wX wY -> FilePatchType wX wY -> Bool
== :: FilePatchType wX wY -> FilePatchType wX wY -> Bool
$c== :: forall wX wY. FilePatchType wX wY -> FilePatchType wX wY -> Bool
Eq,Eq (FilePatchType wX wY)
Eq (FilePatchType wX wY) =>
(FilePatchType wX wY -> FilePatchType wX wY -> Ordering)
-> (FilePatchType wX wY -> FilePatchType wX wY -> Bool)
-> (FilePatchType wX wY -> FilePatchType wX wY -> Bool)
-> (FilePatchType wX wY -> FilePatchType wX wY -> Bool)
-> (FilePatchType wX wY -> FilePatchType wX wY -> Bool)
-> (FilePatchType wX wY
    -> FilePatchType wX wY -> FilePatchType wX wY)
-> (FilePatchType wX wY
    -> FilePatchType wX wY -> FilePatchType wX wY)
-> Ord (FilePatchType wX wY)
FilePatchType wX wY -> FilePatchType wX wY -> Bool
FilePatchType wX wY -> FilePatchType wX wY -> Ordering
FilePatchType wX wY -> FilePatchType wX wY -> FilePatchType wX wY
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall wX wY. Eq (FilePatchType wX wY)
forall wX wY. FilePatchType wX wY -> FilePatchType wX wY -> Bool
forall wX wY.
FilePatchType wX wY -> FilePatchType wX wY -> Ordering
forall wX wY.
FilePatchType wX wY -> FilePatchType wX wY -> FilePatchType wX wY
min :: FilePatchType wX wY -> FilePatchType wX wY -> FilePatchType wX wY
$cmin :: forall wX wY.
FilePatchType wX wY -> FilePatchType wX wY -> FilePatchType wX wY
max :: FilePatchType wX wY -> FilePatchType wX wY -> FilePatchType wX wY
$cmax :: forall wX wY.
FilePatchType wX wY -> FilePatchType wX wY -> FilePatchType wX wY
>= :: FilePatchType wX wY -> FilePatchType wX wY -> Bool
$c>= :: forall wX wY. FilePatchType wX wY -> FilePatchType wX wY -> Bool
> :: FilePatchType wX wY -> FilePatchType wX wY -> Bool
$c> :: forall wX wY. FilePatchType wX wY -> FilePatchType wX wY -> Bool
<= :: FilePatchType wX wY -> FilePatchType wX wY -> Bool
$c<= :: forall wX wY. FilePatchType wX wY -> FilePatchType wX wY -> Bool
< :: FilePatchType wX wY -> FilePatchType wX wY -> Bool
$c< :: forall wX wY. FilePatchType wX wY -> FilePatchType wX wY -> Bool
compare :: FilePatchType wX wY -> FilePatchType wX wY -> Ordering
$ccompare :: forall wX wY.
FilePatchType wX wY -> FilePatchType wX wY -> Ordering
$cp1Ord :: forall wX wY. Eq (FilePatchType wX wY)
Ord)

data DirPatchType wX wY = RmDir | AddDir
                           deriving (DirPatchType wX wY -> DirPatchType wX wY -> Bool
(DirPatchType wX wY -> DirPatchType wX wY -> Bool)
-> (DirPatchType wX wY -> DirPatchType wX wY -> Bool)
-> Eq (DirPatchType wX wY)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall wX wY. DirPatchType wX wY -> DirPatchType wX wY -> Bool
/= :: DirPatchType wX wY -> DirPatchType wX wY -> Bool
$c/= :: forall wX wY. DirPatchType wX wY -> DirPatchType wX wY -> Bool
== :: DirPatchType wX wY -> DirPatchType wX wY -> Bool
$c== :: forall wX wY. DirPatchType wX wY -> DirPatchType wX wY -> Bool
Eq,Eq (DirPatchType wX wY)
Eq (DirPatchType wX wY) =>
(DirPatchType wX wY -> DirPatchType wX wY -> Ordering)
-> (DirPatchType wX wY -> DirPatchType wX wY -> Bool)
-> (DirPatchType wX wY -> DirPatchType wX wY -> Bool)
-> (DirPatchType wX wY -> DirPatchType wX wY -> Bool)
-> (DirPatchType wX wY -> DirPatchType wX wY -> Bool)
-> (DirPatchType wX wY -> DirPatchType wX wY -> DirPatchType wX wY)
-> (DirPatchType wX wY -> DirPatchType wX wY -> DirPatchType wX wY)
-> Ord (DirPatchType wX wY)
DirPatchType wX wY -> DirPatchType wX wY -> Bool
DirPatchType wX wY -> DirPatchType wX wY -> Ordering
DirPatchType wX wY -> DirPatchType wX wY -> DirPatchType wX wY
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall wX wY. Eq (DirPatchType wX wY)
forall wX wY. DirPatchType wX wY -> DirPatchType wX wY -> Bool
forall wX wY. DirPatchType wX wY -> DirPatchType wX wY -> Ordering
forall wX wY.
DirPatchType wX wY -> DirPatchType wX wY -> DirPatchType wX wY
min :: DirPatchType wX wY -> DirPatchType wX wY -> DirPatchType wX wY
$cmin :: forall wX wY.
DirPatchType wX wY -> DirPatchType wX wY -> DirPatchType wX wY
max :: DirPatchType wX wY -> DirPatchType wX wY -> DirPatchType wX wY
$cmax :: forall wX wY.
DirPatchType wX wY -> DirPatchType wX wY -> DirPatchType wX wY
>= :: DirPatchType wX wY -> DirPatchType wX wY -> Bool
$c>= :: forall wX wY. DirPatchType wX wY -> DirPatchType wX wY -> Bool
> :: DirPatchType wX wY -> DirPatchType wX wY -> Bool
$c> :: forall wX wY. DirPatchType wX wY -> DirPatchType wX wY -> Bool
<= :: DirPatchType wX wY -> DirPatchType wX wY -> Bool
$c<= :: forall wX wY. DirPatchType wX wY -> DirPatchType wX wY -> Bool
< :: DirPatchType wX wY -> DirPatchType wX wY -> Bool
$c< :: forall wX wY. DirPatchType wX wY -> DirPatchType wX wY -> Bool
compare :: DirPatchType wX wY -> DirPatchType wX wY -> Ordering
$ccompare :: forall wX wY. DirPatchType wX wY -> DirPatchType wX wY -> Ordering
$cp1Ord :: forall wX wY. Eq (DirPatchType wX wY)
Ord)

instance Eq2 FilePatchType where
    unsafeCompare :: FilePatchType wA wB -> FilePatchType wC wD -> Bool
unsafeCompare a :: FilePatchType wA wB
a b :: FilePatchType wC wD
b = FilePatchType wA wB
a FilePatchType wA wB -> FilePatchType wA wB -> Bool
forall a. Eq a => a -> a -> Bool
== FilePatchType wC wD -> FilePatchType wA wB
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP FilePatchType wC wD
b

instance Eq2 DirPatchType where
    unsafeCompare :: DirPatchType wA wB -> DirPatchType wC wD -> Bool
unsafeCompare a :: DirPatchType wA wB
a b :: DirPatchType wC wD
b = DirPatchType wA wB
a DirPatchType wA wB -> DirPatchType wA wB -> Bool
forall a. Eq a => a -> a -> Bool
== DirPatchType wC wD -> DirPatchType wA wB
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP DirPatchType wC wD
b

isIdentity :: Prim wX wY -> EqCheck wX wY
isIdentity :: Prim wX wY -> EqCheck wX wY
isIdentity (FP _ (Binary old :: ByteString
old new :: ByteString
new)) | ByteString
old ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
new = EqCheck Any Any -> EqCheck wX wY
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP EqCheck Any Any
forall wA. EqCheck wA wA
IsEq
isIdentity (FP _ (Hunk _ old :: [ByteString]
old new :: [ByteString]
new)) | [ByteString]
old [ByteString] -> [ByteString] -> Bool
forall a. Eq a => a -> a -> Bool
== [ByteString]
new = EqCheck Any Any -> EqCheck wX wY
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP EqCheck Any Any
forall wA. EqCheck wA wA
IsEq
isIdentity (FP _ (TokReplace _ old :: String
old new :: String
new)) | String
old String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
new = EqCheck Any Any -> EqCheck wX wY
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP EqCheck Any Any
forall wA. EqCheck wA wA
IsEq
isIdentity (Move old :: FileName
old new :: FileName
new) | FileName
old FileName -> FileName -> Bool
forall a. Eq a => a -> a -> Bool
== FileName
new = EqCheck Any Any -> EqCheck wX wY
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP EqCheck Any Any
forall wA. EqCheck wA wA
IsEq
isIdentity _ = EqCheck wX wY
forall wA wB. EqCheck wA wB
NotEq

instance PrimClassify Prim where
   primIsAddfile :: Prim wX wY -> Bool
primIsAddfile (FP _ AddFile) = Bool
True
   primIsAddfile _ = Bool
False

   primIsRmfile :: Prim wX wY -> Bool
primIsRmfile (FP _ RmFile) = Bool
True
   primIsRmfile _ = Bool
False

   primIsAdddir :: Prim wX wY -> Bool
primIsAdddir (DP _ AddDir) = Bool
True
   primIsAdddir _ = Bool
False

   primIsRmdir :: Prim wX wY -> Bool
primIsRmdir (DP _ RmDir) = Bool
True
   primIsRmdir _ = Bool
False

   primIsMove :: Prim wX wY -> Bool
primIsMove (Move _ _) = Bool
True
   primIsMove _ = Bool
False

   primIsHunk :: Prim wX wY -> Bool
primIsHunk (FP _ (Hunk _ _ _)) = Bool
True
   primIsHunk _ = Bool
False

   primIsTokReplace :: Prim wX wY -> Bool
primIsTokReplace (FP _ (TokReplace _ _ _)) = Bool
True
   primIsTokReplace _ = Bool
False

   primIsBinary :: Prim wX wY -> Bool
primIsBinary (FP _ (Binary _ _)) = Bool
True
   primIsBinary _ = Bool
False

   primIsSetpref :: Prim wX wY -> Bool
primIsSetpref (ChangePref _ _ _) = Bool
True
   primIsSetpref _ = Bool
False

   is_filepatch :: Prim wX wY -> Maybe FileName
is_filepatch (FP f :: FileName
f _) = FileName -> Maybe FileName
forall a. a -> Maybe a
Just FileName
f
   is_filepatch _ = Maybe FileName
forall a. Maybe a
Nothing

evalargs :: (a -> b -> c) -> a -> b -> c
evalargs :: (a -> b -> c) -> a -> b -> c
evalargs f :: a -> b -> c
f x :: a
x y :: b
y = (a -> b -> c
f (a -> b -> c) -> a -> b -> c
forall a b. (a -> b) -> a -> b
$! a
x) (b -> c) -> b -> c
forall a b. (a -> b) -> a -> b
$! b
y

instance PrimConstruct Prim where
   addfile :: String -> Prim wX wY
addfile f :: String
f = FileName -> FilePatchType wX wY -> Prim wX wY
forall wX wY. FileName -> FilePatchType wX wY -> Prim wX wY
FP (String -> FileName
fp2fn (String -> FileName) -> String -> FileName
forall a b. (a -> b) -> a -> b
$ String -> String
nFn String
f) FilePatchType wX wY
forall wX wY. FilePatchType wX wY
AddFile
   rmfile :: String -> Prim wX wY
rmfile f :: String
f = FileName -> FilePatchType wX wY -> Prim wX wY
forall wX wY. FileName -> FilePatchType wX wY -> Prim wX wY
FP (String -> FileName
fp2fn (String -> FileName) -> String -> FileName
forall a b. (a -> b) -> a -> b
$ String -> String
nFn String
f) FilePatchType wX wY
forall wX wY. FilePatchType wX wY
RmFile
   adddir :: String -> Prim wX wY
adddir d :: String
d = FileName -> DirPatchType wX wY -> Prim wX wY
forall wX wY. FileName -> DirPatchType wX wY -> Prim wX wY
DP (String -> FileName
fp2fn (String -> FileName) -> String -> FileName
forall a b. (a -> b) -> a -> b
$ String -> String
nFn String
d) DirPatchType wX wY
forall wX wY. DirPatchType wX wY
AddDir
   rmdir :: String -> Prim wX wY
rmdir d :: String
d = FileName -> DirPatchType wX wY -> Prim wX wY
forall wX wY. FileName -> DirPatchType wX wY -> Prim wX wY
DP (String -> FileName
fp2fn (String -> FileName) -> String -> FileName
forall a b. (a -> b) -> a -> b
$ String -> String
nFn String
d) DirPatchType wX wY
forall wX wY. DirPatchType wX wY
RmDir
   move :: String -> String -> Prim wX wY
move f :: String
f f' :: String
f' = FileName -> FileName -> Prim wX wY
forall wX wY. FileName -> FileName -> Prim wX wY
Move (String -> FileName
fp2fn (String -> FileName) -> String -> FileName
forall a b. (a -> b) -> a -> b
$ String -> String
nFn String
f) (String -> FileName
fp2fn (String -> FileName) -> String -> FileName
forall a b. (a -> b) -> a -> b
$ String -> String
nFn String
f')
   changepref :: String -> String -> String -> Prim wX wY
changepref p :: String
p f :: String
f t :: String
t = String -> String -> String -> Prim wX wY
forall wX wY. String -> String -> String -> Prim wX wY
ChangePref String
p String
f String
t
   hunk :: String -> Int -> [ByteString] -> [ByteString] -> Prim wX wY
hunk f :: String
f line :: Int
line old :: [ByteString]
old new :: [ByteString]
new = (FileName -> FilePatchType wX wY -> Prim wX wY)
-> FileName -> FilePatchType wX wY -> Prim wX wY
forall a b c. (a -> b -> c) -> a -> b -> c
evalargs FileName -> FilePatchType wX wY -> Prim wX wY
forall wX wY. FileName -> FilePatchType wX wY -> Prim wX wY
FP (String -> FileName
fp2fn (String -> FileName) -> String -> FileName
forall a b. (a -> b) -> a -> b
$ String -> String
nFn String
f) (Int -> [ByteString] -> [ByteString] -> FilePatchType wX wY
forall wX wY.
Int -> [ByteString] -> [ByteString] -> FilePatchType wX wY
Hunk Int
line [ByteString]
old [ByteString]
new)
   tokreplace :: String -> String -> String -> String -> Prim wX wY
tokreplace f :: String
f tokchars :: String
tokchars old :: String
old new :: String
new =
       (FileName -> FilePatchType wX wY -> Prim wX wY)
-> FileName -> FilePatchType wX wY -> Prim wX wY
forall a b c. (a -> b -> c) -> a -> b -> c
evalargs FileName -> FilePatchType wX wY -> Prim wX wY
forall wX wY. FileName -> FilePatchType wX wY -> Prim wX wY
FP (String -> FileName
fp2fn (String -> FileName) -> String -> FileName
forall a b. (a -> b) -> a -> b
$ String -> String
nFn String
f) (String -> String -> String -> FilePatchType wX wY
forall wX wY. String -> String -> String -> FilePatchType wX wY
TokReplace String
tokchars String
old String
new)
   binary :: String -> ByteString -> ByteString -> Prim wX wY
binary f :: String
f old :: ByteString
old new :: ByteString
new = FileName -> FilePatchType wX wY -> Prim wX wY
forall wX wY. FileName -> FilePatchType wX wY -> Prim wX wY
FP (String -> FileName
fp2fn (String -> FileName) -> String -> FileName
forall a b. (a -> b) -> a -> b
$! String -> String
nFn String
f) (FilePatchType wX wY -> Prim wX wY)
-> FilePatchType wX wY -> Prim wX wY
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString -> FilePatchType wX wY
forall wX wY. ByteString -> ByteString -> FilePatchType wX wY
Binary ByteString
old ByteString
new
   primFromHunk :: FileHunk wX wY -> Prim wX wY
primFromHunk (FileHunk fn :: FileName
fn line :: Int
line before :: [ByteString]
before after :: [ByteString]
after) = FileName -> FilePatchType wX wY -> Prim wX wY
forall wX wY. FileName -> FilePatchType wX wY -> Prim wX wY
FP FileName
fn (Int -> [ByteString] -> [ByteString] -> FilePatchType wX wY
forall wX wY.
Int -> [ByteString] -> [ByteString] -> FilePatchType wX wY
Hunk Int
line [ByteString]
before [ByteString]
after)
   anIdentity :: Prim wX wX
anIdentity = let fp :: String
fp = "./dummy" in String -> String -> Prim wX wX
forall (prim :: * -> * -> *) wX wY.
PrimConstruct prim =>
String -> String -> prim wX wY
move String
fp String
fp

nFn :: FilePath -> FilePath
nFn :: String -> String
nFn f :: String
f = "./"String -> String -> String
forall a. [a] -> [a] -> [a]
++(FileName -> String
fn2fp (FileName -> String) -> FileName -> String
forall a b. (a -> b) -> a -> b
$ FileName -> FileName
normPath (FileName -> FileName) -> FileName -> FileName
forall a b. (a -> b) -> a -> b
$ String -> FileName
fp2fn String
f)

instance IsHunk Prim where
   isHunk :: Prim wX wY -> Maybe (FileHunk wX wY)
isHunk (FP fn :: FileName
fn (Hunk line :: Int
line before :: [ByteString]
before after :: [ByteString]
after)) = FileHunk wX wY -> Maybe (FileHunk wX wY)
forall a. a -> Maybe a
Just (FileName -> Int -> [ByteString] -> [ByteString] -> FileHunk wX wY
forall wX wY.
FileName -> Int -> [ByteString] -> [ByteString] -> FileHunk wX wY
FileHunk FileName
fn Int
line [ByteString]
before [ByteString]
after)
   isHunk _ = Maybe (FileHunk wX wY)
forall a. Maybe a
Nothing

instance Invert Prim where
    invert :: Prim wX wY -> Prim wY wX
invert (FP f :: FileName
f RmFile)  = FileName -> FilePatchType wY wX -> Prim wY wX
forall wX wY. FileName -> FilePatchType wX wY -> Prim wX wY
FP FileName
f FilePatchType wY wX
forall wX wY. FilePatchType wX wY
AddFile
    invert (FP f :: FileName
f AddFile)  = FileName -> FilePatchType wY wX -> Prim wY wX
forall wX wY. FileName -> FilePatchType wX wY -> Prim wX wY
FP FileName
f FilePatchType wY wX
forall wX wY. FilePatchType wX wY
RmFile
    invert (FP f :: FileName
f (Hunk line :: Int
line old :: [ByteString]
old new :: [ByteString]
new))  = FileName -> FilePatchType wY wX -> Prim wY wX
forall wX wY. FileName -> FilePatchType wX wY -> Prim wX wY
FP FileName
f (FilePatchType wY wX -> Prim wY wX)
-> FilePatchType wY wX -> Prim wY wX
forall a b. (a -> b) -> a -> b
$ Int -> [ByteString] -> [ByteString] -> FilePatchType wY wX
forall wX wY.
Int -> [ByteString] -> [ByteString] -> FilePatchType wX wY
Hunk Int
line [ByteString]
new [ByteString]
old
    invert (FP f :: FileName
f (TokReplace t :: String
t o :: String
o n :: String
n)) = FileName -> FilePatchType wY wX -> Prim wY wX
forall wX wY. FileName -> FilePatchType wX wY -> Prim wX wY
FP FileName
f (FilePatchType wY wX -> Prim wY wX)
-> FilePatchType wY wX -> Prim wY wX
forall a b. (a -> b) -> a -> b
$ String -> String -> String -> FilePatchType wY wX
forall wX wY. String -> String -> String -> FilePatchType wX wY
TokReplace String
t String
n String
o
    invert (FP f :: FileName
f (Binary o :: ByteString
o n :: ByteString
n)) = FileName -> FilePatchType wY wX -> Prim wY wX
forall wX wY. FileName -> FilePatchType wX wY -> Prim wX wY
FP FileName
f (FilePatchType wY wX -> Prim wY wX)
-> FilePatchType wY wX -> Prim wY wX
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString -> FilePatchType wY wX
forall wX wY. ByteString -> ByteString -> FilePatchType wX wY
Binary ByteString
n ByteString
o
    invert (DP d :: FileName
d RmDir) = FileName -> DirPatchType wY wX -> Prim wY wX
forall wX wY. FileName -> DirPatchType wX wY -> Prim wX wY
DP FileName
d DirPatchType wY wX
forall wX wY. DirPatchType wX wY
AddDir
    invert (DP d :: FileName
d AddDir) = FileName -> DirPatchType wY wX -> Prim wY wX
forall wX wY. FileName -> DirPatchType wX wY -> Prim wX wY
DP FileName
d DirPatchType wY wX
forall wX wY. DirPatchType wX wY
RmDir
    invert (Move f :: FileName
f f' :: FileName
f') = FileName -> FileName -> Prim wY wX
forall wX wY. FileName -> FileName -> Prim wX wY
Move FileName
f' FileName
f
    invert (ChangePref p :: String
p f :: String
f t :: String
t) = String -> String -> String -> Prim wY wX
forall wX wY. String -> String -> String -> Prim wX wY
ChangePref String
p String
t String
f

instance PatchInspect Prim where
    -- Recurse on everything, these are potentially spoofed patches
    listTouchedFiles :: Prim wX wY -> [String]
listTouchedFiles (Move f1 :: FileName
f1 f2 :: FileName
f2) = (FileName -> String) -> [FileName] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map FileName -> String
fn2fp [FileName
f1, FileName
f2]
    listTouchedFiles (FP f :: FileName
f _) = [FileName -> String
fn2fp FileName
f]
    listTouchedFiles (DP d :: FileName
d _) = [FileName -> String
fn2fp FileName
d]
    listTouchedFiles (ChangePref _ _ _) = []

    hunkMatches :: (ByteString -> Bool) -> Prim wX wY -> Bool
hunkMatches f :: ByteString -> Bool
f (FP _ (Hunk _ remove :: [ByteString]
remove add :: [ByteString]
add)) = [ByteString] -> Bool
anyMatches [ByteString]
remove Bool -> Bool -> Bool
|| [ByteString] -> Bool
anyMatches [ByteString]
add
        where anyMatches :: [ByteString] -> Bool
anyMatches = (ByteString -> Bool -> Bool) -> Bool -> [ByteString] -> Bool
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (Bool -> Bool -> Bool
(||) (Bool -> Bool -> Bool)
-> (ByteString -> Bool) -> ByteString -> Bool -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Bool
f) Bool
False
    hunkMatches _ (FP _ _) = Bool
False
    hunkMatches _ (DP _ _) = Bool
False
    hunkMatches _ (ChangePref _ _ _) = Bool
False
    hunkMatches _ (Move _ _) = Bool
False

instance PatchDebug Prim

instance Eq2 Prim where
    unsafeCompare :: Prim wA wB -> Prim wC wD -> Bool
unsafeCompare (Move a :: FileName
a b :: FileName
b) (Move c :: FileName
c d :: FileName
d) = FileName
a FileName -> FileName -> Bool
forall a. Eq a => a -> a -> Bool
== FileName
c Bool -> Bool -> Bool
&& FileName
b FileName -> FileName -> Bool
forall a. Eq a => a -> a -> Bool
== FileName
d
    unsafeCompare (DP d1 :: FileName
d1 p1 :: DirPatchType wA wB
p1) (DP d2 :: FileName
d2 p2 :: DirPatchType wC wD
p2)
        = FileName
d1 FileName -> FileName -> Bool
forall a. Eq a => a -> a -> Bool
== FileName
d2 Bool -> Bool -> Bool
&& DirPatchType wA wB
p1 DirPatchType wA wB -> DirPatchType wC wD -> Bool
forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
`unsafeCompare` DirPatchType wC wD
p2
    unsafeCompare (FP f1 :: FileName
f1 fp1 :: FilePatchType wA wB
fp1) (FP f2 :: FileName
f2 fp2 :: FilePatchType wC wD
fp2)
        = FileName
f1 FileName -> FileName -> Bool
forall a. Eq a => a -> a -> Bool
== FileName
f2 Bool -> Bool -> Bool
&& FilePatchType wA wB
fp1 FilePatchType wA wB -> FilePatchType wC wD -> Bool
forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
`unsafeCompare` FilePatchType wC wD
fp2
    unsafeCompare (ChangePref a1 :: String
a1 b1 :: String
b1 c1 :: String
c1) (ChangePref a2 :: String
a2 b2 :: String
b2 c2 :: String
c2)
        = String
c1 String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
c2 Bool -> Bool -> Bool
&& String
b1 String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
b2 Bool -> Bool -> Bool
&& String
a1 String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
a2
    unsafeCompare _ _ = Bool
False

instance Eq (Prim wX wY) where
    == :: Prim wX wY -> Prim wX wY -> Bool
(==) = Prim wX wY -> Prim wX wY -> Bool
forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
unsafeCompare

-- | 'comparePrim' @p1 p2@ is used to provide an arbitrary ordering between
--   @p1@ and @p2@.  Basically, identical patches are equal and
--   @Move < DP < FP < ChangePref@.
--   Everything else is compared in dictionary order of its arguments.
comparePrim :: Prim wX wY -> Prim wW wZ -> Ordering
comparePrim :: Prim wX wY -> Prim wW wZ -> Ordering
comparePrim (Move a :: FileName
a b :: FileName
b) (Move c :: FileName
c d :: FileName
d) = (FileName, FileName) -> (FileName, FileName) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (FileName
a, FileName
b) (FileName
c, FileName
d)
comparePrim (Move _ _) _ = Ordering
LT
comparePrim _ (Move _ _) = Ordering
GT
comparePrim (DP d1 :: FileName
d1 p1 :: DirPatchType wX wY
p1) (DP d2 :: FileName
d2 p2 :: DirPatchType wW wZ
p2) = (FileName, DirPatchType wX wY)
-> (FileName, DirPatchType wX wY) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (FileName
d1, DirPatchType wX wY
p1) ((FileName, DirPatchType wX wY) -> Ordering)
-> (FileName, DirPatchType wX wY) -> Ordering
forall a b. (a -> b) -> a -> b
$ (FileName, DirPatchType wW wZ) -> (FileName, DirPatchType wX wY)
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP (FileName
d2, DirPatchType wW wZ
p2)
comparePrim (DP _ _) _ = Ordering
LT
comparePrim _ (DP _ _) = Ordering
GT
comparePrim (FP f1 :: FileName
f1 fp1 :: FilePatchType wX wY
fp1) (FP f2 :: FileName
f2 fp2 :: FilePatchType wW wZ
fp2) = (FileName, FilePatchType wX wY)
-> (FileName, FilePatchType wX wY) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (FileName
f1, FilePatchType wX wY
fp1) ((FileName, FilePatchType wX wY) -> Ordering)
-> (FileName, FilePatchType wX wY) -> Ordering
forall a b. (a -> b) -> a -> b
$ (FileName, FilePatchType wW wZ) -> (FileName, FilePatchType wX wY)
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP (FileName
f2, FilePatchType wW wZ
fp2)
comparePrim (FP _ _) _ = Ordering
LT
comparePrim _ (FP _ _) = Ordering
GT
comparePrim (ChangePref a1 :: String
a1 b1 :: String
b1 c1 :: String
c1) (ChangePref a2 :: String
a2 b2 :: String
b2 c2 :: String
c2)
 = (String, String, String) -> (String, String, String) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (String
c1, String
b1, String
a1) (String
c2, String
b2, String
a2)