// Serialization back to JSON, following schemars' `Serialize` impls (fields
// that are `None`, `false` or empty are skipped as schemars does).
///|
fn put(
o : @collections.StrMap[@serde_json.Value],
key : String,
v : @serde_json.Value?,
) -> Unit {
if v is Some(v) {
o.set(key, v)
}
}
///|
fn str_value(s : String) -> @serde_json.Value {
String(s)
}
///|
fn arr_value(xs : Array[@serde_json.Value]) -> @serde_json.Value {
Array(xs)
}
///|
fn bool_value(b : Bool) -> @serde_json.Value {
Bool(b)
}
///|
fn f64_value(d : Double) -> @serde_json.Value {
@serde_json.Value::from_f64(d)
}
///|
fn u32_value(n : UInt) -> @serde_json.Value {
@serde_json.Value::from_u64(n.to_uint64())
}
///|
fn schemas_value(xs : Array[Schema]) -> @serde_json.Value {
Array(xs.map(x => x.to_value()))
}
///|
fn schema_map_value(m : @collections.StrMap[Schema]) -> @serde_json.Value {
Object(m.map(x => x.to_value()))
}
///|
/// Serialize to a JSON value.
pub fn Schema::to_value(self : Schema) -> @serde_json.Value {
match self {
Bool(b) => Bool(b)
Object(o) => o.to_value()
}
}
///|
/// Serialize to a JSON value.
pub fn SchemaObject::to_value(self : SchemaObject) -> @serde_json.Value {
let o = @collections.StrMap::new()
if self.metadata is Some(m) {
put(o, "$id", m.id.map(str_value))
put(o, "title", m.title.map(str_value))
put(o, "description", m.description.map(str_value))
put(o, "default", m.default)
if m.deprecated {
o.set("deprecated", Bool(true))
}
if m.read_only {
o.set("readOnly", Bool(true))
}
if m.write_only {
o.set("writeOnly", Bool(true))
}
if !m.examples.is_empty() {
o.set("examples", Array(m.examples))
}
}
put(
o,
"type",
self.instance_type.map(t => {
match t {
Single(t) => String(t.name())
Vec(ts) => Array(ts.map(t => str_value(t.name())))
}
}),
)
put(o, "format", self.format.map(str_value))
put(o, "enum", self.enum_values.map(arr_value))
put(o, "const", self.const_value)
if self.subschemas is Some(s) {
put(o, "allOf", s.all_of.map(schemas_value))
put(o, "anyOf", s.any_of.map(schemas_value))
put(o, "oneOf", s.one_of.map(schemas_value))
put(o, "not", s.not.map(x => x.to_value()))
put(o, "if", s.if_schema.map(x => x.to_value()))
put(o, "then", s.then_schema.map(x => x.to_value()))
put(o, "else", s.else_schema.map(x => x.to_value()))
}
if self.number is Some(n) {
put(o, "multipleOf", n.multiple_of.map(f64_value))
put(o, "maximum", n.maximum.map(f64_value))
put(o, "exclusiveMaximum", n.exclusive_maximum.map(f64_value))
put(o, "minimum", n.minimum.map(f64_value))
put(o, "exclusiveMinimum", n.exclusive_minimum.map(f64_value))
}
if self.string is Some(s) {
put(o, "maxLength", s.max_length.map(u32_value))
put(o, "minLength", s.min_length.map(u32_value))
put(o, "pattern", s.pattern.map(str_value))
}
if self.array is Some(a) {
put(
o,
"items",
a.items.map(i => {
match i {
Single(s) => s.to_value()
Vec(xs) => schemas_value(xs)
}
}),
)
put(o, "additionalItems", a.additional_items.map(x => x.to_value()))
put(o, "maxItems", a.max_items.map(u32_value))
put(o, "minItems", a.min_items.map(u32_value))
put(o, "uniqueItems", a.unique_items.map(bool_value))
put(o, "contains", a.contains.map(x => x.to_value()))
}
if self.object is Some(ov) {
put(o, "maxProperties", ov.max_properties.map(u32_value))
put(o, "minProperties", ov.min_properties.map(u32_value))
if !ov.required.is_empty() {
o.set("required", Array(ov.required.to_array().map(str_value)))
}
if !ov.properties.is_empty() {
o.set("properties", schema_map_value(ov.properties))
}
if !ov.pattern_properties.is_empty() {
o.set("patternProperties", schema_map_value(ov.pattern_properties))
}
put(
o,
"additionalProperties",
ov.additional_properties.map(x => x.to_value()),
)
put(o, "propertyNames", ov.property_names.map(x => x.to_value()))
}
put(o, "$ref", self.reference.map(str_value))
for k, v in self.extensions {
o.set(k, v)
}
Object(o)
}
///|
/// Serialize to a JSON value.
pub fn RootSchema::to_value(self : RootSchema) -> @serde_json.Value {
guard self.schema.to_value() is Object(o) else { abort("unreachable") }
let o = o.copy()
put(o, "$schema", self.meta_schema.map(str_value))
if !self.definitions.is_empty() {
o.set("definitions", schema_map_value(self.definitions))
}
Object(o)
}