Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 5 additions & 9 deletions JsonDiffPatch/AddOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,17 @@ public AddOperation(JsonPointer path, JToken value) : base(path)
Value = value;
}

public override void Write(JsonWriter writer)
public override void Write(IJsonObjectWriter writer)
{
writer.WriteStartObject();

WriteOp(writer, "add");
WritePath(writer,Path);
WriteValue(writer,Value);

writer.WriteEndObject();
writer.WriteOp("add").
WritePath(Path).
WriteValue(Value);
}

public override void Read(JObject jOperation)
{

Path = new JsonPointer(SplitPath((string)jOperation.GetValue("path")));
Path = new JsonPointer(jOperation.GetValue("path"));
Value = jOperation.GetValue("value");
}
}
Expand Down
16 changes: 6 additions & 10 deletions JsonDiffPatch/CopyOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,17 @@ public CopyOperation(JsonPointer path, JsonPointer fromPath) : base(path)
FromPath = fromPath;
}

public override void Write(JsonWriter writer)
public override void Write(IJsonObjectWriter writer)
{
writer.WriteStartObject();

WriteOp(writer, "copy");
WritePath(writer, Path);
WriteFromPath(writer, FromPath);

writer.WriteEndObject();
writer.WriteOp("copy").
WritePath(Path).
WriteFromPath(FromPath);
}

public override void Read(JObject jOperation)
{
Path = new JsonPointer(SplitPath((string)jOperation.GetValue("path")));
FromPath = new JsonPointer(SplitPath((string)jOperation.GetValue("from")));
Path = new JsonPointer(jOperation.GetValue("path"));
FromPath = new JsonPointer(jOperation.GetValue("from"));
}
}
}
15 changes: 15 additions & 0 deletions JsonDiffPatch/IJsonObjectWriter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;

using Newtonsoft.Json.Linq;

namespace JsonDiffPatch
{
public interface IJsonObjectWriter
{
void WriteProperty(string name, string value);

void WriteProperty(string name, JToken value);
}
}
23 changes: 14 additions & 9 deletions JsonDiffPatch/JsonDiffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ namespace JsonDiffPatch
/// <summary>
/// Parts adapted from https://github.com/benjamine/jsondiffpatch/blob/42ce1b6ca30c4d7a19688a020fce021a756b43cc/src/filters/arrays.js
/// </summary>
public class JsonDiffer
public static class JsonDiffer
{
internal static string Extend(string path, string extension)
private static string Extend(string path, string extension)
{
// TODO: JSON property name needs escaping for path ??
return path + "/" + EncodeKey(extension);
Expand All @@ -31,22 +31,22 @@ private static Operation Build(string op, string path, string key, JToken value)
(value == null ? "null" : value.ToString(Formatting.None)) + "}");
}

internal static Operation Add(string path, string key, JToken value)
private static Operation Add(string path, string key, JToken value)
{
return Build("add", path, key, value);
}

internal static Operation Remove(string path, string key)
private static Operation Remove(string path, string key)
{
return Build("remove", path, key, null);
}

internal static Operation Replace(string path, string key, JToken value)
private static Operation Replace(string path, string key, JToken value)
{
return Build("replace", path, key, value);
}

internal static IEnumerable<Operation> CalculatePatch(JToken left, JToken right, bool useIdToDetermineEquality,
private static IEnumerable<Operation> CalculatePatch(JToken left, JToken right, bool useIdToDetermineEquality,
string path = "")
{
if (left.Type != right.Type)
Expand Down Expand Up @@ -306,7 +306,12 @@ private static IEnumerable<Operation> ProcessArray(JToken left, JToken right, st

private class MatchesKey : IEqualityComparer<KeyValuePair<string, JToken>>
{
public static MatchesKey Instance = new MatchesKey();
public readonly static MatchesKey Instance = new MatchesKey();

private MatchesKey()
{

}

public bool Equals(KeyValuePair<string, JToken> x, KeyValuePair<string, JToken> y)
{
Expand All @@ -326,9 +331,9 @@ public int GetHashCode(KeyValuePair<string, JToken> obj)
/// <param name="to"></param>
/// <param name="useIdPropertyToDetermineEquality">Use id propety on array members to determine equality</param>
/// <returns></returns>
public PatchDocument Diff(JToken @from, JToken to, bool useIdPropertyToDetermineEquality)
public static PatchDocument Diff(JToken @from, JToken to, bool useIdPropertyToDetermineEquality)
{
return new PatchDocument(CalculatePatch(@from, to, useIdPropertyToDetermineEquality).ToArray());
return new PatchDocument(CalculatePatch(@from, to, useIdPropertyToDetermineEquality));
}
}

Expand Down
35 changes: 35 additions & 0 deletions JsonDiffPatch/JsonObjectWriterExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Text;

using Newtonsoft.Json.Linq;
using Tavis;

namespace JsonDiffPatch
{
internal static class JsonObjectWriterExtensions
{
public static IJsonObjectWriter WriteOp(this IJsonObjectWriter writer, string op)
{
writer.WriteProperty("op", op);
return writer;
}

public static IJsonObjectWriter WritePath(this IJsonObjectWriter writer, JsonPointer pointer)
{
writer.WriteProperty("path", pointer.ToString());
return writer;
}

public static IJsonObjectWriter WriteFromPath(this IJsonObjectWriter writer, JsonPointer pointer)
{
writer.WriteProperty("from", pointer.ToString());
return writer;
}
public static IJsonObjectWriter WriteValue(this IJsonObjectWriter writer, JToken value)
{
writer.WriteProperty("value", value);
return writer;
}
}
}
56 changes: 56 additions & 0 deletions JsonDiffPatch/JsonPointerTokensSource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Newtonsoft.Json.Linq;

namespace JsonDiffPatch
{
internal class JsonPointerTokensSource : IEnumerable<string>
{
private readonly IReadOnlyList<string> _list;
private readonly int startIndex;
private readonly int lastIndex;

public bool IsEmpty => lastIndex < startIndex;

public JsonPointerTokensSource(string pointer)
{
_list = pointer.Split('/').ToList();
startIndex = 1;
lastIndex = _list.Count - 1;
}

private JsonPointerTokensSource(IReadOnlyList<string> list, int startIndex, int lastIndex)
{
_list = list;
this.startIndex = startIndex;
this.lastIndex = lastIndex;
}

public string Last()
{
return lastIndex >= startIndex ? _list[lastIndex] : string.Empty;
}

internal JsonPointerTokensSource ForParent()
{
return new JsonPointerTokensSource(_list, startIndex, lastIndex - 1);
}

public IEnumerator<string> GetEnumerator()
{
for (int i = startIndex; i <= lastIndex; i++)
{
yield return _list[i];
}
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
16 changes: 6 additions & 10 deletions JsonDiffPatch/MoveOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,17 @@ public MoveOperation(JsonPointer path, JsonPointer fromPath) : base(path)
FromPath = fromPath;
}

public override void Write(JsonWriter writer)
public override void Write(IJsonObjectWriter writer)
{
writer.WriteStartObject();

WriteOp(writer, "move");
WritePath(writer, Path);
WriteFromPath(writer, FromPath);

writer.WriteEndObject();
writer.WriteOp("move").
WritePath(Path).
WriteFromPath(FromPath);
}

public override void Read(JObject jOperation)
{
Path = new JsonPointer(SplitPath((string)jOperation.GetValue("path")));
FromPath = new JsonPointer(SplitPath((string)jOperation.GetValue("from")));
Path = new JsonPointer(jOperation.GetValue("path"));
FromPath = new JsonPointer(jOperation.GetValue("from"));
}
}
}
29 changes: 2 additions & 27 deletions JsonDiffPatch/Operation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,7 @@ public Operation(JsonPointer path)
Path = path;
}

public abstract void Write(JsonWriter writer);

protected static void WriteOp(JsonWriter writer, string op)
{
writer.WritePropertyName("op");
writer.WriteValue(op);
}

protected static void WritePath(JsonWriter writer, JsonPointer pointer)
{
writer.WritePropertyName("path");
writer.WriteValue(pointer.ToString());
}

protected static void WriteFromPath(JsonWriter writer, JsonPointer pointer)
{
writer.WritePropertyName("from");
writer.WriteValue(pointer.ToString());
}
protected static void WriteValue(JsonWriter writer, JToken value)
{
writer.WritePropertyName("value");
value.WriteTo(writer);
}

protected static string[] SplitPath(string path) => path.Split('/').Skip(1).ToArray();
public abstract void Write(IJsonObjectWriter writer);

public abstract void Read(JObject jOperation);

Expand All @@ -55,7 +30,7 @@ public static Operation Parse(string json)

public static Operation Build(JObject jOperation)
{
var op = PatchDocument.CreateOperation((string)jOperation["op"]);
var op = OperationCreator.Create((string)jOperation["op"]);
op.Read(jOperation);
return op;
}
Expand Down
34 changes: 34 additions & 0 deletions JsonDiffPatch/OperationCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace JsonDiffPatch
{
internal class OperationCollection : IReadOnlyCollection<Operation>
{
private readonly List<Operation> _operations = new List<Operation>();

public int Count => _operations.Count;

public void Add(Operation operation)
{
_operations.Add(operation);
}

internal void AddRange(IEnumerable<Operation> operations)
{
_operations.AddRange(operations);
}

public IEnumerator<Operation> GetEnumerator()
{
return _operations.GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator()
{
return _operations.GetEnumerator();
}
}
}
23 changes: 23 additions & 0 deletions JsonDiffPatch/OperationCreator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace JsonDiffPatch
{
internal static class OperationCreator
{
public static Operation Create(string op)
{
switch (op)
{
case "add": return new AddOperation();
case "copy": return new CopyOperation();
case "move": return new MoveOperation();
case "remove": return new RemoveOperation();
case "replace": return new ReplaceOperation();
case "test": return new TestOperation();
}
return null;
}
}
}
Loading