-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathjson_array_extraction.ail
More file actions
106 lines (87 loc) · 3.85 KB
/
Copy pathjson_array_extraction.ail
File metadata and controls
106 lines (87 loc) · 3.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
-- JSON Array Extraction (v0.6.5)
-- Demonstrates filterStrings, allStrings, getStringArrayOrEmpty, etc.
module examples/runnable/json_array_extraction
import std/json (Json, JString, JNumber, JBool, JNull, JArray,
filterStrings, filterNumbers, allStrings, allNumbers,
getStringArray, getStringArrayStrict, getStringArrayOrEmpty,
getNumberArray, getNumberArrayOrEmpty,
decode, jo, ja, kv, js, jnum)
import std/option (Option, Some, None)
import std/result (Result, Ok, Err)
import std/string (join, floatToStr)
import std/list (length)
-- Helper to show float list
func showFloats(xs: [float]) -> string {
showFloatsHelper(xs, true)
}
func showFloatsHelper(xs: [float], first: bool) -> string {
match xs {
[] => "",
[x, ...rest] => {
let prefix = if first then "" else ", ";
"${prefix}${floatToStr(x)}${showFloatsHelper(rest, false)}"
}
}
}
export func main() -> () ! {IO} {
println("=== Permissive Array Extraction (filterStrings/filterNumbers) ===");
-- Mixed array with different JSON types
let mixed = [JString("apple"), JNumber(42.0), JString("banana"), JBool(true), JString("cherry")];
-- filterStrings: Extract only strings, skip non-strings
let strings = filterStrings(mixed);
println("filterStrings(mixed) = [${join(", ", strings)}]");
-- filterNumbers: Extract only numbers, skip non-numbers
let numbers = filterNumbers(mixed);
println("filterNumbers(mixed) = [${showFloats(numbers)}]");
println("");
println("=== Strict Array Extraction (allStrings/allNumbers) ===");
-- allStrings: Fails if any element is not a string
match allStrings(mixed) {
Some(xs) => println("allStrings(mixed) = Some([${join(", ", xs)}])"),
None => println("allStrings(mixed) = None (mixed types!)")
};
-- All-string array
let onlyStrings = [JString("red"), JString("green"), JString("blue")];
match allStrings(onlyStrings) {
Some(xs) => println("allStrings(onlyStrings) = Some([${join(", ", xs)}])"),
None => println("allStrings(onlyStrings) = None")
};
-- All-number array
let onlyNumbers = [JNumber(1.0), JNumber(2.0), JNumber(3.0)];
match allNumbers(onlyNumbers) {
Some(xs) => println("allNumbers(onlyNumbers) = Some([${showFloats(xs)}])"),
None => println("allNumbers(onlyNumbers) = None")
};
println("");
println("=== Convenience Wrappers (getStringArrayOrEmpty, etc.) ===");
-- Parse JSON object with tags array
let jsonStr = "{\"name\": \"Project\", \"tags\": [\"ai\", \"lang\", \"functional\"]}";
match decode(jsonStr) {
Ok(obj) => {
-- getStringArrayOrEmpty: Returns [] if missing or invalid
let tags = getStringArrayOrEmpty(obj, "tags");
println("getStringArrayOrEmpty(obj, \"tags\") = [${join(", ", tags)}]");
let missing = getStringArrayOrEmpty(obj, "categories");
println("getStringArrayOrEmpty(obj, \"categories\") = [${join(", ", missing)}] (empty for missing)");
-- getStringArray: Returns Option (Some for valid, None for missing/invalid)
match getStringArray(obj, "tags") {
Some(xs) => println("getStringArray(obj, \"tags\") = Some([${join(", ", xs)}])"),
None => println("getStringArray(obj, \"tags\") = None")
}
},
Err(e) => println("Parse error: ${e}")
};
println("");
println("=== Real-World Use Case: Config Parsing ===");
-- Parse a config with string arrays
let configStr = "{\"allowedHosts\": [\"example.com\", \"api.example.com\"], \"ports\": [80, 443, 8080]}";
match decode(configStr) {
Ok(config) => {
let hosts = getStringArrayOrEmpty(config, "allowedHosts");
println("Allowed hosts (${show(length(hosts))}): ${join(", ", hosts)}");
let ports = getNumberArrayOrEmpty(config, "ports");
println("Ports (${show(length(ports))}): ${showFloats(ports)}")
},
Err(e) => println("Config parse error: ${e}")
}
}