///|
test {
let types = @schema.TypeConstraint::many([
@schema.StringType,
@schema.NullType,
]).unwrap()
let schema = @schema.Schema::from_keywords([
@schema.Type(types),
@schema.MaxLength(
@schema.NonNegativeInteger::parse("9007199254740993").unwrap(),
),
@schema.Default(@json.Value::null()),
@schema.ReadOnly(false),
]).unwrap()
guard schema.kind() is @schema.ObjectSchema(object) else { fail("object") }
guard object.keyword("maxLength").unwrap() is @schema.MaxLength(bound) else {
fail("bound")
}
assert_eq(bound.number().token(), "9007199254740993")
assert_true(schema.to_json().get("default") is Some(_))
assert_true(object.keyword("minLength") is None)
}///|
test {
let raw = @json.parse(
"{\"properties\":{\"$id\":false},\"default\":{\"type\":17},\"custom\":{\"$ref\":\"literal data\"},\"x-vendor\":false}",
)
.unwrap()
.lower()
.unwrap()
let schema = @schema.Schema::from_json(raw).unwrap()
guard schema.kind() is @schema.ObjectSchema(object) else { fail("object") }
assert_eq(object.additional_fields().length(), 1)
assert_eq(object.extensions().entries().length(), 1)
guard object.keyword("properties").unwrap() is @schema.Properties(entries) else {
fail("properties")
}
assert_eq(entries[0].0, "$id")
assert_true(entries[0].1.kind() is @schema.BooleanSchema(false))
assert_true(schema.to_json().equals(raw).unwrap())
}///|
test {
let raw = @json.parse("{\"type\":17}").unwrap().lower().unwrap()
assert_true(@schema.Schema::from_json(raw) is Err(_))
let report = @schema.validate_json(raw, root=raw)
assert_true(report.diagnostics().any(d => d.code() == @json.InvalidSchema))
}///|
test {
let raw = @json.parse("{\"enum\":[1,1.00]}").unwrap().lower().unwrap()
let report = @schema.validate_json(raw, root=raw)
assert_true(report.is_complete())
assert_eq(report.diagnostics()[0].path(), ["enum", "1"])
let distinct = @json.parse(
"{\"enum\":[9007199254740992,9007199254740993],\"minimum\":10,\"maximum\":1}",
)
.unwrap()
.lower()
.unwrap()
let report = @schema.validate_json(distinct, root=distinct)
assert_true(report.is_complete())
assert_eq(report.diagnostics().length(), 0)
}///|
test {
assert_true(@schema.check_pattern("(?<word>x)\\k<word>") is Ok(_))
assert_true(@schema.check_pattern("(?<=x)y") is Ok(_))
guard @schema.check_pattern("[z-a]") is Err(error) else {
fail("invalid character range")
}
assert_eq(error.code(), @json.InvalidSchema)
assert_true(error.offset() >= 0)
}///|
test {
let root = @json.parse(
"{\"x-vendor\":{\"schema\":{\"$ref\":\"https://schemas.example/document#/definitions/S\"}},\"definitions\":{\"S\":false}}",
)
.unwrap()
.lower()
.unwrap()
let embedded = root.get("x-vendor").unwrap().get("schema").unwrap()
let report = @schema.validate_json(
embedded,
root~,
path=["x-vendor", "schema"],
base=Some(
@reference.UriReference::parse("https://schemas.example/document").unwrap(),
),
)
assert_true(report.is_complete())
assert_eq(report.diagnostics().length(), 0)
}///|
test {
let raw = @json.parse(
"{\"$id\":\"http://x.test/root.json\",\"definitions\":{\"B\":{\"$id\":\"b.json\",\"definitions\":{\"X\":{\"type\":\"string\"}},\"properties\":{\"p\":{\"$ref\":\"#/definitions/X\"},\"e\":{\"$ref\":\"https://ext.test/e.json\"}}}}}",
)
.unwrap()
.lower()
.unwrap()
let open = @schema.validate_json(raw, root=raw)
assert_false(open.references_complete())
assert_eq(open.diagnostics()[0].code(), @json.UnavailableResource)
let external = @reference.Resource::new(
@reference.UriReference::parse("https://ext.test/e.json").unwrap(),
@json.Value::boolean(true),
schema_roots=[@reference.JsonPointer::parse("").unwrap()],
).unwrap()
let closed = @schema.validate_json(
raw,
root=raw,
resources=@reference.ResourceSet::new([external]).unwrap(),
)
assert_true(closed.is_complete())
assert_eq(closed.diagnostics().length(), 0)
assert_eq(closed.resolutions().length(), 2)
}pub(all) enum Keyword {
Id(UriReference)
Dialect(UriReference)
Ref(Reference)
Comment(String)
Title(String)
Description(String)
Default(Value)
ReadOnly(Bool)
WriteOnly(Bool)
Examples(Array[Value])
MultipleOf(PositiveNumber)
Maximum(Number)
ExclusiveMaximum(Number)
Minimum(Number)
ExclusiveMinimum(Number)
MaxLength(NonNegativeInteger)
MinLength(NonNegativeInteger)
Pattern(String)
AdditionalItems(Schema)
Items(Items)
MaxItems(NonNegativeInteger)
MinItems(NonNegativeInteger)
UniqueItems(Bool)
Contains(Schema)
MaxProperties(NonNegativeInteger)
MinProperties(NonNegativeInteger)
Required(Array[String])
AdditionalProperties(Schema)
Definitions(Array[(String, Schema)])
Properties(Array[(String, Schema)])
PatternProperties(Array[(String, Schema)])
Dependencies(Array[(String, Dependency)])
PropertyNames(Schema)
Const(Value)
Enum(Array[Value])
Type(TypeConstraint)
Format(String)
ContentMediaType(String)
ContentEncoding(String)
If(Schema)
Then(Schema)
Else(Schema)
AllOf(Array[Schema])
AnyOf(Array[Schema])
OneOf(Array[Schema])
Not(Schema)
} derive(Debug)fn Schema::from_keywords(keywords : Array[Keyword], additional_fields? : Array[(String, Value)], extensions? : Extensions, limits? : Limits) -> Result[Schema, Diagnostic]pub(all) enum SchemaKind {
BooleanSchema(Bool)
ObjectSchema(SchemaObject)
ReferenceSchema(ReferenceObject)
UnsupportedDialectSchema(UriReference, Value)
} derive(Debug)fn validate(schema : Schema, root~ : Value, path? : Array[String], base? : UriReference?, resources? : ResourceSet, max_nodes? : Int, max_edges? : Int, max_findings? : Int, max_comparison_work? : Int, limits? : Limits) -> Reportfn validate_in(schema : Schema, index~ : SchemaIndex, resource? : UriReference?, path? : Array[String], max_nodes? : Int, max_edges? : Int, max_findings? : Int, max_comparison_work? : Int, limits? : Limits) -> Reportfn validate_json(value : Value, root~ : Value, path? : Array[String], base? : UriReference?, resources? : ResourceSet, max_nodes? : Int, max_edges? : Int, max_findings? : Int, max_comparison_work? : Int, limits? : Limits) -> ReportInstall
Download zipPortable OpenRPC documents with exact JSON and source-preserving syntax