module Darcs.Patch.PatchInfoAnd ( Hopefully(..), SimpleHopefully(..), PatchInfoAnd(..),
WPatchInfo, unWPatchInfo, compareWPatchInfo,
piap, n2pia, patchInfoAndPatch,
fmapFLPIAP, generaliseRepoTypePIAP,
conscientiously, hopefully, info, winfo,
hopefullyM, createHashed, extractHash,
actually, unavailable, patchDesc ) where
import Prelude ()
import Darcs.Prelude
import System.IO.Unsafe ( unsafeInterleaveIO )
import Darcs.Util.SignalHandler ( catchNonSignal )
import Darcs.Util.Printer
( Doc, renderString, errorDoc, text, ($$), vcat
, RenderMode(..) )
import Darcs.Patch.Info ( PatchInfo, showPatchInfoUI, justName )
import Darcs.Patch.Conflict ( Conflict, CommuteNoConflicts )
import Darcs.Patch.Debug ( PatchDebug(..) )
import Darcs.Patch.Effect ( Effect(..) )
import Darcs.Patch.FileHunk ( IsHunk(..) )
import Darcs.Patch.Format ( PatchListFormat )
import Darcs.Patch.Merge ( Merge(..) )
import Darcs.Patch.Named.Wrapped
( WrappedNamed, patch2patchinfo, fmapFL_WrappedNamed, (:~:), (:~~:)
, generaliseRepoTypeWrapped
)
import Darcs.Patch.Prim ( PrimPatchBase(..), FromPrim )
import Darcs.Patch.Patchy ( Patchy, ReadPatch(..), Apply(..), Invert(..),
ShowPatch(..), Commute(..), PatchInspect(..) )
import Darcs.Patch.Repair ( Repair(..), RepairToFL )
import Darcs.Patch.RepoType ( RepoType(..), IsRepoType, RebaseTypeOf, RebaseType(..) )
import Darcs.Patch.Show ( ShowPatchBasic(..) )
import Darcs.Patch.Witnesses.Eq ( MyEq(..), EqCheck(..) )
import Darcs.Patch.Witnesses.Unsafe ( unsafeCoerceP )
import Darcs.Patch.Witnesses.Ordered ( (:>)(..), (:\/:)(..), (:/\:)(..), FL, mapFL )
import Darcs.Patch.Witnesses.Sealed ( Sealed(Sealed), seal, mapSeal )
import Darcs.Patch.Witnesses.Show ( Show1(..), Show2(..), ShowDict(ShowDictClass) )
import Darcs.Util.Exception ( prettyException )
import Darcs.Util.Tree( Tree )
data Hopefully a wX wY = Hopefully (SimpleHopefully a wX wY) | Hashed String (SimpleHopefully a wX wY)
deriving Show
data SimpleHopefully a wX wY = Actually (a wX wY) | Unavailable String
deriving Show
data PatchInfoAnd rt p wA wB = PIAP !PatchInfo (Hopefully (WrappedNamed rt p) wA wB)
deriving Show
instance Show2 p => Show1 (PatchInfoAnd rt p wX) where
showDict1 = ShowDictClass
instance Show2 p => Show2 (PatchInfoAnd rt p) where
showDict2 = ShowDictClass
instance PrimPatchBase p => PrimPatchBase (PatchInfoAnd rt p) where
type PrimOf (PatchInfoAnd rt p) = PrimOf p
newtype WPatchInfo wA wB = WPatchInfo { unWPatchInfo :: PatchInfo }
compareWPatchInfo :: WPatchInfo wA wB -> WPatchInfo wC wD -> EqCheck (wA, wB) (wC, wD)
compareWPatchInfo (WPatchInfo x) (WPatchInfo y) = if x == y then unsafeCoerceP IsEq else NotEq
instance MyEq WPatchInfo where
WPatchInfo x `unsafeCompare` WPatchInfo y = x == y
fmapH :: (a wX wY -> b wW wZ) -> Hopefully a wX wY -> Hopefully b wW wZ
fmapH f (Hopefully sh) = Hopefully (ff sh)
where ff (Actually a) = Actually (f a)
ff (Unavailable e) = Unavailable e
fmapH f (Hashed h sh) = Hashed h (ff sh)
where ff (Actually a) = Actually (f a)
ff (Unavailable e) = Unavailable e
info :: PatchInfoAnd rt p wA wB -> PatchInfo
info (PIAP i _) = i
patchDesc :: forall rt p wX wY . PatchInfoAnd rt p wX wY -> String
patchDesc p = justName $ info p
winfo :: PatchInfoAnd rt p wA wB -> WPatchInfo wA wB
winfo (PIAP i _) = WPatchInfo i
piap :: PatchInfo -> WrappedNamed rt p wA wB -> PatchInfoAnd rt p wA wB
piap i p = PIAP i (Hopefully $ Actually p)
n2pia :: WrappedNamed rt p wX wY -> PatchInfoAnd rt p wX wY
n2pia x = patch2patchinfo x `piap` x
patchInfoAndPatch :: PatchInfo -> Hopefully (WrappedNamed rt p) wA wB -> PatchInfoAnd rt p wA wB
patchInfoAndPatch = PIAP
fmapFLPIAP
:: (FL p wX wY -> FL q wX wY)
-> (RebaseTypeOf rt :~~: 'IsRebase -> p :~: q)
-> PatchInfoAnd rt p wX wY
-> PatchInfoAnd rt q wX wY
fmapFLPIAP f whenRebase (PIAP i hp)
= PIAP i (fmapH (fmapFL_WrappedNamed f whenRebase) hp)
generaliseRepoTypePIAP
:: PatchInfoAnd ('RepoType 'NoRebase) p wA wB
-> PatchInfoAnd rt p wA wB
generaliseRepoTypePIAP (PIAP i hp) = PIAP i (fmapH generaliseRepoTypeWrapped hp)
hopefully :: PatchInfoAnd rt p wA wB -> WrappedNamed rt p wA wB
hopefully = conscientiously $ \e -> text "failed to read patch:" $$ e
conscientiously :: (Doc -> Doc)
-> PatchInfoAnd rt p wA wB -> WrappedNamed rt p wA wB
conscientiously er (PIAP pinf hp) =
case hopefully2either hp of
Right p -> p
Left e -> errorDoc $ er (showPatchInfoUI pinf $$ text e)
hopefullyM :: Monad m => PatchInfoAnd rt p wA wB -> m (WrappedNamed rt p wA wB)
hopefullyM (PIAP pinf hp) = case hopefully2either hp of
Right p -> return p
Left e -> fail $ renderString Encode
(showPatchInfoUI pinf $$ text e)
hopefully2either :: Hopefully a wX wY -> Either String (a wX wY)
hopefully2either (Hopefully (Actually p)) = Right p
hopefully2either (Hashed _ (Actually p)) = Right p
hopefully2either (Hopefully (Unavailable e)) = Left e
hopefully2either (Hashed _ (Unavailable e)) = Left e
actually :: a wX wY -> Hopefully a wX wY
actually = Hopefully . Actually
createHashed :: String -> (String -> IO (Sealed (a wX))) -> IO (Sealed (Hopefully a wX))
createHashed h f = mapSeal (Hashed h) `fmap` unsafeInterleaveIO (f' `catchNonSignal` handler)
where
f' = do Sealed x <- f h
return (Sealed (Actually x))
handler e = return $ seal $ Unavailable $ prettyException e
extractHash :: PatchInfoAnd rt p wA wB -> Either (WrappedNamed rt p wA wB) String
extractHash (PIAP _ (Hashed s _)) = Right s
extractHash hp = Left $ conscientiously (\e -> text "unable to read patch:" $$ e) hp
unavailable :: String -> Hopefully a wX wY
unavailable = Hopefully . Unavailable
instance MyEq (PatchInfoAnd rt p) where
unsafeCompare (PIAP i _) (PIAP i2 _) = i == i2
instance Invert p => Invert (PatchInfoAnd rt p) where
invert (PIAP i p) = PIAP i (invert `fmapH` p)
instance PatchListFormat (PatchInfoAnd rt p)
instance (PatchListFormat p, ShowPatchBasic p) => ShowPatchBasic (PatchInfoAnd rt p) where
showPatch (PIAP n p) = case hopefully2either p of
Right x -> showPatch x
Left _ -> showPatchInfoUI n
instance (Apply p, Conflict p, CommuteNoConflicts p, IsHunk p, PatchListFormat p, PrimPatchBase p,
ShowPatch p, ApplyState p ~ Tree) => ShowPatch (PatchInfoAnd rt p) where
showContextPatch (PIAP n p) = case hopefully2either p of
Right x -> showContextPatch x
Left _ -> return $ showPatchInfoUI n
description (PIAP n _) = showPatchInfoUI n
summary (PIAP n p) = case hopefully2either p of
Right x -> summary x
Left _ -> showPatchInfoUI n
summaryFL = vcat . mapFL summary
showNicely (PIAP n p) = case hopefully2either p of
Right x -> showNicely x
Left _ -> showPatchInfoUI n
instance Commute p => Commute (PatchInfoAnd rt p) where
commute (x :> y) = do y' :> x' <- commute (hopefully x :> hopefully y)
return $ (info y `piap` y') :> (info x `piap` x')
instance Merge p => Merge (PatchInfoAnd rt p) where
merge (x :\/: y) = case merge (hopefully x :\/: hopefully y) of
y' :/\: x' -> (info y `piap` y') :/\: (info x `piap` x')
instance PatchInspect p => PatchInspect (PatchInfoAnd rt p) where
listTouchedFiles = listTouchedFiles . hopefully
hunkMatches f = hunkMatches f . hopefully
instance Apply p => Apply (PatchInfoAnd rt p) where
type ApplyState (PatchInfoAnd rt p) = ApplyState p
apply p = apply $ hopefully p
instance RepairToFL p => Repair (PatchInfoAnd rt p) where
applyAndTryToFix p = do mp' <- applyAndTryToFix $ hopefully p
case mp' of
Nothing -> return Nothing
Just (e,p') -> return $ Just (e, n2pia p')
instance ( ReadPatch p, PatchListFormat p, PrimPatchBase p, Effect p, FromPrim p
, IsRepoType rt
) => ReadPatch (PatchInfoAnd rt p) where
readPatch' = mapSeal n2pia <$> readPatch'
instance Effect p => Effect (PatchInfoAnd rt p) where
effect = effect . hopefully
effectRL = effectRL . hopefully
instance IsHunk (PatchInfoAnd rt p) where
isHunk _ = Nothing
instance PatchDebug p => PatchDebug (PatchInfoAnd rt p)
instance (Patchy p, ApplyState p ~ Tree) => Patchy (PatchInfoAnd rt p)