A minimal MoonBit validation library that constructs a typed value while validating, without holding a schema as a value.
///|
test {
let json : Json = { "name": "Ada", "age": 36 }
let obj = @maru.from_json(json).object()
let name = obj.field("name").string().nonempty().value()
let age = obj.field("age").int().range(0, 150).value()
assert_eq(name, "Ada")
assert_eq(age, 36)
}moon add kosei28/maruimport {
"kosei28/maru"
}///|
test {
let value = @maru.from_json({ "ok": true })
assert_eq(value.object().field("ok").bool().value(), true)
}value.null()
value.bool()
value.int()
value.int64()
value.double()
value.string()
value.array()
value.object()users[2].email: invalid emailTyped[String]
.nonempty()
.min_len(n)
.max_len(n)
.len(n)
.starts_with(s)
.ends_with(s)
.includes(s)
.lowercase()
.uppercase()
.regex(pattern)
.email()
.url()
.uuid()
.ipv4()
.ipv6()
.date()
.time()
.datetime()
.base64()
.eq(value)
.refine(predicate, message)
Typed[Int]
.min(n)
.max(n)
.range(min, max)
.gt(n)
.lt(n)
.positive()
.negative()
.nonnegative()
.nonpositive()
.multiple_of(n)
.eq(value)
.refine(predicate, message)
Typed[Int64]
.min(n)
.max(n)
.range(min, max)
.gt(n)
.lt(n)
.positive()
.negative()
.nonnegative()
.nonpositive()
.multiple_of(n)
.eq(value)
.refine(predicate, message)
Typed[Double]
.min(n)
.max(n)
.range(min, max)
.gt(n)
.lt(n)
.positive()
.negative()
.nonnegative()
.nonpositive()
.multiple_of(n)
.eq(value)
.refine(predicate, message)
Typed[Bool]
.eq(value)
.refine(predicate, message)
Typed[Array[T]]
.nonempty()
.min_len(n)
.max_len(n)
.len(n)
.unique()
.map(f)
.eq(value)
.refine(predicate, message)///|
fn User::parse(value : @maru.Value) -> User raise @maru.Invalid {
let obj = value.object()
User::{
name: obj.field("name").string().nonempty().value(),
email: obj.field("email").string().email().value(),
age: obj.field("age").int().range(0, 150).value(),
rating: obj.field("rating").double().range(0.0, 5.0).value(),
nickname: obj
.optional_field("nickname")
.map(v => v.string().max_len(30).value()),
}
}Object
↓ field("name")
Value
↓ string()
Typed[String]///|
test {
let obj = @maru.from_json({ "name": "Ada" }).object()
let nickname = obj
.optional_field("nickname")
.map(v => v.string().max_len(30).value())
assert_eq(nickname, None)
}///|
test {
let scores = @maru.from_json({ "scores": [10.0, 99.5] })
.object()
.field("scores")
.array()
.map(v => v.double().range(0.0, 100.0).value())
.value()
assert_eq(scores, [10.0, 99.5])
}///|
test {
let id = @maru.first_of(@maru.from_json(7), [
v => v.string().value(),
v => v.int().value().to_string(),
])
assert_eq(id, "7")
}///|
test {
let nickname : String? = @maru.first_of(@maru.from_json(null), [
v => { v.null(); None },
v => Some(v.string().value()),
])
assert_eq(nickname, None)
}Install
Download zipA minimal MoonBit validation library that constructs a typed value while validating, without holding a schema as a value.