Skip to content

Commit 2ae2317

Browse files
committed
JSON parser
1 parent 2454313 commit 2ae2317

File tree

2 files changed

+91
-1
lines changed

2 files changed

+91
-1
lines changed

utils/PPUtils.java

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ void start(Array<String> args) throws Exception {
8181
var statement = args.getFirst().orElse("");
8282
switch (statement) {
8383
case "find" -> { // Example: find [--print] public.+interface java$
84-
final var file = args.get(1).map(t -> Path.of(t)).get();
84+
final var file = args.get(1).map(Path::of).get();
8585
final var printLine = args.get(2).orElse("").equals("--print");
8686
final var subArgs = args.subArray(2 + (printLine ? 1 : 0 ));
8787
final var bodyPattern = subArgs.get(-2).map(t -> Pattern.compile(t)).orElse(null);
@@ -471,4 +471,59 @@ public static <T> Array<T> of(T... chars) {
471471
return new Array<T>(chars);
472472
}
473473
}
474+
475+
/** JSON parser */
476+
public static class Json {
477+
static final Pattern keyPattern = Pattern.compile("\"(.*?)\"\\s*:\\s*(\".*?\"|\\d+\\.?\\d*|true|false|null|\\{.*?\\})");
478+
final Map<String, Object> map;
479+
480+
private Json(Map<String, Object> map) {
481+
this.map = map;
482+
}
483+
484+
/** JSON Parser */
485+
public static Json of(String jsonString) {
486+
final var result = new HashMap<String, Object>();
487+
final var matcher = keyPattern.matcher(jsonString);
488+
while (matcher.find()) {
489+
final var key = matcher.group(1);
490+
final var value = parseValue(matcher.group(2));
491+
result.put(key, value);
492+
}
493+
return new Json(result);
494+
}
495+
496+
private static Object parseValue(final String textValue) {
497+
if (textValue.startsWith("\"") && textValue.endsWith("\"")) {
498+
return textValue.substring(1, textValue.length() - 1);
499+
} else if ("true".equals(textValue)) {
500+
return true;
501+
} else if ("false".equals(textValue)) {
502+
return false;
503+
} else if ("null".equals(textValue)) {
504+
return null;
505+
} else if (textValue.indexOf('.') >= 0) {
506+
return Double.parseDouble(textValue);
507+
} else if (textValue.startsWith("{")) {
508+
return of(textValue);
509+
} else {
510+
return Long.parseLong(textValue);
511+
}
512+
}
513+
514+
/** Sample: {@code json.get("a.b.c")} */
515+
public Optional<Object> get(String keys) {
516+
var json = this;
517+
var result = (Object) null;
518+
for (var key : keys.split("\\.")) {
519+
result = json.map.get(key);
520+
if (result instanceof Json j) {
521+
json = j;
522+
} else {
523+
Optional.empty();
524+
}
525+
}
526+
return Optional.ofNullable(result);
527+
}
528+
}
474529
}

utils/PPUtilsTest.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package utils;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static org.junit.jupiter.api.Assertions.*;
6+
7+
class PPUtilsTest {
8+
9+
@Test
10+
void jsonTest() {
11+
var json = """
12+
{ "a": "A"
13+
, "b": 1
14+
, "c": 2.2
15+
, "d": true
16+
, "e": null
17+
, "f": { "g": "G", "h": 2 }
18+
}
19+
""";
20+
21+
var map = PPUtils.Json.of(json);
22+
assertEquals(map.get("a").get(), "A");
23+
assertEquals(map.get("b").get(), 1L);
24+
assertEquals(map.get("c").get(), 2.2);
25+
assertEquals(map.get("d").get(), true);
26+
assertEquals(map.get("e").orElse(null), null);
27+
assertEquals(map.get("f.g").get(), "G");
28+
assertEquals(map.get("f.h").get(), 2L);
29+
30+
assertEquals(map.get("x").orElse("X"), "X");
31+
assertEquals(map.get("x.y").orElse("Y"), "Y");
32+
assertEquals(map.get("a.z").orElse("Z"), "Z");
33+
}
34+
35+
}

0 commit comments

Comments
 (0)