Typed JSON lenses, builders, and aggregate validation for MoonBit
test {
let document = @json.parse(
"{\"user\":{\"name\":\"Ada\",\"age\":37,\"active\":true}}",
)
let user = object("user")
let name_lens = user.string("name")
let age_lens = user.int("age")
let active_lens = user.bool("active")
inspect(name_lens.get(document), content="Ada")
inspect(age_lens.get(document), content="37")
inspect(active_lens.get(document), content="true")
}test {
let document = @json.parse("{\"user\":{}}")
try {
object("user").string("name").get(document) |> ignore
fail("expected LensError")
} catch {
LensError(issue) =>
inspect(issue.pointer.to_string(), content="/user/name")
_ => fail("unexpected error")
}
}test {
let builder = JsonBuilder::JsonBuilder()
let user = object("user")
user.string("name").set(builder, "Ada")
user.int("age").set(builder, 37)
user.bool("active").set(builder, true)
user.string("roles").array().set(builder, ["admin", "reviewer"])
@json.json_inspect(builder, content={
"user": {
"name": "Ada",
"age": 37,
"active": true,
"roles": ["admin", "reviewer"],
},
})
}test {
let document = @json.parse("{\"names\":[\"Ada\",\"Grace\"]}")
debug_inspect(
root().string("names").array().get(document),
content="[\"Ada\", \"Grace\"]",
)
}| Input state | Required string | nullable | optional | nullish |
|---|---|---|---|---|
| Missing | error | error | None | None |
| null | type error | None | type error | None |
| String | value | Some(T) | Some(T) | Some(T) |
test {
let document = @json.parse(
"{\"user\":{\"name\":\"Ada\",\"age\":37}}",
)
let user = object("user")
let name_lens = user.string("name")
let age_lens = user.int("age")
match validate(document, [user, name_lens, age_lens]) {
Valid => {
let name : String = name_lens.get(document)
let age : Int = age_lens.get(document)
inspect((name, age), content="(Ada, 37)")
}
Invalid(issues) => fail("unexpected issues: \{issues}")
}
}pub struct JsonBuilder {
// private fields
}impl ToJson for JsonBuilderpub struct Lens[T] {
// private fields
}fn[T] Lens::get_or_json_decode_error(self : Lens[T], document : Json, path : JsonPath) -> T raise JsonDecodeErrorpub struct ObjectLens {
// private fields
}impl LensTrait for ObjectLenspub struct PresenceLens[T] {
// private fields
}impl LensTrait for PresenceLens[T]fn[T] PresenceLens::get_or_json_decode_error(self : PresenceLens[T], document : Json, path : JsonPath) -> T? raise JsonDecodeErrorfn[T] PresenceLens::json_decode_error(self : PresenceLens[T], path : JsonPath, message : String) -> JsonDecodeErrorfn[T] PresenceLens::nullish(self : PresenceLens[T], encode_mode? : NullishEncodeMode) -> PresenceLens[T]fn[T] PresenceLens::set(self : PresenceLens[T], builder : JsonBuilder, value : T?) -> Unit raise JsonBuildErrorTyped JSON lenses, builders, and aggregate validation for MoonBit