JSON Schema validation for MoonBit, draft-04 through v1: four output formats, nineteen format names, and vocabularies from outside.
moon add moonbitstack/moonschemafn main raise {
let schema = @moonschema.Schema::new(
@json.parse(
(
#|{ "type": "object",
#| "properties": { "port": { "type": "integer", "minimum": 1 } },
#| "required": ["port"] }
),
),
)
println(schema.valid(@json.parse("{\"port\": 8080}")))
for fault in schema.faults(@json.parse("{\"port\": 0}")) {
println(fault.to_string())
}
}true
/port: below the minimum (minimum at /properties/port/minimum)let schema = @moonschema.Schema::new(@json.parse("{ \"type\": \"integer\" }"))
let report = schema.report(@json.parse("\"seven\""), output=@moonschema.Output::Basic)
println(report.to_json().stringify(indent=2)){
"valid": false,
"errors": [
{
"valid": false,
"keywordLocation": "/type",
"instanceLocation": "",
"error": "not of type integer"
}
]
}let schema = @moonschema.Schema::new(
@json.parse("{ \"format\": \"ipv4\" }"),
format=true,
)
println(schema.valid(@json.parse("\"not-an-ipv4\""))) // falselet remote = @json.parse("{ \"$ref\": \"https://example.test/int\" }")
let schema = @moonschema.Schema::new(
remote,
remotes={
"https://example.test/int": @json.parse("{ \"type\": \"integer\" }"),
},
)
println(schema.valid(Json::number(1.0))) // truestruct Even {}
pub impl @moonschema.Keyword for Even with fn name(_self) { "x-even" }
pub impl @moonschema.Keyword for Even with fn judge(_self, value, instance, site) {
ignore(site)
match (value, instance) {
(True, Number(number, ..)) =>
if number == (number / 2.0).floor() * 2.0 {
Accept
} else {
Refuse(why="odd")
}
_ => Accept
}
}
pub extend Even with @moonschema.Keyword::{name, judge}
struct Counting {}
pub impl @moonschema.Vocabulary for Counting with fn uri(_self) {
"https://example.test/vocab/counting"
}
pub impl @moonschema.Vocabulary for Counting with fn keywords(_self) {
let even : &@moonschema.Keyword = Even::{ }
[even]
}
pub extend Counting with Vocabulary::{uri, keywords}struct Even {}
pub impl Keyword for Even with fn name(_self) {
"x-even"
}
pub impl Keyword for Even with fn judge(_self, value, instance, site) {
ignore(site)
match (value, instance) {
(True, Number(number, ..)) =>
if number % 2.0 == 0.0 {
Accept
} else {
Refuse("odd")
}
_ => Accept()
}
}
pub extend Even with Keyword::{name, judge}pub(all) struct OutputUnit {
valid : Bool
keyword_at : String
absolute_at : String?
at : String
error : String?
annotation : Json?
children : Array[OutputUnit]
} derive(Eq, Debug)impl ToJson for OutputUnitpub struct Registry {
// private fields
}pub struct Schema {
// private fields
}let schema = @moonschema.Schema::new(
@json.parse("{ \"type\": \"integer\", \"minimum\": 1 }"),
)
for fault in schema.faults(@json.parse("0")) {
println(fault.to_string())
}
// the instance: below the minimum (minimum at /minimum)let schema = @moonschema.Schema::new(
@json.parse("{ \"type\": \"object\", \"required\": [\"id\"] }"),
)
schema.valid(@json.parse("{\"id\": 1}")) // truelet schema = @moonschema.Schema::new(
@json.parse("{ \"type\": \"integer\", \"minimum\": 1 }"),
)
let report = schema.report(@json.parse("0"), output=@moonschema.Output::Basic)
println(report.to_json().stringify(indent=2))let schema = @moonschema.Schema::new(@json.parse("{ \"type\": \"integer\" }"))
schema.valid(@json.parse("7")) // true
schema.valid(@json.parse("\"seven\"")) // falseInstall
Download zipJSON Schema validation for MoonBit, draft-04 through v1: four output formats, nineteen format names, and vocabularies from outside.