Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

73
LINES

< > BotCompany Repo | #1026301 // JsonDiff

JavaX fragment (include) [tags: use-pretranspiled]

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]