private static void PatchForObject(JsonElement orig, JsonElement mod, List <PatchOperation> patch, JsonPointer path) { var origNames = orig.EnumerateObject().Select(x => x.Name).ToArray(); var modNames = mod.EnumerateObject().Select(x => x.Name).ToArray(); foreach (var k in origNames.Except(modNames)) { patch.Add(PatchOperation.Remove(path.Combine(k))); } foreach (var k in modNames.Except(origNames)) { var prop = mod.EnumerateObject().First(p => p.NameEquals(k)); patch.Add(PatchOperation.Add(path.Combine(k), prop.Value)); } foreach (var k in origNames.Intersect(modNames)) { var origProp = orig.EnumerateObject().First(p => p.NameEquals(k)); var modProp = mod.EnumerateObject().First(p => p.NameEquals(k)); if (origProp.Value.ValueKind != modProp.Value.ValueKind) { patch.Add(PatchOperation.Replace(JsonPointer.Parse(path + modProp.Name), modProp.Value)); } else if (!string.Equals(origProp.Value.ToString(), modProp.Value.ToString())) // TODO { if (origProp.Value.ValueKind == JsonValueKind.Object) { PatchForObject(origProp.Value, modProp.Value, patch, path.Combine(modProp.Name)); } else if (origProp.Value.ValueKind == JsonValueKind.Array) { PatchForArray(origProp.Value, modProp.Value, patch, path.Combine(modProp.Name)); } else { patch.Add(PatchOperation.Replace(path.Combine(modProp.Name), modProp.Value)); } } } }
private static void PatchForArray(JsonElement orig, JsonElement mod, List <PatchOperation> patch, JsonPointer path) { for (int i = 0; i < Math.Max(orig.GetArrayLength(), mod.GetArrayLength()); i++) { var ui = (uint)i; if (i >= orig.GetArrayLength()) { patch.Add(PatchOperation.Add(path.Combine(ui), mod[i])); continue; } if (i >= mod.GetArrayLength()) { patch.Add(PatchOperation.Remove(path.Combine(ui))); continue; } var origObject = orig[i]; var modObject = mod[i]; if (origObject.ValueKind != modObject.ValueKind) { patch.Add(PatchOperation.Replace(path.Combine("/" + i), modObject)); } else if (!string.Equals(origObject.ToString(), modObject.ToString())) // TODO { if (origObject.ValueKind == JsonValueKind.Object) { PatchForObject(origObject, modObject, patch, path.Combine(ui)); } else if (origObject.ValueKind == JsonValueKind.Array) { PatchForArray(origObject, modObject, patch, path.Combine(ui)); } else { patch.Add(PatchOperation.Replace(path.Combine(ui), modObject)); } } } }