use super::json_schema::JsonSchema;
use super::spec_version::SpecVersion;
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct JsonSchemaSettings {
pub disallow_unknown_fields: bool,
pub spec_version: Option<SpecVersion>,
}
#[derive(Debug, Clone, Default)]
pub struct JsonSchemaSettingsBuilder {
disallow_unknown_fields: Option<bool>,
spec_version: Option<SpecVersion>,
}
impl JsonSchemaSettingsBuilder {
#[must_use]
pub fn disallow_unknown_fields(mut self, value: bool) -> Self {
self.disallow_unknown_fields = Some(value);
self
}
#[must_use]
pub fn spec_version(mut self, value: SpecVersion) -> Self {
self.spec_version = Some(value);
self
}
#[must_use]
pub fn build(self) -> JsonSchemaSettings {
JsonSchemaSettings {
disallow_unknown_fields: self.disallow_unknown_fields.unwrap_or(false),
spec_version: self.spec_version,
}
}
}
impl JsonSchemaSettings {
#[must_use]
pub fn builder() -> JsonSchemaSettingsBuilder {
JsonSchemaSettingsBuilder::default()
}
}
#[must_use]
pub fn resolved_spec_version(schema: &JsonSchema, settings: &JsonSchemaSettings) -> SpecVersion {
if let Some(v) = settings.spec_version {
return v;
}
schema
.schema
.as_deref()
.and_then(SpecVersion::from_schema_uri)
.unwrap_or(SpecVersion::Draft202012)
}
#[cfg(test)]
mod tests {
use super::{JsonSchemaSettings, resolved_spec_version};
use crate::json_schema::SpecVersion;
use crate::json_schema::json_schema::JsonSchema;
#[test]
fn builder_default_disallow_is_false() {
let settings: JsonSchemaSettings = JsonSchemaSettings::default();
assert!(!settings.disallow_unknown_fields);
}
#[test]
fn builder_disallow_unknown_fields() {
let settings: JsonSchemaSettings = JsonSchemaSettings::builder()
.disallow_unknown_fields(true)
.build();
assert!(settings.disallow_unknown_fields);
}
#[test]
fn builder_spec_version_explicit() {
let settings: JsonSchemaSettings = JsonSchemaSettings::builder()
.spec_version(SpecVersion::Draft07)
.build();
assert_eq!(settings.spec_version, Some(SpecVersion::Draft07));
}
#[test]
fn resolved_spec_version_uses_explicit_when_set() {
let schema: JsonSchema = JsonSchema {
schema: Some("https://json-schema.org/draft/2020-12/schema".to_string()),
..JsonSchema::default()
};
let settings: JsonSchemaSettings = JsonSchemaSettings::builder()
.spec_version(SpecVersion::Draft04)
.build();
let expected: SpecVersion = SpecVersion::Draft04;
let actual: SpecVersion = resolved_spec_version(&schema, &settings);
assert_eq!(expected, actual);
}
#[test]
fn resolved_spec_version_infers_from_schema_uri_when_not_set() {
let schema: JsonSchema = JsonSchema {
schema: Some("https://json-schema.org/draft/2020-12/schema".to_string()),
..JsonSchema::default()
};
let settings: JsonSchemaSettings = JsonSchemaSettings::default();
let expected: SpecVersion = SpecVersion::Draft202012;
let actual: SpecVersion = resolved_spec_version(&schema, &settings);
assert_eq!(expected, actual);
}
#[test]
fn resolved_spec_version_defaults_to_2020_12_when_schema_absent() {
let schema: JsonSchema = JsonSchema::default();
let settings: JsonSchemaSettings = JsonSchemaSettings::default();
let expected: SpecVersion = SpecVersion::Draft202012;
let actual: SpecVersion = resolved_spec_version(&schema, &settings);
assert_eq!(expected, actual);
}
#[test]
fn resolved_spec_version_defaults_to_2020_12_when_schema_unknown() {
let schema: JsonSchema = JsonSchema {
schema: Some("https://unknown.example/schema".to_string()),
..JsonSchema::default()
};
let settings: JsonSchemaSettings = JsonSchemaSettings::default();
let expected: SpecVersion = SpecVersion::Draft202012;
let actual: SpecVersion = resolved_spec_version(&schema, &settings);
assert_eq!(expected, actual);
}
}