public static JObject Diff()

in edge-util/src/Microsoft.Azure.Devices.Edge.Util/JsonEx.cs [99:174]


        public static JObject Diff(JToken fromToken, JToken toToken)
        {
            var patch = new JObject();

            // both 'from' and 'to' must be objects
            if (fromToken.Type != JTokenType.Object || toToken.Type != JTokenType.Object)
            {
                return patch;
            }

            var from = (JObject)fromToken;
            var to = (JObject)toToken;

            foreach (JProperty fromProp in from.Properties())
            {
                if (IsValidToken(fromProp.Value))
                {
                    JProperty toProp = to.Property(fromProp.Name);
                    if (toProp != null)
                    {
                        // if this property exists in 'to' and is an object then do a
                        // recursive deep diff
                        if (fromProp.Value.Type == JTokenType.Object && toProp.Value.Type == JTokenType.Object)
                        {
                            JObject obj = Diff(fromProp.Value, toProp.Value);

                            // if something was added in 'obj' then there's a diff to be
                            // patched in this sub-object
                            if (obj.HasValues)
                            {
                                patch.Add(fromProp.Name, obj);
                            }
                        }

                        // if this property exists in 'to' but has a different value
                        // then add the prop from 'to' to 'patch'
                        else if (fromProp.Value.Type != toProp.Value.Type || !JToken.DeepEquals(fromProp.Value, toProp.Value))
                        {
                            patch.Add(fromProp.Name, toProp.Value);
                        }
                    }

                    // if a property exists in 'from' but not in 'to' then that
                    // is to be deleted
                    else
                    {
                        patch.Add(fromProp.Name, JValue.CreateNull());
                    }
                }
                else
                {
                    throw new InvalidOperationException($"Property {fromProp.Name} has a value of unsupported type. Valid types are integer, float, string, bool, null and nested object");
                }
            }

            foreach (JProperty toProp in to.Properties())
            {
                if (IsValidToken(toProp.Value))
                {
                    JProperty fromProp = from.Property(toProp.Name);

                    // if this property exists in 'to' but not in 'from' then
                    // add it to 'patch'
                    if (fromProp == null)
                    {
                        patch.Add(toProp.Name, toProp.Value);
                    }
                }
                else
                {
                    throw new InvalidOperationException($"Property {toProp.Name} has a value of unsupported type. Valid types are integer, float, string, bool, null and nested object");
                }
            }

            return patch;
        }