module Darcs.Patch.Prim.Class ( PrimConstruct(..), PrimCanonize(..) , PrimClassify(..), PrimDetails(..) , PrimShow(..), PrimRead(..) , PrimApply(..) , PrimPatch, PrimPatchBase(..) , FromPrim(..), FromPrims(..), ToFromPrim(..) , PrimPatchCommon ) where import Prelude () import Darcs.Prelude import Darcs.Patch.ApplyMonad ( ApplyMonad ) import Darcs.Patch.Apply( ApplyState ) import Darcs.Patch.FileHunk ( FileHunk, IsHunk ) import Darcs.Util.Path ( FileName ) import Darcs.Patch.Format ( FileNameFormat, PatchListFormat ) import Darcs.Patch.Inspect ( PatchInspect ) import Darcs.Patch.Apply ( Apply(..) ) import Darcs.Patch.Commute ( Commute(..) ) import Darcs.Patch.Invert ( Invert(..) ) import Darcs.Patch.Read ( ReadPatch ) import Darcs.Patch.ReadMonads ( ParserM ) import Darcs.Patch.Repair ( RepairToFL ) import Darcs.Patch.Show ( ShowPatch, ShowContextPatch ) import Darcs.Patch.SummaryData ( SummDetail ) import Darcs.Patch.Witnesses.Eq ( Eq2(..) ) import Darcs.Patch.Witnesses.Ordered ( FL(..), RL, (:>), mapFL_FL, reverseFL ) import Darcs.Patch.Witnesses.Show ( Show2 ) import Darcs.Patch.Witnesses.Sealed ( Sealed ) import Darcs.Util.Printer ( Doc ) import qualified Darcs.Util.Diff as D ( DiffAlgorithm ) import qualified Data.ByteString as B ( ByteString ) -- | This class describes the abstract interface to primitive patches -- that is indepenent of the on-disk format. class ( Apply prim , Commute prim , Invert prim , Eq2 prim , IsHunk prim , PatchInspect prim , RepairToFL prim , Show2 prim , PrimConstruct prim , PrimCanonize prim , PrimClassify prim , PrimDetails prim , PrimApply prim ) => PrimPatchCommon prim class ( PrimPatchCommon prim , ReadPatch prim , ShowPatch prim , ShowContextPatch prim , PatchListFormat prim ) => PrimPatch prim class PrimPatch (PrimOf p) => PrimPatchBase p where type PrimOf (p :: (* -> * -> *)) :: (* -> * -> *) instance PrimPatchBase p => PrimPatchBase (FL p) where type PrimOf (FL p) = PrimOf p instance PrimPatchBase p => PrimPatchBase (RL p) where type PrimOf (RL p) = PrimOf p class FromPrim p where fromPrim :: PrimOf p wX wY -> p wX wY class FromPrim p => ToFromPrim p where toPrim :: p wX wY -> Maybe (PrimOf p wX wY) class FromPrims p where fromPrims :: FL (PrimOf p) wX wY -> p wX wY instance FromPrim p => FromPrim (FL p) where fromPrim p = fromPrim p :>: NilFL instance FromPrim p => FromPrims (FL p) where fromPrims = mapFL_FL fromPrim instance FromPrim p => FromPrims (RL p) where fromPrims = reverseFL . mapFL_FL fromPrim class PrimClassify prim where primIsAddfile :: prim wX wY -> Bool primIsRmfile :: prim wX wY -> Bool primIsAdddir :: prim wX wY -> Bool primIsRmdir :: prim wX wY -> Bool primIsMove :: prim wX wY -> Bool primIsHunk :: prim wX wY -> Bool primIsTokReplace :: prim wX wY -> Bool primIsBinary :: prim wX wY -> Bool primIsSetpref :: prim wX wY -> Bool is_filepatch :: prim wX wY -> Maybe FileName class PrimConstruct prim where addfile :: FilePath -> prim wX wY rmfile :: FilePath -> prim wX wY adddir :: FilePath -> prim wX wY rmdir :: FilePath -> prim wX wY move :: FilePath -> FilePath -> prim wX wY changepref :: String -> String -> String -> prim wX wY hunk :: FilePath -> Int -> [B.ByteString] -> [B.ByteString] -> prim wX wY tokreplace :: FilePath -> String -> String -> String -> prim wX wY binary :: FilePath -> B.ByteString -> B.ByteString -> prim wX wY primFromHunk :: FileHunk wX wY -> prim wX wY anIdentity :: prim wX wX class PrimCanonize prim where -- | @tryToShrink ps@ simplifies @ps@ by getting rid of self-cancellations -- or coalescing patches -- -- Question (Eric Kow): what properties should this have? For example, -- the prim1 implementation only gets rid of the first self-cancellation -- it finds (as far as I can tell). Is that OK? Can we try harder? tryToShrink :: FL prim wX wY -> FL prim wX wY -- | @tryShrinkingInverse ps@ deletes the first subsequence of -- primitive patches that is followed by the inverse subsequence, -- if one exists. If not, it returns @Nothing@ tryShrinkingInverse :: FL prim wX wY -> Maybe (FL prim wX wY) -- | 'sortCoalesceFL' @ps@ coalesces as many patches in @ps@ as -- possible, sorting the results in some standard order. sortCoalesceFL :: FL prim wX wY -> FL prim wX wY -- | It can sometimes be handy to have a canonical representation of a given -- patch. We achieve this by defining a canonical form for each patch type, -- and a function 'canonize' which takes a patch and puts it into -- canonical form. This routine is used by the diff function to create an -- optimal patch (based on an LCS algorithm) from a simple hunk describing the -- old and new version of a file. canonize :: D.DiffAlgorithm -> prim wX wY -> FL prim wX wY -- | 'canonizeFL' @ps@ puts a sequence of primitive patches into -- canonical form. Even if the patches are just hunk patches, -- this is not necessarily the same set of results as you would get -- if you applied the sequence to a specific tree and recalculated -- a diff. -- -- Note that this process does not preserve the commutation behaviour -- of the patches and is therefore not appropriate for use when -- working with already recorded patches (unless doing amend-record -- or the like). canonizeFL :: D.DiffAlgorithm -> FL prim wX wY -> FL prim wX wY coalesce :: (prim :> prim) wX wY -> Maybe (FL prim wX wY) class PrimDetails prim where summarizePrim :: prim wX wY -> [SummDetail] class PrimShow prim where showPrim :: FileNameFormat -> prim wA wB -> Doc showPrimCtx :: ApplyMonad (ApplyState prim) m => FileNameFormat -> prim wA wB -> m Doc class PrimRead prim where readPrim :: ParserM m => FileNameFormat -> m (Sealed (prim wX)) class PrimApply prim where applyPrimFL :: ApplyMonad (ApplyState prim) m => FL prim wX wY -> m ()