use crate::{xotdata::Node, Span};
#[derive(Debug, Clone)]
pub enum ParseError {
UnclosedTag(Span),
InvalidCloseTag(String, String, Span),
UnclosedEntity(String, usize),
InvalidEntity(String, Span),
UnknownPrefix(String, Span),
DuplicateAttribute(String, Span),
UnsupportedVersion(String, Span),
#[deprecated(
since = "0.2.9",
note = "The value of the standalone declaration is now ignored"
)]
UnsupportedNotStandalone(Span),
DtdUnsupported(Span),
NoElementAtTopLevel(usize),
MultipleElementsAtTopLevel(Span),
TextAtTopLevel(Span),
DuplicateId(String, Span),
XmlParser(xmlparser::Error, usize),
}
impl ParseError {
pub fn span(&self) -> Span {
match self {
ParseError::UnclosedTag(span) => *span,
ParseError::InvalidCloseTag(_, _, span) => *span,
ParseError::UnclosedEntity(_, position) => Span::new(*position, *position),
ParseError::InvalidEntity(_, span) => *span,
ParseError::UnknownPrefix(_, span) => *span,
ParseError::DuplicateAttribute(_, span) => *span,
ParseError::UnsupportedVersion(_, span) => *span,
#[allow(deprecated)]
ParseError::UnsupportedNotStandalone(span) => *span,
ParseError::DtdUnsupported(span) => *span,
ParseError::NoElementAtTopLevel(position) => Span::new(*position, *position),
ParseError::MultipleElementsAtTopLevel(span) => *span,
ParseError::TextAtTopLevel(span) => *span,
ParseError::DuplicateId(_, span) => *span,
ParseError::XmlParser(_, position) => Span::new(*position, *position),
}
}
}
#[derive(Debug, Clone)]
pub enum Error {
NotDocument(Node),
InvalidOperation(String),
InvalidComment(String),
InvalidTarget(String),
NotElement(Node),
NodeError(indextree::NodeError),
MissingPrefix(String),
ProcessingInstructionGtInHtml(String),
NamespaceInProcessingInstruction,
Parse(ParseError),
UnknownPrefix(String),
IllegalAtTopLevel(Node),
TextAtTopLevel(Node),
NoElementAtTopLevel,
MultipleElementsAtTopLevel,
Io(String),
}
impl From<indextree::NodeError> for Error {
#[inline]
fn from(e: indextree::NodeError) -> Self {
Error::NodeError(e)
}
}
impl From<std::io::Error> for Error {
#[inline]
fn from(e: std::io::Error) -> Self {
Error::Io(e.to_string())
}
}
impl From<ParseError> for Error {
#[inline]
fn from(e: ParseError) -> Self {
Error::Parse(e)
}
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Error::NotDocument(_) => write!(f, "Not a document node"),
Error::InvalidOperation(s) => write!(f, "Invalid operation: {}", s),
Error::InvalidComment(s) => write!(f, "Invalid comment: {}", s),
Error::InvalidTarget(s) => write!(f, "Invalid target: {}", s),
Error::NotElement(_) => write!(f, "Not an element"),
Error::NodeError(e) => write!(f, "Node error: {}", e),
Error::MissingPrefix(_) => write!(f, "Missing prefix"),
Error::ProcessingInstructionGtInHtml(s) => {
write!(f, "Processing instruction with > in HTML: {}", s)
}
Error::NamespaceInProcessingInstruction => {
write!(f, "Namespace in processing instruction target")
}
Error::Parse(e) => write!(f, "Parse error: {:?}", e),
Error::UnknownPrefix(s) => write!(f, "Unknown prefix: {}", s),
Error::IllegalAtTopLevel(_) => write!(f, "Illegal content under document node (attribute, namespace or document node"),
Error::TextAtTopLevel(_) => write!(f, "Text node under document not. Not allowed in a well-formed document, but allowed in a fragment"),
Error::NoElementAtTopLevel => write!(f, "No element under document root. Not allowed in a well-formed document, but allowed in a fragment"),
Error::MultipleElementsAtTopLevel => write!(f, "Multiple elements under document root. Not allowed in a well-formed document, but allowed in a fragment"),
Error::Io(s) => write!(f, "IO error: {}", s),
}
}
}
impl std::fmt::Display for ParseError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
ParseError::UnclosedTag(_) => write!(f, "Unclosed tag"),
ParseError::InvalidCloseTag(s, s2, _) => write!(f, "Invalid close tag: {} {}", s, s2),
ParseError::UnclosedEntity(s, _) => write!(f, "Unclosed entity: {}", s),
ParseError::InvalidEntity(s, _) => write!(f, "Invalid entity: {}", s),
ParseError::UnknownPrefix(s, _) => write!(f, "Unknown prefix: {}", s),
ParseError::DuplicateAttribute(s, _) => write!(f, "Duplicate attribute: {}", s),
ParseError::UnsupportedVersion(s, _) => write!(f, "Unsupported version: {}", s),
#[allow(deprecated)]
ParseError::UnsupportedNotStandalone(_) => write!(f, "Unsupported standalone"),
ParseError::DtdUnsupported(_) => write!(f, "DTD is not supported"),
ParseError::NoElementAtTopLevel(_) => write!(f, "No element at top level"),
ParseError::MultipleElementsAtTopLevel(_) => {
write!(f, "Multiple elements at top level")
}
ParseError::TextAtTopLevel(_) => write!(f, "Text at top level"),
ParseError::DuplicateId(s, _) => write!(f, "Duplicate xml:id: {}", s),
ParseError::XmlParser(e, _position) => write!(f, "Parser error: {}", e),
}
}
}
impl std::error::Error for ParseError {
fn description(&self) -> &str {
"XML parsing error"
}
}
impl std::error::Error for Error {
fn description(&self) -> &str {
"Xot error"
}
}