use thiserror::Error;
pub type Result<T> = std::result::Result<T, FopError>;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Location {
pub line: usize,
pub column: usize,
}
impl Location {
pub fn new(line: usize, column: usize) -> Self {
Self { line, column }
}
pub fn unknown() -> Self {
Self { line: 0, column: 0 }
}
}
impl std::fmt::Display for Location {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.line == 0 && self.column == 0 {
write!(f, "unknown location")
} else {
write!(f, "line {}, column {}", self.line, self.column)
}
}
}
#[derive(Error, Debug)]
pub enum FopError {
#[error("XML parsing error at {location}: {message}")]
XmlErrorWithLocation {
message: String,
location: Location,
suggestion: Option<String>,
},
#[error("XML parsing error: {0}")]
XmlError(String),
#[error("Entity resolution error at {location}: {message}")]
EntityError { message: String, location: Location },
#[error("Invalid property value for {property}: {value}")]
InvalidPropertyValue { property: String, value: String },
#[error("Unknown property: {0}")]
UnknownProperty(String),
#[error("Invalid element: {0}")]
InvalidElement(String),
#[error("Invalid element nesting: {child} cannot be a child of {parent}")]
InvalidNesting { parent: String, child: String },
#[error("Missing required attribute {attribute} on element {element}")]
MissingAttribute { element: String, attribute: String },
#[error("Property validation error for {property}: {value} - {reason}")]
PropertyValidation {
property: String,
value: String,
reason: String,
},
#[error("I/O error: {0}")]
IoError(#[from] std::io::Error),
#[error("Parse error: {0}")]
ParseError(String),
#[error("{0}")]
Generic(String),
}