1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//! Error types for arena operations.
//!
//! DOM spec defines hierarchy errors as throwable; in Rust we return
//! `Result<_, DomError>` from any operation that can fail. Tests exercise
//! every error variant.
use crate::NodeId;
use crate::node::NodeType;
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum DomError {
/// NodeId doesn't exist in this arena (may have been freed).
InvalidNode(NodeId),
/// Would create a cycle: attempted to insert a node into its own
/// subtree (spec `HierarchyRequestError`).
HierarchyRequest,
/// `insert_before` / `replace_child` reference child does not belong
/// to the target parent (spec `NotFoundError`).
NotFound,
/// Operation requires a specific node type — e.g. `set_node_value`
/// only works on Text and Comment nodes, not Element / Fragment.
WrongNodeType {
expected: &'static str,
got: NodeType,
},
/// A byte offset supplied to a text-editing operation either
/// overshoots the node's data length or falls inside a multi-byte
/// UTF-8 codepoint (not on a `char` boundary). Callers should
/// derive offsets from `Position` or grapheme walks to avoid this.
InvalidOffset { node: NodeId, offset: usize },
/// The operation is not valid in the object's current state (spec
/// `InvalidStateError`) — e.g. dispatching an `Event` that is
/// already being dispatched.
InvalidState(&'static str),
/// An argument has the wrong kind — the web's `TypeError` (Web IDL
/// §3.14.1 simple exception, not a `DOMException`), named without
/// the `Error` suffix like the `DOMException` names above
/// (`InvalidStateError` → `InvalidState`). E.g.
/// `form.requestSubmit(submitter)` with a submitter that is not a
/// submit button.
Type(&'static str),
/// A string argument does not parse (spec `SyntaxError`) — e.g.
/// `el.contentEditable = "yes"`.
Syntax(&'static str),
}
impl std::fmt::Display for DomError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
DomError::InvalidNode(id) => write!(f, "invalid node id: {id:?}"),
DomError::HierarchyRequest => write!(f, "hierarchy request error: would create cycle"),
DomError::NotFound => write!(f, "reference node not found in target"),
DomError::WrongNodeType { expected, got } => {
write!(f, "wrong node type: expected {expected}, got {got:?}")
}
DomError::InvalidOffset { node, offset } => {
write!(
f,
"invalid byte offset {offset} for node {node:?} (out of range or mid-codepoint)"
)
}
DomError::InvalidState(what) => write!(f, "invalid state: {what}"),
DomError::Type(what) => write!(f, "type error: {what}"),
DomError::Syntax(what) => write!(f, "syntax error: {what}"),
}
}
}
impl std::error::Error for DomError {}
pub type Result<T> = std::result::Result<T, DomError>;