A pure MoonBit JSON parser with comprehensive parsing and serialization capabilities
{
"import": [
"tonyfettes/maria_json_parser"
]
}///|
test "parse basic json" {
let json_text = "{\"name\": \"Alice\", \"age\": 30}"
let value = @maria_json_parser.parse(json_text)
match value {
@maria_json_parser.JsonValue::Object(obj) => {
inspect(obj.get("name"), content="Some(String(\"Alice\"))")
inspect(obj.get("age"), content="Some(Number(30))")
}
_ => fail("Expected object")
}
}///|
test "serialize to json" {
let data : Map[String, @maria_json_parser.JsonValue] = {
"name": @maria_json_parser.JsonValue::String("Bob"),
"score": @maria_json_parser.JsonValue::Number(95.5),
"passed": @maria_json_parser.JsonValue::Boolean(true),
}
let json = @maria_json_parser.stringify(
@maria_json_parser.JsonValue::Object(data),
)
assert_true(json.contains("\"name\":\"Bob\""))
assert_true(json.contains("\"score\":95.5"))
}///|
test "pretty print json" {
let data : Map[String, @maria_json_parser.JsonValue] = {
"users": @maria_json_parser.JsonValue::Array([
@maria_json_parser.JsonValue::String("Alice"),
@maria_json_parser.JsonValue::String("Bob"),
]),
}
let pretty = @maria_json_parser.stringify(
@maria_json_parser.JsonValue::Object(data),
indent=2,
)
assert_true(pretty.contains("\n"))
assert_true(pretty.contains(" "))
}///|
pub(all) enum JsonValue {
Object(Map[String, JsonValue])
Array(Array[JsonValue])
String(String)
Number(Double)
Boolean(Bool)
Null
}///|
pub(all) suberror ParseError {
UnexpectedToken(Position, Token, String)
UnexpectedChar(Position, Char)
UnexpectedEof(Position)
InvalidNumber(Position, String)
InvalidEscape(Position, Char)
InvalidUnicode(Position, String)
}///|
test "parse example" {
let value = @maria_json_parser.parse("[1, 2, 3]")
match value {
@maria_json_parser.JsonValue::Array(arr) =>
inspect(arr.length(), content="3")
_ => fail("Expected array")
}
}///|
test "stringify example" {
let arr = @maria_json_parser.JsonValue::Array([
@maria_json_parser.JsonValue::Number(1.0),
@maria_json_parser.JsonValue::Number(2.0),
])
let json = @maria_json_parser.stringify(arr)
inspect(json, content="[1,2]")
}///|
test "pretty string example" {
let obj : Map[String, @maria_json_parser.JsonValue] = {
"key": @maria_json_parser.JsonValue::String("value"),
}
let pretty = @maria_json_parser.JsonValue::Object(obj).to_pretty_string()
assert_true(pretty.contains("\n"))
}///|
test "handle parse errors" {
let result : Result[
@maria_json_parser.JsonValue,
@maria_json_parser.ParseError,
] = try! @maria_json_parser.parse("invalid")
match result {
Err(_error) =>
// Handle error - position and details available in error
inspect(true, content="true")
Ok(_) => fail("Expected error")
}
}///|
test "complex structure" {
let json =
#|{
#| "user": {
#| "name": "Alice",
#| "settings": {
#| "theme": "dark",
#| "notifications": true
#| }
#| }
#|}
let value = @maria_json_parser.parse(json)
match value {
@maria_json_parser.JsonValue::Object(root) =>
match root.get("user") {
Some(@maria_json_parser.JsonValue::Object(user)) =>
match user.get("settings") {
Some(@maria_json_parser.JsonValue::Object(settings)) => {
inspect(settings.get("theme"), content="Some(String(\"dark\"))")
inspect(
settings.get("notifications"),
content="Some(Boolean(true))",
)
}
_ => fail("Expected settings object")
}
_ => fail("Expected user object")
}
_ => fail("Expected root object")
}
}///|
test "round trip" {
let original = @maria_json_parser.JsonValue::Array([
@maria_json_parser.JsonValue::String("hello"),
@maria_json_parser.JsonValue::Number(42.0),
@maria_json_parser.JsonValue::Boolean(true),
@maria_json_parser.JsonValue::Null,
])
let json = @maria_json_parser.stringify(original)
let parsed = @maria_json_parser.parse(json)
inspect(parsed == original, content="true")
}impl Eq for ParseErrorimpl Show for ParseErrortype Positiontype TokenA pure MoonBit JSON parser with comprehensive parsing and serialization capabilities