Libraryless. Click here for Pure Java version (2818L/18K).
1 | sclass JsonDiff { |
2 | srecord DiffResult(O a, O b) {} |
3 | |
4 | // key made from getListKey |
5 | srecord GatheredKey(S key, O value) { |
6 | O get() { ret value; } |
7 | } |
8 | |
9 | sclass Removed > DiffResult { *(O *a, O *b) {} } // b missing |
10 | sclass Added > DiffResult { *(O *a, O *b) {} } // a missing |
11 | sclass DifferentType > DiffResult { *(O *a, O *b) {} } |
12 | sclass Different > DiffResult { *(O *a, O *b) {} } // same type, generally different |
13 | |
14 | // paths are usually L<String>, but IDs gathered by getListKey can also be in there |
15 | |
16 | IF1<L, S> getListKey; // key field for diffing lists. argument is path |
17 | |
18 | // returns null if identical |
19 | O diff(S json1, S json2) { |
20 | O o1 = jsonDecode(json1), o2 = jsonDecode(json2); |
21 | ret diff(json1, json2, new L); |
22 | } |
23 | |
24 | // a, b = decoded JSON |
25 | O diff(O a, O b) { |
26 | ret diff(a, b, new L); |
27 | } |
28 | |
29 | // a, b = decoded JSON |
30 | O diff(O a, O b, L path) { |
31 | if (eq(a, b)) null; |
32 | if (a == null) ret new Added(a, b); |
33 | if (b == null) ret new Removed(a, b); |
34 | if (a.getClass() != b.getClass()) ret new DifferentType(a, b); |
35 | // from here on, we know that a and b have the same type |
36 | if (a cast Map) |
37 | ret diffMaps(a, (Map) b, path); |
38 | |
39 | if (a cast L) |
40 | try object diffLists(a, (L) b, path); |
41 | |
42 | ret new Different(a, b); |
43 | } |
44 | |
45 | O diffMaps(Map a, Map b, L path) { |
46 | ret withoutNullValues |
47 | (mapKeyAndFunction_lhm(concatAsOrderedSet(keys(a), keys(b)), |
48 | key -> { |
49 | temp tempAddToList(path, key); |
50 | ret diff(a.get(key), b/Map.get(key), path); |
51 | })); |
52 | } |
53 | |
54 | O diffLists(L a, L b, L path) { |
55 | S key = callF(getListKey, path); |
56 | if (key == null) null; |
57 | Map mapA = gatherListElements(a, key, path); |
58 | if (mapA == null) null; |
59 | Map mapB = gatherListElements(b, key, path); |
60 | if (mapB == null) null; |
61 | ret diffMaps(mapA, mapB, path); |
62 | } |
63 | |
64 | Map gatherListElements(L l, S key, L path) { |
65 | new LinkedHashMap mapOut; |
66 | for (O x : l) { |
67 | if (!x instanceof Map) |
68 | ret null with print("Can't get object key " + key + " of non-map (path: " + path + ")"); |
69 | mapOut.put(new GatheredKey(key, x/Map.get(key)), x); |
70 | } |
71 | ret mapOut; |
72 | } |
73 | } |
download show line numbers debug dex old transpilations
Travelled to 6 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1026301 |
Snippet name: | JsonDiff |
Eternal ID of this version: | #1026301/24 |
Text MD5: | 080d4f10b8b5a7c6ffad2a6c17ae4387 |
Transpilation MD5: | d87170cd9534f76ee00b78ef35ecf234 |
Author: | stefan |
Category: | javax / discord |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2019-12-15 21:34:31 |
Source code size: | 2214 bytes / 73 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 343 / 1090 |
Version history: | 23 change(s) |
Referenced in: | [show references] |