/// <summary> /// Applies the PATH operation to the given Document. /// </summary> /// <param name="operation">The PATCH operation.</param> /// <param name="document">The Document.</param> /// <exception cref="System.ArgumentNullException"></exception> public static void Apply(this PatchOperationDto operation, Document document) { operation.Validate(); if (document == null) throw new ArgumentNullException(nameof(document)); var dictionary = document.AsDictionary(); var path = new JsonPath(operation.path); operation.Apply(dictionary, path); }
private static void Apply(this PatchOperationDto operation, object parentObject, JsonPath path) { if (parentObject == null) throw new ArgumentNullException(nameof(parentObject)); if (path == null) throw new ArgumentNullException(nameof(path)); if (path.Segments.Count < 1) throw new ArgumentException($"Invalid path: '{path}'"); var currentSegment = path.Segments[0]; if (parentObject is IList) { var array = parentObject as IList; var index = currentSegment.ToArrayIndex(array); if (path.HasNext()) { // We're not yet on the target location, continue traversing the path. var nextPath = path.GetNext(); object childObject = index < array.Count ? array[index] : null; operation.Apply(childObject, nextPath); } else { // We are on the target location, perform the operation. switch (operation.op) { case PatchOpCode.ADD: array.Insert(index, operation.value); break; case PatchOpCode.REPLACE: array[index] = operation.value; break; case PatchOpCode.REMOVE: array.RemoveAt(index); break; } } } else if (parentObject is IDictionary<string, object>) { var dictionary = parentObject as IDictionary<string, object>; var fieldName = currentSegment; if (path.HasNext()) { // We're not yet on the target location, continue traversing the path. var nextPath = path.GetNext(); object childObject = dictionary.ContainsKey(fieldName) ? dictionary[fieldName] : null; operation.Apply(childObject, nextPath); } else { // We are on the target location, perform the operation. switch (operation.op) { case PatchOpCode.ADD: case PatchOpCode.REPLACE: dictionary[fieldName] = operation.value; break; case PatchOpCode.REMOVE: dictionary.Remove(fieldName); break; } } } }