#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NodeError {
Stale,
NotAnElement,
NotAContainer,
NotAChild,
NotText,
NotRemovable,
RootElementExists,
WouldCycle,
InvalidName,
InvalidText,
}
impl NodeError {
#[cfg(test)]
const ALL: [Self; 10] = [
Self::Stale,
Self::NotAnElement,
Self::NotAContainer,
Self::NotAChild,
Self::NotText,
Self::NotRemovable,
Self::RootElementExists,
Self::WouldCycle,
Self::InvalidName,
Self::InvalidText,
];
const fn message(self) -> &'static str {
const MESSAGES: [&str; 10] = [
"the node has been removed",
"the node is not an element",
"the node cannot have children",
"an attribute or namespace node cannot be moved or detached",
"the node is not a text node",
"the document root cannot be removed, moved or detached",
"the document already has a root element",
"the move would place a node inside its own subtree",
"the name is not an NCName",
"the text cannot be written as XML",
];
MESSAGES[self as usize]
}
}
impl core::fmt::Display for NodeError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(self.message())
}
}
#[cfg(feature = "std")]
impl std::error::Error for NodeError {}
#[cfg(test)]
mod error_tests {
use super::NodeError;
#[test]
fn every_error_has_its_own_message() {
let messages: alloc::vec::Vec<&str> =
NodeError::ALL.iter().map(|e| e.message()).collect();
for (i, m) in messages.iter().enumerate() {
assert!(!m.is_empty());
assert!(
!messages[..i].contains(m),
"{:?} shares a message with an earlier variant",
NodeError::ALL[i]
);
}
assert_eq!(NodeError::NotText.message(), "the node is not a text node");
assert_eq!(
NodeError::InvalidText.message(),
"the text cannot be written as XML"
);
}
}