void AddOrRemove(Parts destination, IParts source, int level) { var toBeAdded = source is Parts; Debug.Assert( source is Parts.NullParts || toBeAdded, $"Unsupported 'from' type ({source.GetType().FullName})."); var s = destination.SegmentPartsByNestingLevel(level); if (destination.NumberOfPathSegments == level + 1) { if (toBeAdded) { var leaf = new Tuple <Parts, Parts>(destination, source as Parts); LeavesToCreate.Add(s.Name, leaf); } else { LeavesToDrop.Add(s.Name, destination); } return; } if (!SubTreesToUpdate.TryGetValue(s.Name, out var targetTree)) { targetTree = new TargetTree(s); SubTreesToUpdate.Add(s.Name, targetTree); } targetTree.AddOrRemove(destination, source, ++level); }
protected void AddOrRemove_Internal(IParts from, Parts to) { switch (from) { case Parts toAddOrUpdate: if (toAddOrUpdate.Type != to.Type) { throw new ArgumentException($"Cannot map [{toAddOrUpdate.Type}: {toAddOrUpdate.Url}] to [{to.Type}: {to.Url}]. "); } if (toBeRemovedEntries.Contains(to)) { throw new InvalidOperationException($"Cannot add this as the target path '{to.Path}' in branch'{to.Branch}' of '{to.Owner}/{to.Repository}' as it's already scheduled for removal."); } if (!toBeAddedOrUpdatedEntries.TryGetValue(toAddOrUpdate, out var parts)) { parts = new List <Parts>(); toBeAddedOrUpdatedEntries.Add(toAddOrUpdate, parts); } parts.Add(to); break; case Parts.NullParts _: if (to.Type == TreeEntryTargetType.Tree) { throw new NotSupportedException($"Removing a '{nameof(TreeEntryTargetType.Tree)}' isn't supported."); } if (toBeAddedOrUpdatedEntries.Values.SelectMany(x => x).Contains(to)) { throw new InvalidOperationException( $"Cannot remove this as the target path '{to.Path}' in branch '{to.Branch}' of '{to.Owner}/{to.Repository}' as it's already scheduled for addition."); } if (toBeRemovedEntries.Contains(to)) { return; } toBeRemovedEntries.Add(to); break; default: throw new InvalidOperationException($"Unsupported 'from' type ({from.GetType().FullName})."); } }