public bool Equals(IRecursiveDiffingType <TPropertiesEnum, TDiffGram> x, IRecursiveDiffingType <TPropertiesEnum, TDiffGram> y) { if (x == null && y == null) { return(true); } if (x == null ^ y == null) { return(false); } if (this.includeRecursiveChildren) { throw new System.NotImplementedException(); } return(x.Equals(x.DiffProperties(y), default(TPropertiesEnum))); }
public static IReadOnlyList <TDiffGram> ChangesSince <TPropertiesEnum, TDiffGram>(this IRecursiveDiffingType <TPropertiesEnum, TDiffGram> current, IRecursiveDiffingType <TPropertiesEnum, TDiffGram> priorVersion) where TPropertiesEnum : struct where TDiffGram : struct { Requires.NotNull(current, "current"); Requires.NotNull(priorVersion, "priorVersion"); if (current == priorVersion) { return(System.Collections.Immutable.ImmutableList.Create <TDiffGram>()); } if (priorVersion.Identity != current.Identity) { throw new System.ArgumentException("Not another version of the same node.", nameof(priorVersion)); } var currentAsParent = current as IRecursiveParent <IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >; var currentAsRecursiveType = (IRecursiveDiffingType <TPropertiesEnum, TDiffGram>)current; var before = new HashSet <ParentedRecursiveType <IRecursiveParent <IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >, IRecursiveDiffingType <TPropertiesEnum, TDiffGram> > >(Comparers.Parented <IRecursiveParent <IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >, IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >()); var after = new HashSet <ParentedRecursiveType <IRecursiveParent <IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >, IRecursiveDiffingType <TPropertiesEnum, TDiffGram> > >(Comparers.Parented <IRecursiveParent <IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >, IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >()); var priorVersionAsParent = priorVersion as IRecursiveParent <IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >; if (priorVersionAsParent != null) { before.UnionWith(priorVersionAsParent.GetSelfAndDescendentsWithParents <IRecursiveParent <IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >, IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >()); } else { before.Add(priorVersion.WithParent()); } if (currentAsParent != null) { after.UnionWith(currentAsParent.GetSelfAndDescendentsWithParents <IRecursiveParent <IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >, IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >()); } else { after.Add(current.WithParent()); } var added = new HashSet <ParentedRecursiveType <IRecursiveParent <IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >, IRecursiveDiffingType <TPropertiesEnum, TDiffGram> > >(Comparers.Parented <IRecursiveParent <IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >, IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >()); var removed = new HashSet <ParentedRecursiveType <IRecursiveParent <IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >, IRecursiveDiffingType <TPropertiesEnum, TDiffGram> > >(Comparers.Parented <IRecursiveParent <IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >, IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >()); var changed = new Dictionary <ParentedRecursiveType <IRecursiveParent <IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >, IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >, ParentedRecursiveType <IRecursiveParent <IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >, IRecursiveDiffingType <TPropertiesEnum, TDiffGram> > >(Comparers.Parented <IRecursiveParent <IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >, IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >()); var descendentsOfAddOrRemove = new HashSet <IRecursiveType>(Comparers.Identity); foreach (var fromBefore in before) { if (after.Contains(fromBefore)) { ParentedRecursiveType <IRecursiveParent <IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >, IRecursiveDiffingType <TPropertiesEnum, TDiffGram> > fromAfter; if (currentAsParent != null) { var parent = currentAsParent.GetParentedNode(fromBefore.Value.Identity); fromAfter = new ParentedRecursiveType <IRecursiveParent <IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >, IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >( (IRecursiveDiffingType <TPropertiesEnum, TDiffGram>)parent.Value, (IRecursiveParent <IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >)parent.Parent); } else { fromAfter = new ParentedRecursiveType <IRecursiveParent <IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >, IRecursiveDiffingType <TPropertiesEnum, TDiffGram> >( fromBefore.Value.Identity == current.Identity ? (IRecursiveDiffingType <TPropertiesEnum, TDiffGram>)current : null); } if (!object.ReferenceEquals(fromBefore.Value, fromAfter.Value) || fromBefore.Parent.Identity != fromAfter.Parent.Identity) { changed.Add(fromBefore, fromAfter); } } else { removed.Add(fromBefore); } } foreach (var fromAfter in after) { if (!before.Contains(fromAfter)) { added.Add(fromAfter); } } foreach (var topLevelOperation in added.Concat(removed)) { descendentsOfAddOrRemove.UnionWith(topLevelOperation.Value.GetSelfAndDescendents().Skip(1)); } var history = new List <TDiffGram>(); history.AddRange(removed.Where(r => !descendentsOfAddOrRemove.Contains(r.Value)).Select(r => currentAsRecursiveType.Remove(r.Value))); foreach (var changedNode in changed) { var oldNode = changedNode.Key; var newNode = changedNode.Value; var diff = newNode.DiffProperties(oldNode); if (!currentAsRecursiveType.Equals(diff, default(TPropertiesEnum))) { history.Add(currentAsRecursiveType.Change(oldNode.Value, newNode.Value, diff)); } } history.AddRange(added.Where(a => !descendentsOfAddOrRemove.Contains(a.Value)).Select(a => currentAsRecursiveType.Add(a.Value))); return(history); }
public int GetHashCode(IRecursiveDiffingType <TPropertiesEnum, TDiffGram> obj) { return(obj.Identity.GetHashCode()); }