Typed JSON lenses 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 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 Lens[T] {
// private fields
}pub struct ObjectLens {
// private fields
}impl LensTrait for ObjectLens