| ModifyContent k v
deriving (Eq, Ord, Show)
+pairToFunc :: (a -> b -> c) -> (a, b) -> c
+pairToFunc func (a, b) = func a b
+
{- | Perform a bi-directional sync. Compared to the last known state of
the child, evaluate the new states of the master and child. Return a list of
changes to make to the master and list of changes to make to the child to
where masterchanges = (map DeleteItem .
findDeleted childstate masterstate $ lastchildstate)
++
- (map (\(x, y) -> CopyItem x y) .
+ (map (pairToFunc CopyItem) .
findAdded childstate masterstate $ lastchildstate)
- ++ (map (\(x, y) -> ModifyContent x y) . Map.toList $ masterPayloadChanges)
+ ++ (map (pairToFunc ModifyContent) . Map.toList $ masterPayloadChanges)
childchanges = (map DeleteItem .
findDeleted masterstate childstate $ lastchildstate)
++
- (map (\(x, y) -> CopyItem x y) .
+ (map (pairToFunc CopyItem) .
findAdded masterstate childstate $ lastchildstate)
- ++ (map (\(x, y) -> ModifyContent x y) . Map.toList $ childPayloadChanges)
+ ++ (map (pairToFunc ModifyContent) . Map.toList $ childPayloadChanges)
masterPayloadChanges =
- findModified childstate lastchildstate
+ Map.union (findModified childstate lastchildstate)
+ (findModified childstate masterstate)
-- The child's payload takes precedence, so we are going to
-- calculate the changes made on the master to apply to the client,
-- then subtract out any items in the master changes that have the
-- same key.
childPayloadChanges =
foldl (flip Map.delete) (findModified masterstate lastchildstate)
- (Map.keys masterPayloadChanges)
+ (Map.keys (findModified childstate masterstate))
{- | Compares two SyncCollections, and returns the commands that, when
-> [SyncCommand k v]
diffCollection coll1 coll2 =
(map DeleteItem . findDeleted coll2 coll1 $ coll1) ++
- (map (\(k, v) -> CopyItem k v) . findAdded coll2 coll1 $ coll1)
+ (map (pairToFunc CopyItem) . findAdded coll2 coll1 $ coll1)
{- | Returns a list of keys that exist in state2 and lastchildstate
but not in state1 -}
findModified :: (Ord k, Eq v) =>
SyncCollection k v -> SyncCollection k v -> SyncCollection k v
findModified state1 lastchildstate =
- Map.differenceWith (\v1 v2 -> if v1 /= v2 then Just v1 else Nothing) state1 $ lastchildstate
+ Map.mapMaybe id .
+ Map.intersectionWith (\v1 v2 -> if v1 /= v2 then Just v1 else Nothing)
+ state1 $ lastchildstate
{- | Apply the specified changes to the given SyncCollection. Returns
a new SyncCollection with the changes applied. If changes are specified