Example #1
0
        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.";
        }
Example #2
0
        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));
                    }
                }
            }
        }