{-# LANGUAGE MultiParamTypeClasses, OverloadedStrings, UndecidableInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Darcs.Patch.Prim.FileUUID.Apply ( hunkEdit, ObjectMap(..) ) where

import Darcs.Prelude

import Control.Monad.Catch ( MonadThrow(throwM) )
import Control.Monad.State( StateT, runStateT, gets, lift, put )
import qualified Data.ByteString as B
import qualified Data.Map as M

import Darcs.Patch.Apply ( Apply(..) )
import Darcs.Patch.ApplyMonad
    ( ApplyMonad(..), ApplyMonadTrans(..)
    , ApplyMonadOperations
    )
import Darcs.Patch.Prim.Class ( PrimApply(..) )
import Darcs.Patch.Prim.FileUUID.Core ( Prim(..), Hunk(..), HunkMove(..) )
import Darcs.Patch.Prim.FileUUID.Show
import Darcs.Patch.Prim.FileUUID.ObjectMap
import Darcs.Patch.Repair ( RepairToFL(..) )
import Darcs.Patch.Witnesses.Ordered ( FL(..) )

import Darcs.Util.Printer( text, packedString, ($$), renderString )


instance Apply Prim where
  type ApplyState Prim = ObjectMap
  apply :: forall (m :: * -> *) wX wY.
ApplyMonad (ApplyState Prim) m =>
Prim wX wY -> m ()
apply (Manifest UUID
i (L UUID
dirid Name
name)) = UUID -> (DirContent -> Either String DirContent) -> m ()
forall (m :: * -> *).
ApplyMonadObjectMap m =>
UUID -> (DirContent -> Either String DirContent) -> m ()
editDirectory UUID
dirid (Name -> UUID -> UUID -> DirContent -> Either String DirContent
addObject Name
name UUID
i UUID
dirid)
  apply (Demanifest UUID
i (L UUID
dirid Name
name)) = UUID -> (DirContent -> Either String DirContent) -> m ()
forall (m :: * -> *).
ApplyMonadObjectMap m =>
UUID -> (DirContent -> Either String DirContent) -> m ()
editDirectory UUID
dirid (Name -> UUID -> UUID -> DirContent -> Either String DirContent
delObject Name
name UUID
i UUID
dirid)
  apply (Hunk UUID
i Hunk wX wY
hunk) = UUID -> (FileContent -> Either String FileContent) -> m ()
forall (m :: * -> *).
ApplyMonadObjectMap m =>
UUID -> (FileContent -> Either String FileContent) -> m ()
editFile UUID
i (Hunk wX wY -> FileContent -> Either String FileContent
forall wX wY.
Hunk wX wY -> FileContent -> Either String FileContent
hunkEdit Hunk wX wY
hunk)
  apply (HunkMove (HM UUID
fs Int
ls UUID
ft Int
lt FileContent
c)) =
    UUID -> (FileContent -> Either String FileContent) -> m ()
forall (m :: * -> *).
ApplyMonadObjectMap m =>
UUID -> (FileContent -> Either String FileContent) -> m ()
editFile UUID
fs (Hunk Any Any -> FileContent -> Either String FileContent
forall wX wY.
Hunk wX wY -> FileContent -> Either String FileContent
hunkEdit (Int -> FileContent -> FileContent -> Hunk Any Any
forall wX wY. Int -> FileContent -> FileContent -> Hunk wX wY
H Int
ls FileContent
c FileContent
B.empty)) m () -> m () -> m ()
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> UUID -> (FileContent -> Either String FileContent) -> m ()
forall (m :: * -> *).
ApplyMonadObjectMap m =>
UUID -> (FileContent -> Either String FileContent) -> m ()
editFile UUID
ft (Hunk Any Any -> FileContent -> Either String FileContent
forall wX wY.
Hunk wX wY -> FileContent -> Either String FileContent
hunkEdit (Int -> FileContent -> FileContent -> Hunk Any Any
forall wX wY. Int -> FileContent -> FileContent -> Hunk wX wY
H Int
lt FileContent
B.empty FileContent
c))
  apply Prim wX wY
Identity = () -> m ()
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()

instance RepairToFL Prim where
  applyAndTryToFixFL :: forall (m :: * -> *) wX wY.
ApplyMonad (ApplyState Prim) m =>
Prim wX wY -> m (Maybe (String, FL Prim wX wY))
applyAndTryToFixFL Prim wX wY
p = Prim wX wY -> m ()
forall (m :: * -> *) wX wY.
ApplyMonad (ApplyState Prim) m =>
Prim wX wY -> m ()
forall (p :: * -> * -> *) (m :: * -> *) wX wY.
(Apply p, ApplyMonad (ApplyState p) m) =>
p wX wY -> m ()
apply Prim wX wY
p m ()
-> m (Maybe (String, FL Prim wX wY))
-> m (Maybe (String, FL Prim wX wY))
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Maybe (String, FL Prim wX wY) -> m (Maybe (String, FL Prim wX wY))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (String, FL Prim wX wY)
forall a. Maybe a
Nothing

instance PrimApply Prim where
  applyPrimFL :: forall (m :: * -> *) wX wY.
ApplyMonad (ApplyState Prim) m =>
FL Prim wX wY -> m ()
applyPrimFL FL Prim wX wY
NilFL = () -> m ()
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  applyPrimFL (Prim wX wY
p :>: FL Prim wY wY
ps) = Prim wX wY -> m ()
forall (m :: * -> *) wX wY.
ApplyMonad (ApplyState Prim) m =>
Prim wX wY -> m ()
forall (p :: * -> * -> *) (m :: * -> *) wX wY.
(Apply p, ApplyMonad (ApplyState p) m) =>
p wX wY -> m ()
apply Prim wX wY
p m () -> m () -> m ()
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> FL Prim wY wY -> m ()
forall (m :: * -> *) wX wY.
ApplyMonad (ApplyState Prim) m =>
FL Prim wX wY -> m ()
forall (prim :: * -> * -> *) (m :: * -> *) wX wY.
(PrimApply prim, ApplyMonad (ApplyState prim) m) =>
FL prim wX wY -> m ()
applyPrimFL FL Prim wY wY
ps

addObject :: Name -> UUID -> UUID -> DirContent -> Either String DirContent
addObject :: Name -> UUID -> UUID -> DirContent -> Either String DirContent
addObject Name
name UUID
obj UUID
dirid DirContent
dir
  | Just UUID
obj' <- Name -> DirContent -> Maybe UUID
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Name
name DirContent
dir =
    String -> Either String DirContent
forall a b. a -> Either a b
Left (String -> Either String DirContent)
-> String -> Either String DirContent
forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords
      [ String
"##error applying patch: cannot insert"
      , (Name, UUID) -> String
forall a. Show a => a -> String
show (Name
name, UUID
obj)
      , String
"into directory"
      , UUID -> String
forall a. Show a => a -> String
show UUID
dirid
      , String
"because another object"
      , UUID -> String
forall a. Show a => a -> String
show UUID
obj'
      , String
"with that name already exists"
      ]
  | Bool
otherwise = DirContent -> Either String DirContent
forall a b. b -> Either a b
Right (DirContent -> Either String DirContent)
-> DirContent -> Either String DirContent
forall a b. (a -> b) -> a -> b
$ Name -> UUID -> DirContent -> DirContent
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Name
name UUID
obj DirContent
dir

delObject :: Name -> UUID -> UUID -> DirContent -> Either String DirContent
delObject :: Name -> UUID -> UUID -> DirContent -> Either String DirContent
delObject Name
name UUID
obj UUID
dirid DirContent
dir =
  case Name -> DirContent -> Maybe UUID
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Name
name DirContent
dir of
    Just UUID
obj'
      | UUID
obj UUID -> UUID -> Bool
forall a. Eq a => a -> a -> Bool
== UUID
obj' -> DirContent -> Either String DirContent
forall a b. b -> Either a b
Right (DirContent -> Either String DirContent)
-> DirContent -> Either String DirContent
forall a b. (a -> b) -> a -> b
$ Name -> DirContent -> DirContent
forall k a. Ord k => k -> Map k a -> Map k a
M.delete Name
name DirContent
dir
      | Bool
otherwise ->
        String -> Either String DirContent
forall a b. a -> Either a b
Left (String -> Either String DirContent)
-> String -> Either String DirContent
forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords
          [ String
"##error applying patch: cannot remove"
          , (Name, UUID) -> String
forall a. Show a => a -> String
show (Name
name, UUID
obj)
          , String
"from directory"
          , UUID -> String
forall a. Show a => a -> String
show UUID
dirid
          , String
"because it contains a different object"
          , UUID -> String
forall a. Show a => a -> String
show UUID
obj'
          ]
    Maybe UUID
Nothing ->
        String -> Either String DirContent
forall a b. a -> Either a b
Left (String -> Either String DirContent)
-> String -> Either String DirContent
forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords
          [ String
"##error applying patch: cannot remove"
          , (Name, UUID) -> String
forall a. Show a => a -> String
show (Name
name, UUID
obj)
          , String
"from directory"
          , UUID -> String
forall a. Show a => a -> String
show UUID
dirid
          , String
"because it does not contain any object of that name"
          ]

hunkEdit :: Hunk wX wY -> FileContent -> Either String FileContent
hunkEdit :: forall wX wY.
Hunk wX wY -> FileContent -> Either String FileContent
hunkEdit h :: Hunk wX wY
h@(H Int
off FileContent
old FileContent
new) FileContent
c
  | FileContent
old FileContent -> FileContent -> Bool
`B.isPrefixOf` (Int -> FileContent -> FileContent
B.drop Int
off FileContent
c) =
      FileContent -> Either String FileContent
forall a b. b -> Either a b
Right (FileContent -> Either String FileContent)
-> FileContent -> Either String FileContent
forall a b. (a -> b) -> a -> b
$ [FileContent] -> FileContent
B.concat [Int -> FileContent -> FileContent
B.take Int
off FileContent
c, FileContent
new, Int -> FileContent -> FileContent
B.drop (Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ FileContent -> Int
B.length FileContent
old) FileContent
c]
  | Bool
otherwise =
      String -> Either String FileContent
forall a b. a -> Either a b
Left (String -> Either String FileContent)
-> String -> Either String FileContent
forall a b. (a -> b) -> a -> b
$ Doc -> String
renderString (Doc -> String) -> Doc -> String
forall a b. (a -> b) -> a -> b
$
      String -> Doc
text String
"##error applying hunk:" Doc -> Doc -> Doc
$$ Maybe UUID -> Hunk wX wY -> Doc
forall wX wY. Maybe UUID -> Hunk wX wY -> Doc
displayHunk Maybe UUID
forall a. Maybe a
Nothing Hunk wX wY
h Doc -> Doc -> Doc
$$ Doc
"##to" Doc -> Doc -> Doc
$$
      FileContent -> Doc
packedString FileContent
c
--       $$ text "##old=" <> text (ppShow old) $$
--       text "##new=" <> text (ppShow new) $$
--       text "##c=" <> text (ppShow c)

editObject :: MonadThrow m
           => UUID
           -> (Maybe (Object m) -> Either String (Object m))
           -> (StateT (ObjectMap m) m) ()
editObject :: forall (m :: * -> *).
MonadThrow m =>
UUID
-> (Maybe (Object m) -> Either String (Object m))
-> StateT (ObjectMap m) m ()
editObject UUID
i Maybe (Object m) -> Either String (Object m)
edit = do
  UUID -> m (Maybe (Object m))
load <- (ObjectMap m -> UUID -> m (Maybe (Object m)))
-> StateT (ObjectMap m) m (UUID -> m (Maybe (Object m)))
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets ObjectMap m -> UUID -> m (Maybe (Object m))
forall (m :: * -> *). ObjectMap m -> UUID -> m (Maybe (Object m))
getObject
  UUID -> Object m -> m (ObjectMap m)
store <- (ObjectMap m -> UUID -> Object m -> m (ObjectMap m))
-> StateT (ObjectMap m) m (UUID -> Object m -> m (ObjectMap m))
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets ObjectMap m -> UUID -> Object m -> m (ObjectMap m)
forall (m :: * -> *).
ObjectMap m -> UUID -> Object m -> m (ObjectMap m)
putObject
  Maybe (Object m)
obj <- m (Maybe (Object m)) -> StateT (ObjectMap m) m (Maybe (Object m))
forall (m :: * -> *) a. Monad m => m a -> StateT (ObjectMap m) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe (Object m)) -> StateT (ObjectMap m) m (Maybe (Object m)))
-> m (Maybe (Object m))
-> StateT (ObjectMap m) m (Maybe (Object m))
forall a b. (a -> b) -> a -> b
$ UUID -> m (Maybe (Object m))
load UUID
i
  Object m
obj' <- Either String (Object m) -> StateT (ObjectMap m) m (Object m)
forall (m :: * -> *) a. MonadThrow m => Either String a -> m a
liftEither (Either String (Object m) -> StateT (ObjectMap m) m (Object m))
-> Either String (Object m) -> StateT (ObjectMap m) m (Object m)
forall a b. (a -> b) -> a -> b
$ Maybe (Object m) -> Either String (Object m)
edit Maybe (Object m)
obj
  ObjectMap m
new <- m (ObjectMap m) -> StateT (ObjectMap m) m (ObjectMap m)
forall (m :: * -> *) a. Monad m => m a -> StateT (ObjectMap m) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (ObjectMap m) -> StateT (ObjectMap m) m (ObjectMap m))
-> m (ObjectMap m) -> StateT (ObjectMap m) m (ObjectMap m)
forall a b. (a -> b) -> a -> b
$ UUID -> Object m -> m (ObjectMap m)
store UUID
i (Object m -> m (ObjectMap m)) -> Object m -> m (ObjectMap m)
forall a b. (a -> b) -> a -> b
$ Object m
obj'
  ObjectMap m -> StateT (ObjectMap m) m ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put ObjectMap m
new

-- a semantic, ObjectMap-based interface for patch application
class ApplyMonadObjectMap m where
  editFile :: UUID -> (FileContent -> Either String FileContent) -> m ()
  editDirectory :: UUID -> (DirContent -> Either String DirContent) -> m ()

type instance ApplyMonadOperations ObjectMap = ApplyMonadObjectMap

instance MonadThrow m => ApplyMonad ObjectMap (StateT (ObjectMap m) m) where
  readFilePS :: ObjectIdOf ObjectMap -> StateT (ObjectMap m) m FileContent
readFilePS ObjectIdOf ObjectMap
i = do
    UUID -> m (Maybe (Object m))
load <- (ObjectMap m -> UUID -> m (Maybe (Object m)))
-> StateT (ObjectMap m) m (UUID -> m (Maybe (Object m)))
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets ObjectMap m -> UUID -> m (Maybe (Object m))
forall (m :: * -> *). ObjectMap m -> UUID -> m (Maybe (Object m))
getObject
    Maybe (Object m)
mobj <- m (Maybe (Object m)) -> StateT (ObjectMap m) m (Maybe (Object m))
forall (m :: * -> *) a. Monad m => m a -> StateT (ObjectMap m) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe (Object m)) -> StateT (ObjectMap m) m (Maybe (Object m)))
-> m (Maybe (Object m))
-> StateT (ObjectMap m) m (Maybe (Object m))
forall a b. (a -> b) -> a -> b
$ UUID -> m (Maybe (Object m))
load ObjectIdOf ObjectMap
UUID
i
    case Maybe (Object m)
mobj of
      Just (Blob m FileContent
readBlob Maybe Hash
_) -> m FileContent -> StateT (ObjectMap m) m FileContent
forall (m :: * -> *) a. Monad m => m a -> StateT (ObjectMap m) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m FileContent
readBlob
      Just Object m
_ -> IOError -> StateT (ObjectMap m) m FileContent
forall e a.
(HasCallStack, Exception e) =>
e -> StateT (ObjectMap m) m a
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> m a
throwM (IOError -> StateT (ObjectMap m) m FileContent)
-> IOError -> StateT (ObjectMap m) m FileContent
forall a b. (a -> b) -> a -> b
$ String -> IOError
userError (String -> IOError) -> String -> IOError
forall a b. (a -> b) -> a -> b
$ String
"readFilePS " String -> String -> String
forall a. [a] -> [a] -> [a]
++ UUID -> String
forall a. Show a => a -> String
show ObjectIdOf ObjectMap
UUID
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": object is not a file"
      Maybe (Object m)
Nothing -> IOError -> StateT (ObjectMap m) m FileContent
forall e a.
(HasCallStack, Exception e) =>
e -> StateT (ObjectMap m) m a
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> m a
throwM (IOError -> StateT (ObjectMap m) m FileContent)
-> IOError -> StateT (ObjectMap m) m FileContent
forall a b. (a -> b) -> a -> b
$ String -> IOError
userError (String -> IOError) -> String -> IOError
forall a b. (a -> b) -> a -> b
$ String
"readFilePS " String -> String -> String
forall a. [a] -> [a] -> [a]
++ UUID -> String
forall a. Show a => a -> String
show ObjectIdOf ObjectMap
UUID
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": no such file"

liftEither :: MonadThrow m => Either String a -> m a
liftEither :: forall (m :: * -> *) a. MonadThrow m => Either String a -> m a
liftEither (Left String
e) = IOError -> m a
forall e a. (HasCallStack, Exception e) => e -> m a
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> m a
throwM (IOError -> m a) -> IOError -> m a
forall a b. (a -> b) -> a -> b
$ String -> IOError
userError String
e
liftEither (Right a
v) = a -> m a
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
v

instance MonadThrow m => ApplyMonadObjectMap (StateT (ObjectMap m) m) where
  editFile :: UUID
-> (FileContent -> Either String FileContent)
-> StateT (ObjectMap m) m ()
editFile UUID
i FileContent -> Either String FileContent
edit = UUID
-> (Maybe (Object m) -> Either String (Object m))
-> StateT (ObjectMap m) m ()
forall (m :: * -> *).
MonadThrow m =>
UUID
-> (Maybe (Object m) -> Either String (Object m))
-> StateT (ObjectMap m) m ()
editObject UUID
i Maybe (Object m) -> Either String (Object m)
forall {m :: * -> *}.
MonadThrow m =>
Maybe (Object m) -> Either String (Object m)
edit'
    where
      edit' :: Maybe (Object m) -> Either String (Object m)
edit' (Just (Blob m FileContent
x Maybe Hash
_)) = Object m -> Either String (Object m)
forall a b. b -> Either a b
Right (Object m -> Either String (Object m))
-> Object m -> Either String (Object m)
forall a b. (a -> b) -> a -> b
$ m FileContent -> Maybe Hash -> Object m
forall (m :: * -> *). m FileContent -> Maybe Hash -> Object m
Blob (Either String FileContent -> m FileContent
forall (m :: * -> *) a. MonadThrow m => Either String a -> m a
liftEither (Either String FileContent -> m FileContent)
-> (FileContent -> Either String FileContent)
-> FileContent
-> m FileContent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FileContent -> Either String FileContent
edit (FileContent -> m FileContent) -> m FileContent -> m FileContent
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m FileContent
x) Maybe Hash
forall a. Maybe a
Nothing
      edit' Maybe (Object m)
Nothing = Object m -> Either String (Object m)
forall a b. b -> Either a b
Right (Object m -> Either String (Object m))
-> Object m -> Either String (Object m)
forall a b. (a -> b) -> a -> b
$ m FileContent -> Maybe Hash -> Object m
forall (m :: * -> *). m FileContent -> Maybe Hash -> Object m
Blob (Either String FileContent -> m FileContent
forall (m :: * -> *) a. MonadThrow m => Either String a -> m a
liftEither (Either String FileContent -> m FileContent)
-> Either String FileContent -> m FileContent
forall a b. (a -> b) -> a -> b
$ FileContent -> Either String FileContent
edit FileContent
"") Maybe Hash
forall a. Maybe a
Nothing
      edit' (Just (Directory DirContent
_)) =
        String -> Either String (Object m)
forall a b. a -> Either a b
Left (String -> Either String (Object m))
-> String -> Either String (Object m)
forall a b. (a -> b) -> a -> b
$ String
"wrong kind of object: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ UUID -> String
forall a. Show a => a -> String
show UUID
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is a directory, not a file"
  editDirectory :: UUID
-> (DirContent -> Either String DirContent)
-> StateT (ObjectMap m) m ()
editDirectory UUID
i DirContent -> Either String DirContent
edit = UUID
-> (Maybe (Object m) -> Either String (Object m))
-> StateT (ObjectMap m) m ()
forall (m :: * -> *).
MonadThrow m =>
UUID
-> (Maybe (Object m) -> Either String (Object m))
-> StateT (ObjectMap m) m ()
editObject UUID
i Maybe (Object m) -> Either String (Object m)
forall {m :: * -> *} {m :: * -> *}.
Maybe (Object m) -> Either String (Object m)
edit'
    where
      edit' :: Maybe (Object m) -> Either String (Object m)
edit' (Just (Directory DirContent
x)) = DirContent -> Object m
forall (m :: * -> *). DirContent -> Object m
Directory (DirContent -> Object m)
-> Either String DirContent -> Either String (Object m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DirContent -> Either String DirContent
edit DirContent
x
      edit' Maybe (Object m)
Nothing = DirContent -> Object m
forall (m :: * -> *). DirContent -> Object m
Directory (DirContent -> Object m)
-> Either String DirContent -> Either String (Object m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DirContent -> Either String DirContent
edit DirContent
forall k a. Map k a
M.empty
      edit' (Just (Blob m FileContent
_ Maybe Hash
_)) =
        String -> Either String (Object m)
forall a b. a -> Either a b
Left (String -> Either String (Object m))
-> String -> Either String (Object m)
forall a b. (a -> b) -> a -> b
$ String
"wrong kind of object: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ UUID -> String
forall a. Show a => a -> String
show UUID
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is a file, not a directory"

instance MonadThrow m => ApplyMonadTrans ObjectMap m where
  type ApplyMonadOver ObjectMap m = StateT (ObjectMap m) m
  runApplyMonad :: forall x.
ApplyMonadOver ObjectMap m x -> ObjectMap m -> m (x, ObjectMap m)
runApplyMonad = StateT (ObjectMap m) m x -> ObjectMap m -> m (x, ObjectMap m)
ApplyMonadOver ObjectMap m x -> ObjectMap m -> m (x, ObjectMap m)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT