use std::{error::Error, fmt};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ProjectionError {
MissingContent {
document: String,
},
EmptySelection,
EmptySelector,
InvalidSelector,
InvalidReferenceProjection(&'static str),
TooManySelections {
maximum: usize,
},
UnknownSelector {
document: String,
selector: String,
},
AmbiguousSelector {
document: String,
selector: String,
candidates: Vec<SelectorCandidate>,
},
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SelectorCandidate {
pub path: String,
pub id: String,
}
impl fmt::Display for ProjectionError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::MissingContent { document } => {
write!(formatter, "document '{document}' has no available content")
}
Self::EmptySelection => formatter.write_str("at least one outline node is required"),
Self::EmptySelector => formatter.write_str("outline node must not be empty"),
Self::InvalidSelector => mant_protocol::InvalidContentSelector.fmt(formatter),
Self::InvalidReferenceProjection(reason) => formatter.write_str(reason),
Self::TooManySelections { maximum } => {
write!(formatter, "at most {maximum} outline nodes may be selected")
}
Self::UnknownSelector { document, selector } => write!(
formatter,
"document '{document}' has no outline node '{selector}'; inspect its entries outline for available selectors and diagnostics"
),
Self::AmbiguousSelector {
document,
selector,
candidates,
} => {
write!(
formatter,
"document '{document}' has multiple content owners for '{selector}': "
)?;
for (index, candidate) in candidates.iter().enumerate() {
if index > 0 {
formatter.write_str(", ")?;
}
write!(formatter, "{} ({})", candidate.path, candidate.id)?;
}
formatter.write_str("; select one by path or ID")
}
}
}
}
impl Error for ProjectionError {}