1use crate::{xotdata::Node, Span};
2
3#[derive(Debug, Clone)]
5pub enum ParseError {
6 UnclosedTag(Span),
8 InvalidCloseTag(String, String, Span),
10 UnclosedEntity(String, usize),
13 InvalidEntity(String, Span),
16 UnknownPrefix(String, Span),
18 DuplicateAttribute(String, Span),
20 UnsupportedVersion(String, Span),
22 #[deprecated(
25 since = "0.2.9",
26 note = "The value of the standalone declaration is now ignored"
27 )]
28 UnsupportedNotStandalone(Span),
29 DtdUnsupported(Span),
31 NoElementAtTopLevel(usize),
33 MultipleElementsAtTopLevel(Span),
35 TextAtTopLevel(Span),
37 DuplicateId(String, Span),
39 XmlParser(xmlparser::Error, usize),
41}
42
43impl ParseError {
44 pub fn span(&self) -> Span {
46 match self {
47 ParseError::UnclosedTag(span) => *span,
48 ParseError::InvalidCloseTag(_, _, span) => *span,
49 ParseError::UnclosedEntity(_, position) => Span::new(*position, *position),
50 ParseError::InvalidEntity(_, span) => *span,
51 ParseError::UnknownPrefix(_, span) => *span,
52 ParseError::DuplicateAttribute(_, span) => *span,
53 ParseError::UnsupportedVersion(_, span) => *span,
54 #[allow(deprecated)]
55 ParseError::UnsupportedNotStandalone(span) => *span,
56 ParseError::DtdUnsupported(span) => *span,
57 ParseError::NoElementAtTopLevel(position) => Span::new(*position, *position),
58 ParseError::MultipleElementsAtTopLevel(span) => *span,
59 ParseError::TextAtTopLevel(span) => *span,
60 ParseError::DuplicateId(_, span) => *span,
61 ParseError::XmlParser(_, position) => Span::new(*position, *position),
62 }
63 }
64}
65
66#[derive(Debug, Clone)]
68pub enum Error {
69 NotDocument(Node),
72
73 InvalidOperation(String),
78
79 InvalidComment(String),
82 InvalidTarget(String),
85 NotElement(Node),
87 NodeError(indextree::NodeError),
89
90 MissingPrefix(String),
96 ProcessingInstructionGtInHtml(String),
98
99 NamespaceInProcessingInstruction,
102
103 Parse(ParseError),
105
106 UnknownPrefix(String),
111
112 IllegalAtTopLevel(Node),
115 TextAtTopLevel(Node),
118 NoElementAtTopLevel,
120 MultipleElementsAtTopLevel,
122
123 Io(String),
128}
129
130impl From<indextree::NodeError> for Error {
131 #[inline]
132 fn from(e: indextree::NodeError) -> Self {
133 Error::NodeError(e)
134 }
135}
136
137impl From<std::io::Error> for Error {
138 #[inline]
139 fn from(e: std::io::Error) -> Self {
140 Error::Io(e.to_string())
141 }
142}
143
144impl From<ParseError> for Error {
145 #[inline]
146 fn from(e: ParseError) -> Self {
147 Error::Parse(e)
148 }
149}
150
151impl std::fmt::Display for Error {
152 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
153 match self {
154 Error::NotDocument(_) => write!(f, "Not a document node"),
155 Error::InvalidOperation(s) => write!(f, "Invalid operation: {}", s),
156 Error::InvalidComment(s) => write!(f, "Invalid comment: {}", s),
157 Error::InvalidTarget(s) => write!(f, "Invalid target: {}", s),
158 Error::NotElement(_) => write!(f, "Not an element"),
159 Error::NodeError(e) => write!(f, "Node error: {}", e),
160 Error::MissingPrefix(_) => write!(f, "Missing prefix"),
161 Error::ProcessingInstructionGtInHtml(s) => {
162 write!(f, "Processing instruction with > in HTML: {}", s)
163 }
164 Error::NamespaceInProcessingInstruction => {
165 write!(f, "Namespace in processing instruction target")
166 }
167 Error::Parse(e) => write!(f, "Parse error: {:?}", e),
168 Error::UnknownPrefix(s) => write!(f, "Unknown prefix: {}", s),
169 Error::IllegalAtTopLevel(_) => write!(f, "Illegal content under document node (attribute, namespace or document node"),
170 Error::TextAtTopLevel(_) => write!(f, "Text node under document not. Not allowed in a well-formed document, but allowed in a fragment"),
171 Error::NoElementAtTopLevel => write!(f, "No element under document root. Not allowed in a well-formed document, but allowed in a fragment"),
172 Error::MultipleElementsAtTopLevel => write!(f, "Multiple elements under document root. Not allowed in a well-formed document, but allowed in a fragment"),
173 Error::Io(s) => write!(f, "IO error: {}", s),
174 }
175 }
176}
177
178impl std::fmt::Display for ParseError {
179 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
180 match self {
181 ParseError::UnclosedTag(_) => write!(f, "Unclosed tag"),
182 ParseError::InvalidCloseTag(s, s2, _) => write!(f, "Invalid close tag: {} {}", s, s2),
183 ParseError::UnclosedEntity(s, _) => write!(f, "Unclosed entity: {}", s),
184 ParseError::InvalidEntity(s, _) => write!(f, "Invalid entity: {}", s),
185 ParseError::UnknownPrefix(s, _) => write!(f, "Unknown prefix: {}", s),
186 ParseError::DuplicateAttribute(s, _) => write!(f, "Duplicate attribute: {}", s),
187 ParseError::UnsupportedVersion(s, _) => write!(f, "Unsupported version: {}", s),
188 #[allow(deprecated)]
189 ParseError::UnsupportedNotStandalone(_) => write!(f, "Unsupported standalone"),
190 ParseError::DtdUnsupported(_) => write!(f, "DTD is not supported"),
191 ParseError::NoElementAtTopLevel(_) => write!(f, "No element at top level"),
192 ParseError::MultipleElementsAtTopLevel(_) => {
193 write!(f, "Multiple elements at top level")
194 }
195 ParseError::TextAtTopLevel(_) => write!(f, "Text at top level"),
196 ParseError::DuplicateId(s, _) => write!(f, "Duplicate xml:id: {}", s),
197 ParseError::XmlParser(e, _position) => write!(f, "Parser error: {}", e),
198 }
199 }
200}
201
202impl std::error::Error for ParseError {
203 fn description(&self) -> &str {
204 "XML parsing error"
205 }
206}
207
208impl std::error::Error for Error {
209 fn description(&self) -> &str {
210 "Xot error"
211 }
212}