Exemple #1
0
            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)));
            }
Exemple #2
0
        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);
        }
Exemple #3
0
 public int GetHashCode(IRecursiveDiffingType <TPropertiesEnum, TDiffGram> obj)
 {
     return(obj.Identity.GetHashCode());
 }