module Git.Tree.Builder.Pure
( EntryHashMap
, newPureTreeBuilder
) where
import Control.Applicative
import Data.Monoid
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as HashMap
import Git
type EntryHashMap m = HashMap TreeFilePath (TreeEntry m)
newPureTreeBuilder :: Repository m
=> (Tree m -> m (EntryHashMap m))
-> (EntryHashMap m -> m (TreeOid m))
-> Maybe (Tree m)
-> m (TreeBuilder m)
newPureTreeBuilder reader writer mtree = do
entMap <- case mtree of
Nothing -> return HashMap.empty
Just tree -> reader tree
return $ makePureBuilder
(treeOid <$> mtree)
mempty
(newPureTreeBuilder reader writer)
entMap
writer
makePureBuilder :: Repository m
=> Maybe (TreeOid m)
-> HashMap TreeFilePath (TreeBuilder m)
-> (Maybe (Tree m) -> m (TreeBuilder m))
-> EntryHashMap m
-> (EntryHashMap m -> m (TreeOid m))
-> TreeBuilder m
makePureBuilder baseTree upds newBuilder entMap writer = TreeBuilder
{ mtbBaseTreeOid = baseTree
, mtbPendingUpdates = upds
, mtbNewBuilder = newBuilder
, mtbWriteContents = \tb -> (,) <$> pure (BuilderUnchanged tb)
<*> writer entMap
, mtbLookupEntry = \key -> return $ HashMap.lookup key entMap
, mtbEntryCount = return $ HashMap.size entMap
, mtbPutEntry = \tb key ent ->
return . ModifiedBuilder $
makePureBuilder
baseTree
(mtbPendingUpdates tb)
newBuilder
(HashMap.insert key ent entMap)
writer
, mtbDropEntry = \tb key ->
return . ModifiedBuilder $
makePureBuilder
baseTree
(mtbPendingUpdates tb)
newBuilder
(HashMap.delete key entMap)
writer
}