A complete JSON parser implementation in MoonBit
///|
test "basic usage" {
let json = "{\"name\": \"Alice\", \"age\": 30}"
let result = @tonyfettes/amjson.parse(json)
match result {
Object(map) => {
inspect(map.get("name"), content="Some(String(\"Alice\"))")
inspect(map.get("age"), content="Some(Number(30))")
}
_ => fail("Expected Object")
}
}///|
test "parse different types" {
// Null
let null_val = @tonyfettes/amjson.parse("null")
inspect(null_val, content="Null")
// Boolean
let bool_val = @tonyfettes/amjson.parse("true")
inspect(bool_val, content="Bool(true)")
// Number
let num_val = @tonyfettes/amjson.parse("42.5")
inspect(num_val, content="Number(42.5)")
// String
let str_val = @tonyfettes/amjson.parse("\"hello\"")
inspect(str_val, content="String(\"hello\")")
// Array
let arr_val = @tonyfettes/amjson.parse("[1, 2, 3]")
inspect(arr_val, content="Array([Number(1), Number(2), Number(3)])")
}///|
test "error handling" {
let invalid_json = "{invalid}"
let result = try! @tonyfettes/amjson.parse(invalid_json)
match result {
Err(UnexpectedChar(_pos, ch)) => inspect(ch, content="i")
_ => fail("Expected parse error")
}
}///|
test "nested structures" {
let json =
#|{
#| "users": [
#| {"name": "Bob", "score": 95.5},
#| {"name": "Carol", "score": 87.0}
#| ],
#| "count": 2
#|}
#|
let result = @tonyfettes/amjson.parse(json)
match result {
Object(map) => {
match map.get("users") {
Some(Array(users)) => inspect(users.length(), content="2")
_ => fail("Expected users array")
}
inspect(map.get("count"), content="Some(Number(2))")
}
_ => fail("Expected Object")
}
}///|
pub enum JsonValue {
Null
Bool(Bool)
Number(Double)
String(String)
Array(Array[JsonValue])
Object(Map[String, JsonValue])
}///|
pub(all) suberror ParseError {
UnexpectedChar(Position, Char)
UnexpectedEof(Position)
InvalidNumber(Position, String)
InvalidEscape(Position)
InvalidUnicodeEscape(Position)
}impl Eq for ParseErrorimpl Show for ParseErrortype PositionA complete JSON parser implementation in MoonBit