{-# LANGUAGE UndecidableInstances #-}
module Darcs.Patch.Named.Wrapped
( WrappedNamed(..)
, fromRebasing
) where
import Darcs.Prelude
import Control.Applicative ( (<|>) )
import Data.Coerce ( coerce )
import Darcs.Patch.Apply ( Apply(..) )
import Darcs.Patch.Commute ( Commute(..) )
import Darcs.Patch.Effect ( Effect(..) )
import Darcs.Patch.Ident ( Ident(..), PatchId )
import Darcs.Patch.Format ( PatchListFormat(..), ListFormat )
import Darcs.Patch.Info ( PatchInfo, showPatchInfo )
import Darcs.Patch.FromPrim ( FromPrim, PrimPatchBase(..) )
import Darcs.Patch.Named ( Named(..), patch2patchinfo )
import Darcs.Patch.Read ( ReadPatch(..) )
import Darcs.Patch.Rebase.Suspended
( Suspended(..)
, addFixupsToSuspended
, removeFixupsFromSuspended
)
import Darcs.Patch.RepoPatch ( RepoPatch )
import Darcs.Patch.RepoType
( RepoType(..), IsRepoType(..), SRepoType(..)
, RebaseType(..), SRebaseType(..)
)
import Darcs.Patch.Show ( ShowPatchBasic(..) )
import Darcs.Patch.Witnesses.Sealed ( mapSeal )
import Darcs.Patch.Witnesses.Show ( Show1, Show2 )
import Darcs.Patch.Witnesses.Ordered
( FL(..), mapFL_FL, (:>)(..)
)
data WrappedNamed (rt :: RepoType) p wX wY where
NormalP :: !(Named p wX wY) -> WrappedNamed rt p wX wY
RebaseP
:: (PrimPatchBase p, FromPrim p, Effect p)
=> !PatchInfo
-> !(Suspended p wX wX)
-> WrappedNamed ('RepoType 'IsRebase) p wX wX
deriving instance Show2 p => Show (WrappedNamed rt p wX wY)
instance Show2 p => Show1 (WrappedNamed rt p wX)
instance Show2 p => Show2 (WrappedNamed rt p)
fromRebasing :: WrappedNamed rt p wX wY -> Named p wX wY
fromRebasing (NormalP n) = n
fromRebasing (RebaseP {}) = error "internal error: found rebasing internal patch"
instance PrimPatchBase p => PrimPatchBase (WrappedNamed rt p) where
type PrimOf (WrappedNamed rt p) = PrimOf p
type instance PatchId (WrappedNamed rt p) = PatchInfo
instance Ident (WrappedNamed rt p) where
ident (NormalP p) = patch2patchinfo p
ident (RebaseP name _) = name
instance PatchListFormat (WrappedNamed rt p)
instance (ShowPatchBasic p, PatchListFormat p)
=> ShowPatchBasic (WrappedNamed rt p) where
showPatch f (NormalP n) = showPatch f n
showPatch f (RebaseP i s) = showPatchInfo f i <> showPatch f s
data ReadRebasing p wX wY where
ReadNormal :: p wX wY -> ReadRebasing p wX wY
ReadSuspended :: Suspended p wX wX -> ReadRebasing p wX wX
instance ( ReadPatch p, PrimPatchBase p, FromPrim p, Effect p, PatchListFormat p
, RepoPatch p, IsRepoType rt
) => ReadPatch (WrappedNamed rt p) where
readPatch' =
case singletonRepoType :: SRepoType rt of
SRepoType SIsRebase ->
let wrapNamed :: Named (ReadRebasing p) wX wY -> WrappedNamed rt p wX wY
wrapNamed (NamedP i [] (ReadSuspended s :>: NilFL))
= RebaseP i s
wrapNamed (NamedP i deps ps) = NormalP (NamedP i deps (mapFL_FL unRead ps))
unRead (ReadNormal p) = p
unRead (ReadSuspended _) = error "unexpected suspended patch"
in fmap (mapSeal wrapNamed) readPatch'
_ -> fmap (mapSeal NormalP) readPatch'
instance PatchListFormat p => PatchListFormat (ReadRebasing p) where
patchListFormat = coerce (patchListFormat :: ListFormat p)
instance (ReadPatch p, PatchListFormat p, PrimPatchBase p, RepoPatch p) => ReadPatch (ReadRebasing p) where
readPatch' =
mapSeal toSuspended <$> readPatch'
<|> mapSeal ReadNormal <$> readPatch'
where
toSuspended :: Suspended p wX wY -> ReadRebasing p wX wY
toSuspended (Items ps) = ReadSuspended (Items ps)
instance Apply p => Apply (WrappedNamed rt p) where
type ApplyState (WrappedNamed rt p) = ApplyState p
apply (NormalP n) = apply n
apply (RebaseP _ _) = return ()
unapply (NormalP n) = unapply n
unapply (RebaseP _ _) = return ()
instance Commute p => Commute (WrappedNamed rt p) where
commute (NormalP n1 :> NormalP n2) = do
n2' :> n1' <- commute (n1 :> n2)
return (NormalP n2' :> NormalP n1')
commute (RebaseP i1 s1 :> RebaseP i2 s2) =
return (RebaseP i2 s2 :> RebaseP i1 s1)
commute (NormalP n1 :> RebaseP i2 s2) =
return (RebaseP i2 (addFixupsToSuspended n1 s2) :> NormalP n1)
commute (RebaseP i1 s1 :> NormalP n2) =
return (NormalP n2 :> RebaseP i1 (removeFixupsFromSuspended n2 s1))