use crate::grammar::GrammarError;
use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SchemaError {
NotJson(String),
NotAnObject { at: String, kind: &'static str },
UnsupportedKeyword {
keyword: String,
at: String,
why: &'static str,
},
UnsupportedPattern { pattern: String, why: String },
UnsupportedFormat { format: String, at: String },
UnknownType { at: String, found: String },
UnsupportedRef { reference: String },
RefNotFound { reference: String, token: String },
RefCollision { pointer: String },
BadValue {
keyword: String,
at: String,
why: String,
},
RootDisplaced { got: String },
Emitted(GrammarError),
Internal(&'static str),
}
impl fmt::Display for SchemaError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SchemaError::NotJson(msg) => write!(f, "JSON schema is not valid JSON: {msg}"),
SchemaError::NotAnObject { at, kind } => write!(
f,
"JSON schema at {at} is a {kind}, not an object; boolean schemas are not supported"
),
SchemaError::UnsupportedKeyword { keyword, at, why } => write!(
f,
"JSON schema keyword {keyword:?} at {at} is not supported ({why}); it would be \
ignored, and the grammar would then accept documents the schema rejects"
),
SchemaError::UnsupportedPattern { pattern, why } => write!(
f,
"JSON schema \"pattern\" {pattern:?} cannot be compiled to a grammar: {why}"
),
SchemaError::UnsupportedFormat { format, at } => write!(
f,
"JSON schema format {format:?} at {at} is not supported; only \"date\", \"time\", \
\"date-time\" and \"uuid\" (or \"uuid1\"..\"uuid5\") have grammars"
),
SchemaError::UnknownType { at, found } => {
write!(
f,
"JSON schema \"type\" at {at} is {found}, which names no JSON type"
)
}
SchemaError::UnsupportedRef { reference } => write!(
f,
"JSON schema $ref {reference:?} is not supported; only same-document refs of the \
form \"#/...\" are resolved, and nothing is fetched over the network"
),
SchemaError::RefNotFound { reference, token } => write!(
f,
"JSON schema $ref {reference:?} does not resolve: {token:?} is not in the document"
),
SchemaError::RefCollision { pointer } => write!(
f,
"two schemas compiled into one grammar both define {pointer:?} and disagree about \
what it is; rename one of them"
),
SchemaError::BadValue { keyword, at, why } => {
write!(
f,
"JSON schema keyword {keyword:?} at {at} is invalid: {why}"
)
}
SchemaError::RootDisplaced { got } => write!(
f,
"the top-level schema compiled to rule {got:?} rather than \"root\", so the \
grammar would start from a subschema; rename the colliding property"
),
SchemaError::Internal(what) => {
write!(f, "internal error in the JSON schema converter: {what}")
}
SchemaError::Emitted(e) => write!(
f,
"the grammar generated from this schema does not parse, which is a bug in the \
converter: {e}"
),
}
}
}
impl std::error::Error for SchemaError {}
impl From<GrammarError> for SchemaError {
fn from(e: GrammarError) -> Self {
SchemaError::Emitted(e)
}
}
pub(super) fn at(name: &str) -> String {
if name.is_empty() {
"the top level".to_string()
} else {
format!("{name:?}")
}
}