public void Process(PatchContext context, PatchOperation operation) { var current = context.Source; var message = EditableJsonElementHelpers.FindParentOfTarget(ref current, operation.Path); if (message != null) { context.Message = message; return; } var from = context.Source; message = EditableJsonElementHelpers.FindTarget(ref from, operation.From); if (message != null) { context.Message = message; return; } if (operation.Path.Segments.Length == 0) { context.Source = from; return; } var last = operation.Path.Segments.Last(); if (current.Object != null) { current.Object[last.Value] = from; return; } if (current.Array != null) { if (last.Value == "-") { current.Array.Add(from); return; } if (!int.TryParse(last.Value, out var index) || 0 > index || index > current.Array.Count) { context.Message = $"Path `{operation.Path}` is not present in the instance."; return; } if ((index != 0 && last.Value[0] == '0') || (index == 0 && last.Value.Length > 1)) { context.Message = $"Path `{operation.Path}` is not present in the instance."; return; } current.Array.Insert(index, from); return; } context.Message = $"Path `{operation.Path}` is not present in the instance."; }
public void Process(PatchContext context, PatchOperation operation) { if (operation.Path.Segments.Length == 0) { context.Message = "Cannot remove root value."; return; } var current = context.Source; var message = EditableJsonElementHelpers.FindParentOfTarget(ref current, operation.Path); if (message != null) { context.Message = message; return; } var last = operation.Path.Segments.Last(); if (current.Object != null) { if (!current.Object.TryGetValue(last.Value, out _)) { context.Message = $"Path `{operation.Path}` is not present in the instance."; return; } current.Object.Remove(last.Value); return; } if (current.Array != null) { if (last.Value == "-") { current.Array.RemoveAt(current.Array.Count - 1); return; } if (!int.TryParse(last.Value, out var index) || 0 > index || index >= current.Array.Count) { context.Message = $"Path `{operation.Path}` is not present in the instance."; return; } if ((index != 0 && last.Value[0] == '0') || (index == 0 && last.Value.Length > 1)) { context.Message = $"Path `{operation.Path}` is not present in the instance."; return; } current.Array.RemoveAt(index); return; } context.Message = $"Path `{operation.Path}` is not present in the instance."; }
public void Process(PatchContext context, PatchOperation operation) { var current = context.Source; var message = EditableJsonElementHelpers.FindTarget(ref current, operation.Path); if (message != null) { context.Message = message; return; } if (current.ToElement().IsEquivalentTo(operation.Value)) { return; } context.Message = $"Path `{operation.Path}` is not equal to the indicated value."; }
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)); } } } }