@@ -382,46 +382,78 @@ instance ( Ord k
382
382
, DecidablyEmpty p
383
383
, Patch p
384
384
) => Semigroup (PatchMapWithPatchingMove k p) where
385
- PatchMapWithPatchingMove ma <> PatchMapWithPatchingMove mb = PatchMapWithPatchingMove m
385
+ PatchMapWithPatchingMove mNew <> PatchMapWithPatchingMove mOld = PatchMapWithPatchingMove m
386
386
where
387
- connections = Map. toList $ Map. intersectionWithKey (\ _ a b -> (_nodeInfo_to a , _nodeInfo_from b )) ma mb
388
- h :: (k , ( Maybe k , From k p ) ) -> [(k , Fixup k p )]
389
- h (_, (mToAfter, editBefore)) = case (mToAfter, editBefore) of
387
+ connections = Map. elems $ Map. intersectionWithKey (\ _ new old -> (_nodeInfo_to new , _nodeInfo_from old )) mNew mOld
388
+ h :: (Maybe k , From k p ) -> [(k , Fixup k p )]
389
+ h = \ case
390
390
(Just toAfter, From_Move fromBefore p)
391
391
| fromBefore == toAfter && isEmpty p
392
- -> [(toAfter, Fixup_Delete )]
392
+ -> [ (toAfter, Fixup_Delete )
393
+ ]
393
394
| otherwise
394
- -> [ (toAfter, Fixup_Update (This editBefore ))
395
- , (fromBefore, Fixup_Update (That mToAfter ))
395
+ -> [ (toAfter, Fixup_Update (This ( From_Move fromBefore p) ))
396
+ , (fromBefore, Fixup_Update (That ( Just toAfter) ))
396
397
]
397
- (Nothing , From_Move fromBefore _) -> [(fromBefore, Fixup_Update (That mToAfter ))] -- The item is destroyed in the second patch, so indicate that it is destroyed in the source map
398
- (Just toAfter, _ ) -> [(toAfter, Fixup_Update (This editBefore))]
398
+ (Nothing , From_Move fromBefore _) -> [(fromBefore, Fixup_Update (That Nothing ))] -- The item is destroyed in the second patch, so indicate that it is destroyed in the source map
399
+ (Just toAfter, editBefore ) -> [(toAfter, Fixup_Update (This editBefore))]
399
400
(Nothing , _) -> []
400
- mergeFixups _ Fixup_Delete Fixup_Delete = Fixup_Delete
401
- mergeFixups _ (Fixup_Update a) (Fixup_Update b)
401
+ mergeFixups Fixup_Delete Fixup_Delete = Fixup_Delete
402
+ mergeFixups (Fixup_Update a) (Fixup_Update b)
402
403
| This x <- a, That y <- b
403
404
= Fixup_Update $ These x y
404
405
| That y <- a, This x <- b
405
406
= Fixup_Update $ These x y
406
- mergeFixups _ _ _ = error " PatchMapWithPatchingMove: incompatible fixups"
407
- fixups = Map. fromListWithKey mergeFixups $ concatMap h connections
408
- combineNodeInfos _ nia nib = NodeInfo
409
- { _nodeInfo_from = _nodeInfo_from nia
410
- , _nodeInfo_to = _nodeInfo_to nib
407
+ mergeFixups _ _ = error " PatchMapWithPatchingMove: incompatible fixups"
408
+ fixups = Map. fromListWithKey ( \ _ -> mergeFixups) $ concatMap h connections
409
+ combineNodeInfos niNew niOld = NodeInfo
410
+ { _nodeInfo_from = _nodeInfo_from niNew
411
+ , _nodeInfo_to = _nodeInfo_to niOld
411
412
}
412
- applyFixup _ ni = \ case
413
+ applyFixup ni = \ case
413
414
Fixup_Delete -> Nothing
414
415
Fixup_Update u -> Just $ NodeInfo
415
416
{ _nodeInfo_from = case _nodeInfo_from ni of
416
- f@ (From_Move _ p') -> case getHere u of -- The `from` fixup comes from the "old" patch
417
- Nothing -> f -- If there's no `from` fixup, just use the "new" `from`
417
+ -- The new patch has a Move, so it could be affected by the
418
+ -- corresponding From in the old patch. If that From exists, then
419
+ -- it is in the fixup here.
420
+ f@ (From_Move _ p') -> case getHere u of
421
+ -- If there's no `From` fixup, just use the "new" `From`
422
+ Nothing -> f
423
+ -- If there's a `From` fixup which is an Insert, we can just apply
424
+ -- our patch to that and turn ourselves into an insert.
418
425
Just (From_Insert v) -> From_Insert $ applyAlways p' v
426
+ -- If there's a `From` fixup which is a Delete, then we can throw
427
+ -- our patch away because there's nothing to apply it to and
428
+ -- become a Delete ourselves.
419
429
Just From_Delete -> From_Delete
430
+ -- If there's a `From` fixup which is a Move, we need to apply
431
+ -- both the old patch and the new patch (in that order) to the
432
+ -- value, so we append the patches here.
420
433
Just (From_Move oldKey p) -> From_Move oldKey $ p' <> p
421
- _ -> error " PatchMapWithPatchingMove: fixup for non-move From"
422
- , _nodeInfo_to = fromMaybe (_nodeInfo_to ni) $ getThere u
434
+ -- If the new patch has an Insert, it doesn't care what the fixup
435
+ -- value is, because it will overwrite it anyway.
436
+ f@ (From_Insert _) -> f
437
+ -- If the new patch has an Delete, it doesn't care what the fixup
438
+ -- value is, because it will overwrite it anyway.
439
+ f@ From_Delete -> f
440
+ , _nodeInfo_to = case _nodeInfo_to ni of
441
+ -- The old patch deletes this data, so we must delete it as well.
442
+ -- According to the code above, any time we have this situation we
443
+ -- should also have `getThere u == Nothing` because a fixup
444
+ -- shouldn't be generated.
445
+ Nothing -> Nothing
446
+ -- The old patch sends the value to oldToAfter
447
+ Just oldToAfter -> case getThere u of
448
+ -- If there is no fixup, that should mean that the new patch
449
+ -- doesn't do anything with the value in oldToAfter, so we still
450
+ -- send it to oldToAfter
451
+ Nothing -> Just oldToAfter
452
+ -- If there is a fixup, it should tell us where the new patch
453
+ -- sends the value at key oldToAfter. We send our value there.
454
+ Just mNewToAfter -> mNewToAfter
423
455
}
424
- m = Map. differenceWithKey applyFixup (Map. unionWithKey combineNodeInfos ma mb ) fixups
456
+ m = Map. differenceWithKey ( \ _ -> applyFixup) (Map. unionWith combineNodeInfos mNew mOld ) fixups
425
457
getHere :: These a b -> Maybe a
426
458
getHere = \ case
427
459
This a -> Just a
0 commit comments