1#![no_std]
17#![forbid(unsafe_code)]
18#![warn(missing_docs)]
19#![warn(missing_copy_implementations)]
20#![warn(missing_debug_implementations)]
21
22extern crate alloc;
23
24#[cfg(feature = "std")]
25extern crate std;
26
27use core::cmp::Ordering;
28use core::fmt;
29use core::hash::{Hash, Hasher};
30use core::num::NonZeroU32;
31use core::ops::Range;
32
33use alloc::vec::Vec;
34
35mod parse;
36mod tokenizer;
37
38#[cfg(test)]
39mod tokenizer_tests;
40
41pub use crate::parse::*;
42
43pub const NS_XML_URI: &str = "http://www.w3.org/XML/1998/namespace";
45const NS_XML_PREFIX: &str = "xml";
47
48pub const NS_XMLNS_URI: &str = "http://www.w3.org/2000/xmlns/";
50const XMLNS: &str = "xmlns";
52
53#[allow(missing_docs)]
57#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
58pub struct TextPos {
59 pub row: u32,
60 pub col: u32,
61}
62
63impl TextPos {
64 pub fn new(row: u32, col: u32) -> TextPos {
66 TextPos { row, col }
67 }
68}
69
70impl fmt::Display for TextPos {
71 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72 write!(f, "{}:{}", self.row, self.col)
73 }
74}
75
76pub struct Document<'input> {
99 text: &'input str,
103 nodes: Vec<NodeData<'input>>,
104 attributes: Vec<AttributeData<'input>>,
105 namespaces: Namespaces<'input>,
106}
107
108impl<'input> Document<'input> {
109 #[inline]
119 pub fn root<'a>(&'a self) -> Node<'a, 'input> {
120 Node {
121 id: NodeId::new(0),
122 d: &self.nodes[0],
123 doc: self,
124 }
125 }
126
127 #[inline]
147 pub fn get_node<'a>(&'a self, id: NodeId) -> Option<Node<'a, 'input>> {
148 self.nodes.get(id.get_usize()).map(|data| Node {
149 id,
150 d: data,
151 doc: self,
152 })
153 }
154
155 #[inline]
168 pub fn root_element<'a>(&'a self) -> Node<'a, 'input> {
169 self.root()
171 .first_element_child()
172 .expect("XML documents must contain a root element")
173 }
174
175 #[inline]
179 pub fn descendants(&self) -> Descendants<'_, 'input> {
180 self.root().descendants()
181 }
182
183 #[inline]
201 pub fn text_pos_at(&self, pos: usize) -> TextPos {
202 tokenizer::Stream::new(self.text).gen_text_pos_from(pos)
203 }
204
205 #[inline]
217 pub fn input_text(&self) -> &'input str {
218 self.text
219 }
220}
221
222impl<'input> fmt::Debug for Document<'input> {
223 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
224 if !self.root().has_children() {
225 return write!(f, "Document []");
226 }
227
228 macro_rules! writeln_indented {
229 ($depth:expr, $f:expr, $fmt:expr) => {
230 for _ in 0..$depth { write!($f, " ")?; }
231 writeln!($f, $fmt)?;
232 };
233 ($depth:expr, $f:expr, $fmt:expr, $($arg:tt)*) => {
234 for _ in 0..$depth { write!($f, " ")?; }
235 writeln!($f, $fmt, $($arg)*)?;
236 };
237 }
238
239 fn print_into_iter<
240 T: fmt::Debug,
241 E: ExactSizeIterator<Item = T>,
242 I: IntoIterator<Item = T, IntoIter = E>,
243 >(
244 prefix: &str,
245 data: I,
246 depth: usize,
247 f: &mut fmt::Formatter,
248 ) -> Result<(), fmt::Error> {
249 let data = data.into_iter();
250 if data.len() == 0 {
251 return Ok(());
252 }
253
254 writeln_indented!(depth, f, "{}: [", prefix);
255 for v in data {
256 writeln_indented!(depth + 1, f, "{:?}", v);
257 }
258 writeln_indented!(depth, f, "]");
259
260 Ok(())
261 }
262
263 fn print_children(
264 parent: Node,
265 depth: usize,
266 f: &mut fmt::Formatter,
267 ) -> Result<(), fmt::Error> {
268 for child in parent.children() {
269 if child.is_element() {
270 writeln_indented!(depth, f, "Element {{");
271 writeln_indented!(depth, f, " tag_name: {:?}", child.tag_name());
272 print_into_iter("attributes", child.attributes(), depth + 1, f)?;
273 print_into_iter("namespaces", child.namespaces(), depth + 1, f)?;
274
275 if child.has_children() {
276 writeln_indented!(depth, f, " children: [");
277 print_children(child, depth + 2, f)?;
278 writeln_indented!(depth, f, " ]");
279 }
280
281 writeln_indented!(depth, f, "}}");
282 } else {
283 writeln_indented!(depth, f, "{:?}", child);
284 }
285 }
286
287 Ok(())
288 }
289
290 writeln!(f, "Document [")?;
291 print_children(self.root(), 1, f)?;
292 writeln!(f, "]")?;
293
294 Ok(())
295 }
296}
297
298#[derive(Clone, Copy, PartialEq, Eq, Debug)]
300pub enum NodeType {
301 Root,
303 Element,
307 PI,
309 Comment,
311 Text,
313}
314
315#[derive(Clone, Copy, PartialEq, Eq, Debug)]
317#[allow(missing_docs)]
318pub struct PI<'input> {
319 pub target: &'input str,
320 pub value: Option<&'input str>,
321}
322
323#[derive(Clone, Copy, Debug)]
327struct ShortRange {
328 start: u32,
329 end: u32,
330}
331
332impl From<Range<usize>> for ShortRange {
333 #[inline]
334 fn from(range: Range<usize>) -> Self {
335 debug_assert!(range.start <= u32::MAX as usize);
336 debug_assert!(range.end <= u32::MAX as usize);
337 ShortRange::new(range.start as u32, range.end as u32)
338 }
339}
340
341impl ShortRange {
342 #[inline]
343 fn new(start: u32, end: u32) -> Self {
344 ShortRange { start, end }
345 }
346
347 #[inline]
348 fn to_urange(self) -> Range<usize> {
349 self.start as usize..self.end as usize
350 }
351}
352
353#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
362pub struct NodeId(NonZeroU32);
363
364impl NodeId {
365 #[inline]
367 pub fn new(id: u32) -> Self {
368 debug_assert!(id < u32::MAX);
369
370 NodeId(NonZeroU32::new(id + 1).unwrap())
372 }
373
374 #[inline]
376 pub fn get(self) -> u32 {
377 self.0.get() - 1
378 }
379
380 #[inline]
382 pub fn get_usize(self) -> usize {
383 self.get() as usize
384 }
385}
386
387impl From<u32> for NodeId {
388 #[inline]
389 fn from(id: u32) -> Self {
390 NodeId::new(id)
391 }
392}
393
394impl From<usize> for NodeId {
395 #[inline]
396 fn from(id: usize) -> Self {
397 debug_assert!(id <= u32::MAX as usize);
399 NodeId::new(id as u32)
400 }
401}
402
403#[derive(Debug)]
404enum NodeKind<'input> {
405 Root,
406 Element {
407 tag_name: ExpandedNameIndexed<'input>,
408 attributes: ShortRange,
409 namespaces: ShortRange,
410 },
411 PI(PI<'input>),
412 Comment(StringStorage<'input>),
413 Text(StringStorage<'input>),
414}
415
416#[derive(Debug)]
417struct NodeData<'input> {
418 parent: Option<NodeId>,
419 prev_sibling: Option<NodeId>,
420 next_subtree: Option<NodeId>,
421 last_child: Option<NodeId>,
422 kind: NodeKind<'input>,
423 #[cfg(feature = "positions")]
424 range: Range<usize>,
425}
426
427#[cfg(target_has_atomic = "ptr")]
428type OwnedSharedString = alloc::sync::Arc<str>;
429
430#[cfg(not(target_has_atomic = "ptr"))]
431type OwnedSharedString = alloc::rc::Rc<str>;
432
433#[derive(Clone, Eq, Debug)]
444pub enum StringStorage<'input> {
445 Borrowed(&'input str),
447
448 Owned(OwnedSharedString),
450}
451
452impl StringStorage<'_> {
453 pub fn new_owned(s: &str) -> Self {
455 StringStorage::Owned(s.into())
456 }
457
458 pub fn as_str(&self) -> &str {
460 match self {
461 StringStorage::Borrowed(s) => s,
462 StringStorage::Owned(s) => s,
463 }
464 }
465}
466
467impl PartialEq for StringStorage<'_> {
468 fn eq(&self, other: &Self) -> bool {
469 self.as_str() == other.as_str()
470 }
471}
472
473impl core::fmt::Display for StringStorage<'_> {
474 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
475 write!(f, "{}", self.as_str())
476 }
477}
478
479impl core::ops::Deref for StringStorage<'_> {
480 type Target = str;
481
482 fn deref(&self) -> &Self::Target {
483 self.as_str()
484 }
485}
486
487#[derive(Clone, Debug)]
488struct AttributeData<'input> {
489 name: ExpandedNameIndexed<'input>,
490 value: StringStorage<'input>,
491 #[cfg(feature = "positions")]
492 range: Range<usize>,
493 #[cfg(feature = "positions")]
494 qname_len: u16,
495 #[cfg(feature = "positions")]
496 eq_len: u8, }
498
499#[derive(Copy, Clone)]
501pub struct Attribute<'a, 'input: 'a> {
502 doc: &'a Document<'input>,
503 data: &'a AttributeData<'input>,
504}
505
506impl<'a, 'input> Attribute<'a, 'input> {
507 #[inline]
520 pub fn namespace(&self) -> Option<&'a str> {
521 self.data.name.namespace(self.doc).map(Namespace::uri)
522 }
523
524 #[inline]
537 pub fn name(&self) -> &'input str {
538 self.data.name.local_name
539 }
540
541 #[inline]
554 pub fn value(&self) -> &'a str {
555 &self.data.value
556 }
557
558 #[inline]
562 pub fn value_storage(&self) -> &StringStorage<'input> {
563 &self.data.value
564 }
565
566 #[deprecated(note="replaced by `range`")]
577 #[cfg(feature = "positions")]
578 #[inline]
579 pub fn position(&self) -> usize {
580 self.data.range.start
581 }
582
583 #[cfg(feature = "positions")]
590 #[inline]
591 pub fn range(&self) -> Range<usize> {
592 self.data.range.clone()
593 }
594
595 #[cfg(feature = "positions")]
605 #[inline]
606 pub fn range_qname(&self) -> Range<usize> {
607 let end = self.data.range.start + usize::from(self.data.qname_len);
608 self.data.range.start..end
609 }
610
611 #[cfg(feature = "positions")]
624 #[inline]
625 pub fn range_value(&self) -> Range<usize> {
626 let start = self.data.range.start + usize::from(self.data.qname_len) + usize::from(self.data.eq_len) + 1;
628 let end = self.data.range.end - 1;
629 start..end
630 }
631}
632
633impl PartialEq for Attribute<'_, '_> {
634 #[inline]
635 fn eq(&self, other: &Attribute<'_, '_>) -> bool {
636 self.data.name.as_expanded_name(self.doc) == other.data.name.as_expanded_name(other.doc)
637 && self.data.value == other.data.value
638 }
639}
640
641impl fmt::Debug for Attribute<'_, '_> {
642 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
643 write!(
644 f,
645 "Attribute {{ name: {:?}, value: {:?} }}",
646 self.data.name.as_expanded_name(self.doc),
647 self.data.value
648 )
649 }
650}
651
652#[derive(Clone, PartialEq, Eq, Debug)]
656pub struct Namespace<'input> {
657 name: Option<&'input str>,
658 uri: StringStorage<'input>,
659}
660
661impl<'input> Namespace<'input> {
662 #[inline]
682 pub fn name(&self) -> Option<&'input str> {
683 self.name
684 }
685
686 #[inline]
698 pub fn uri(&self) -> &str {
699 self.uri.as_ref()
700 }
701}
702
703#[derive(Default)]
704struct Namespaces<'input> {
705 values: Vec<Namespace<'input>>,
707 tree_order: Vec<NamespaceIdx>,
709 sorted_order: Vec<NamespaceIdx>,
711}
712
713impl<'input> Namespaces<'input> {
714 fn push_ns(
715 &mut self,
716 name: Option<&'input str>,
717 uri: StringStorage<'input>,
718 ) -> Result<(), Error> {
719 debug_assert_ne!(name, Some(""));
720
721 let idx = match self.sorted_order.binary_search_by(|idx| {
722 let value = &self.values[idx.0 as usize];
723
724 (value.name, value.uri.as_ref()).cmp(&(name, uri.as_str()))
725 }) {
726 Ok(sorted_idx) => self.sorted_order[sorted_idx],
727 Err(sorted_idx) => {
728 if self.values.len() > u16::MAX as usize {
729 return Err(Error::NamespacesLimitReached);
730 }
731 let idx = NamespaceIdx(self.values.len() as u16);
732 self.values.push(Namespace { name, uri });
733 self.sorted_order.insert(sorted_idx, idx);
734 idx
735 }
736 };
737
738 self.tree_order.push(idx);
739
740 Ok(())
741 }
742
743 #[inline]
744 fn push_ref(&mut self, tree_idx: usize) {
745 let idx = self.tree_order[tree_idx];
746 self.tree_order.push(idx);
747 }
748
749 #[inline]
750 fn exists(&self, start: usize, prefix: Option<&str>) -> bool {
751 self.tree_order[start..]
752 .iter()
753 .any(|idx| self.values[idx.0 as usize].name == prefix)
754 }
755
756 fn shrink_to_fit(&mut self) {
757 self.values.shrink_to_fit();
758 self.tree_order.shrink_to_fit();
759 self.sorted_order = Vec::new();
761 }
762
763 #[inline]
764 fn get(&self, idx: NamespaceIdx) -> &Namespace<'input> {
765 &self.values[idx.0 as usize]
766 }
767}
768
769#[derive(Clone, Copy, Debug)]
770#[repr(transparent)]
771struct NamespaceIdx(u16);
772
773#[derive(Clone, Copy, Debug)]
774struct ExpandedNameIndexed<'input> {
775 namespace_idx: Option<NamespaceIdx>,
776 local_name: &'input str,
777}
778
779impl<'input> ExpandedNameIndexed<'input> {
780 #[inline]
781 fn namespace<'a>(&self, doc: &'a Document<'input>) -> Option<&'a Namespace<'input>> {
782 self.namespace_idx.map(|idx| doc.namespaces.get(idx))
783 }
784
785 #[inline]
786 fn as_expanded_name<'a>(&self, doc: &'a Document<'input>) -> ExpandedName<'a, 'input> {
787 ExpandedName {
788 uri: self.namespace(doc).map(Namespace::uri),
789 name: self.local_name,
790 }
791 }
792}
793
794#[derive(Clone, Copy, PartialEq, Eq)]
798pub struct ExpandedName<'a, 'b> {
799 uri: Option<&'a str>,
800 name: &'b str,
801}
802
803impl<'a, 'b> ExpandedName<'a, 'b> {
804 #[inline]
814 pub fn namespace(&self) -> Option<&'a str> {
815 self.uri
816 }
817
818 #[inline]
828 pub fn name(&self) -> &'b str {
829 self.name
830 }
831}
832
833impl ExpandedName<'static, 'static> {
834 pub const fn from_static(uri: &'static str, name: &'static str) -> Self {
844 Self {
845 uri: Some(uri),
846 name,
847 }
848 }
849}
850
851impl fmt::Debug for ExpandedName<'_, '_> {
852 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
853 match self.namespace() {
854 Some(ns) => write!(f, "{{{}}}{}", ns, self.name),
855 None => write!(f, "{}", self.name),
856 }
857 }
858}
859
860impl<'a, 'b> From<&'b str> for ExpandedName<'a, 'b> {
861 #[inline]
862 fn from(v: &'b str) -> Self {
863 ExpandedName { uri: None, name: v }
864 }
865}
866
867impl<'a, 'b> From<(&'a str, &'b str)> for ExpandedName<'a, 'b> {
868 #[inline]
869 fn from(v: (&'a str, &'b str)) -> Self {
870 ExpandedName {
871 uri: Some(v.0),
872 name: v.1,
873 }
874 }
875}
876
877#[derive(Clone, Copy)]
901pub struct Node<'a, 'input: 'a> {
902 id: NodeId,
904
905 doc: &'a Document<'input>,
907
908 d: &'a NodeData<'input>,
910}
911
912impl Eq for Node<'_, '_> {}
913
914impl PartialEq for Node<'_, '_> {
915 #[inline]
916 fn eq(&self, other: &Self) -> bool {
917 (self.id, self.doc as *const _) == (other.id, other.doc as *const _)
918 }
919}
920
921impl PartialOrd for Node<'_, '_> {
922 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
923 Some(self.cmp(other))
924 }
925}
926
927impl Ord for Node<'_, '_> {
928 fn cmp(&self, other: &Self) -> Ordering {
929 (self.id.0, self.doc as *const _).cmp(&(other.id.0, other.doc as *const _))
930 }
931}
932
933impl Hash for Node<'_, '_> {
934 fn hash<H: Hasher>(&self, state: &mut H) {
935 self.id.0.hash(state);
936 (self.doc as *const Document).hash(state);
937 (self.d as *const NodeData).hash(state);
938 }
939}
940
941impl<'a, 'input: 'a> Node<'a, 'input> {
942 #[inline]
944 pub fn node_type(&self) -> NodeType {
945 match self.d.kind {
946 NodeKind::Root => NodeType::Root,
947 NodeKind::Element { .. } => NodeType::Element,
948 NodeKind::PI { .. } => NodeType::PI,
949 NodeKind::Comment(_) => NodeType::Comment,
950 NodeKind::Text(_) => NodeType::Text,
951 }
952 }
953
954 #[inline]
956 pub fn is_root(&self) -> bool {
957 self.node_type() == NodeType::Root
958 }
959
960 #[inline]
962 pub fn is_element(&self) -> bool {
963 self.node_type() == NodeType::Element
964 }
965
966 #[inline]
968 pub fn is_pi(&self) -> bool {
969 self.node_type() == NodeType::PI
970 }
971
972 #[inline]
974 pub fn is_comment(&self) -> bool {
975 self.node_type() == NodeType::Comment
976 }
977
978 #[inline]
980 pub fn is_text(&self) -> bool {
981 self.node_type() == NodeType::Text
982 }
983
984 #[inline]
986 pub fn document(&self) -> &'a Document<'input> {
987 self.doc
988 }
989
990 #[inline]
1003 pub fn tag_name(&self) -> ExpandedName<'a, 'input> {
1004 match self.d.kind {
1005 NodeKind::Element { ref tag_name, .. } => tag_name.as_expanded_name(self.doc),
1006 _ => "".into(),
1007 }
1008 }
1009
1010 pub fn has_tag_name<'n, 'm, N>(&self, name: N) -> bool
1024 where
1025 N: Into<ExpandedName<'n, 'm>>,
1026 {
1027 let name = name.into();
1028
1029 match self.d.kind {
1030 NodeKind::Element { ref tag_name, .. } => match name.namespace() {
1031 Some(_) => tag_name.as_expanded_name(self.doc) == name,
1032 None => tag_name.local_name == name.name,
1033 },
1034 _ => false,
1035 }
1036 }
1037
1038 pub fn default_namespace(&self) -> Option<&'a str> {
1054 self.namespaces()
1055 .find(|ns| ns.name.is_none())
1056 .map(|v| v.uri.as_ref())
1057 }
1058
1059 pub fn lookup_prefix(&self, uri: &str) -> Option<&'input str> {
1075 if uri == NS_XML_URI {
1076 return Some(NS_XML_PREFIX);
1077 }
1078
1079 self.namespaces()
1080 .find(|ns| &*ns.uri == uri)
1081 .map(|v| v.name)
1082 .unwrap_or(None)
1083 }
1084
1085 pub fn lookup_namespace_uri(&self, prefix: Option<&str>) -> Option<&'a str> {
1101 self.namespaces()
1102 .find(|ns| ns.name == prefix)
1103 .map(|v| v.uri.as_ref())
1104 }
1105
1106 pub fn attribute<'n, 'm, N>(&self, name: N) -> Option<&'a str>
1125 where
1126 N: Into<ExpandedName<'n, 'm>>,
1127 {
1128 self.attribute_node(name).map(|a| a.value())
1129 }
1130
1131 pub fn attribute_node<'n, 'm, N>(&self, name: N) -> Option<Attribute<'a, 'input>>
1137 where
1138 N: Into<ExpandedName<'n, 'm>>,
1139 {
1140 let name = name.into();
1141
1142 match name.namespace() {
1143 Some(_) => self.attributes().find(|a| a.data.name.as_expanded_name(self.doc) == name),
1144 None => self.attributes().find(|a| a.data.name.local_name == name.name),
1145 }
1146 }
1147
1148 pub fn has_attribute<'n, 'm, N>(&self, name: N) -> bool
1164 where
1165 N: Into<ExpandedName<'n, 'm>>,
1166 {
1167 self.attribute_node(name).is_some()
1168 }
1169
1170 #[inline]
1182 pub fn attributes(&self) -> Attributes<'a, 'input> {
1183 Attributes::new(self)
1184 }
1185
1186 #[inline]
1198 pub fn namespaces(&self) -> NamespaceIter<'a, 'input> {
1199 let namespaces = match self.d.kind {
1200 NodeKind::Element { ref namespaces, .. } => {
1201 &self.doc.namespaces.tree_order[namespaces.to_urange()]
1202 }
1203 _ => &[],
1204 };
1205
1206 NamespaceIter {
1207 doc: self.doc,
1208 namespaces: namespaces.iter(),
1209 }
1210 }
1211
1212 #[inline]
1239 pub fn text(&self) -> Option<&'a str> {
1240 self.text_storage().map(|s| s.as_str())
1241 }
1242
1243 pub fn text_storage(&self) -> Option<&'a StringStorage<'input>> {
1247 match self.d.kind {
1248 NodeKind::Element { .. } => match self.first_child() {
1249 Some(child) if child.is_text() => match self.doc.nodes[child.id.get_usize()].kind {
1250 NodeKind::Text(ref text) => Some(text),
1251 _ => None,
1252 },
1253 _ => None,
1254 },
1255 NodeKind::Comment(ref text) => Some(text),
1256 NodeKind::Text(ref text) => Some(text),
1257 _ => None,
1258 }
1259 }
1260
1261 #[inline]
1278 pub fn tail(&self) -> Option<&'a str> {
1279 self.tail_storage().map(|s| s.as_str())
1280 }
1281
1282 pub fn tail_storage(&self) -> Option<&'a StringStorage<'input>> {
1286 if !self.is_element() {
1287 return None;
1288 }
1289
1290 match self.next_sibling().map(|n| n.id) {
1291 Some(id) => match self.doc.nodes[id.get_usize()].kind {
1292 NodeKind::Text(ref text) => Some(text),
1293 _ => None,
1294 },
1295 None => None,
1296 }
1297 }
1298
1299 #[inline]
1301 pub fn pi(&self) -> Option<PI<'input>> {
1302 match self.d.kind {
1303 NodeKind::PI(pi) => Some(pi),
1304 _ => None,
1305 }
1306 }
1307
1308 #[inline]
1310 pub fn parent(&self) -> Option<Self> {
1311 self.d.parent.map(|id| self.doc.get_node(id).unwrap())
1312 }
1313
1314 pub fn parent_element(&self) -> Option<Self> {
1316 self.ancestors().skip(1).find(|n| n.is_element())
1317 }
1318
1319 #[inline]
1321 pub fn prev_sibling(&self) -> Option<Self> {
1322 self.d.prev_sibling.map(|id| self.doc.get_node(id).unwrap())
1323 }
1324
1325 pub fn prev_sibling_element(&self) -> Option<Self> {
1327 self.prev_siblings().skip(1).find(|n| n.is_element())
1328 }
1329
1330 #[inline]
1332 pub fn next_sibling(&self) -> Option<Self> {
1333 self.d
1334 .next_subtree
1335 .map(|id| self.doc.get_node(id).unwrap())
1336 .and_then(|node| {
1337 let possibly_self = node
1338 .d
1339 .prev_sibling
1340 .expect("next_subtree will always have a previous sibling");
1341 if possibly_self == self.id {
1342 Some(node)
1343 } else {
1344 None
1345 }
1346 })
1347 }
1348
1349 pub fn next_sibling_element(&self) -> Option<Self> {
1351 self.next_siblings().skip(1).find(|n| n.is_element())
1352 }
1353
1354 #[inline]
1356 pub fn first_child(&self) -> Option<Self> {
1357 self.d
1358 .last_child
1359 .map(|_| self.doc.get_node(NodeId::new(self.id.get() + 1)).unwrap())
1360 }
1361
1362 pub fn first_element_child(&self) -> Option<Self> {
1364 self.children().find(|n| n.is_element())
1365 }
1366
1367 #[inline]
1369 pub fn last_child(&self) -> Option<Self> {
1370 self.d.last_child.map(|id| self.doc.get_node(id).unwrap())
1371 }
1372
1373 pub fn last_element_child(&self) -> Option<Self> {
1375 self.children().filter(|n| n.is_element()).next_back()
1376 }
1377
1378 #[inline]
1380 pub fn has_siblings(&self) -> bool {
1381 self.d.prev_sibling.is_some() || self.next_sibling().is_some()
1382 }
1383
1384 #[inline]
1386 pub fn has_children(&self) -> bool {
1387 self.d.last_child.is_some()
1388 }
1389
1390 #[inline]
1392 pub fn ancestors(&self) -> AxisIter<'a, 'input> {
1393 AxisIter {
1394 node: Some(*self),
1395 next: Node::parent,
1396 }
1397 }
1398
1399 #[inline]
1401 pub fn prev_siblings(&self) -> AxisIter<'a, 'input> {
1402 AxisIter {
1403 node: Some(*self),
1404 next: Node::prev_sibling,
1405 }
1406 }
1407
1408 #[inline]
1410 pub fn next_siblings(&self) -> AxisIter<'a, 'input> {
1411 AxisIter {
1412 node: Some(*self),
1413 next: Node::next_sibling,
1414 }
1415 }
1416
1417 #[inline]
1419 pub fn first_children(&self) -> AxisIter<'a, 'input> {
1420 AxisIter {
1421 node: Some(*self),
1422 next: Node::first_child,
1423 }
1424 }
1425
1426 #[inline]
1428 pub fn last_children(&self) -> AxisIter<'a, 'input> {
1429 AxisIter {
1430 node: Some(*self),
1431 next: Node::last_child,
1432 }
1433 }
1434
1435 #[inline]
1437 pub fn children(&self) -> Children<'a, 'input> {
1438 Children {
1439 front: self.first_child(),
1440 back: self.last_child(),
1441 }
1442 }
1443
1444 #[inline]
1446 pub fn descendants(&self) -> Descendants<'a, 'input> {
1447 Descendants::new(*self)
1448 }
1449
1450 #[cfg(feature = "positions")]
1452 #[inline]
1453 pub fn range(&self) -> Range<usize> {
1454 self.d.range.clone()
1455 }
1456
1457 #[inline]
1459 pub fn id(&self) -> NodeId {
1460 self.id
1461 }
1462}
1463
1464impl<'a, 'input: 'a> fmt::Debug for Node<'a, 'input> {
1465 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
1466 match self.d.kind {
1467 NodeKind::Root => write!(f, "Root"),
1468 NodeKind::Element { .. } => {
1469 write!(
1470 f,
1471 "Element {{ tag_name: {:?}, attributes: {:?}, namespaces: {:?} }}",
1472 self.tag_name(),
1473 self.attributes(),
1474 self.namespaces()
1475 )
1476 }
1477 NodeKind::PI(pi) => {
1478 write!(f, "PI {{ target: {:?}, value: {:?} }}", pi.target, pi.value)
1479 }
1480 NodeKind::Comment(ref text) => write!(f, "Comment({:?})", text.as_str()),
1481 NodeKind::Text(ref text) => write!(f, "Text({:?})", text.as_str()),
1482 }
1483 }
1484}
1485
1486#[derive(Clone)]
1488pub struct Attributes<'a, 'input> {
1489 doc: &'a Document<'input>,
1490 attrs: core::slice::Iter<'a, AttributeData<'input>>,
1491}
1492
1493impl<'a, 'input> Attributes<'a, 'input> {
1494 #[inline]
1495 fn new(node: &Node<'a, 'input>) -> Attributes<'a, 'input> {
1496 let attrs = match node.d.kind {
1497 NodeKind::Element { ref attributes, .. } => {
1498 &node.doc.attributes[attributes.to_urange()]
1499 }
1500 _ => &[],
1501 };
1502 Attributes {
1503 doc: node.doc,
1504 attrs: attrs.iter(),
1505 }
1506 }
1507}
1508
1509impl<'a, 'input> Iterator for Attributes<'a, 'input> {
1510 type Item = Attribute<'a, 'input>;
1511
1512 #[inline]
1513 fn next(&mut self) -> Option<Self::Item> {
1514 self.attrs.next().map(|attr| Attribute {
1515 doc: self.doc,
1516 data: attr,
1517 })
1518 }
1519
1520 #[inline]
1521 fn nth(&mut self, n: usize) -> Option<Self::Item> {
1522 self.attrs.nth(n).map(|attr| Attribute {
1523 doc: self.doc,
1524 data: attr,
1525 })
1526 }
1527
1528 #[inline]
1529 fn size_hint(&self) -> (usize, Option<usize>) {
1530 self.attrs.size_hint()
1531 }
1532}
1533
1534impl<'a, 'input> DoubleEndedIterator for Attributes<'a, 'input> {
1535 #[inline]
1536 fn next_back(&mut self) -> Option<Self::Item> {
1537 self.attrs.next_back().map(|attr| Attribute {
1538 doc: self.doc,
1539 data: attr,
1540 })
1541 }
1542}
1543
1544impl ExactSizeIterator for Attributes<'_, '_> {}
1545
1546impl fmt::Debug for Attributes<'_, '_> {
1547 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
1548 f.debug_struct("Attributes")
1549 .field("attrs", &self.attrs)
1550 .finish()
1551 }
1552}
1553
1554#[derive(Clone)]
1556pub struct AxisIter<'a, 'input: 'a> {
1557 node: Option<Node<'a, 'input>>,
1558 next: fn(&Node<'a, 'input>) -> Option<Node<'a, 'input>>,
1559}
1560
1561impl<'a, 'input: 'a> Iterator for AxisIter<'a, 'input> {
1562 type Item = Node<'a, 'input>;
1563
1564 #[inline]
1565 fn next(&mut self) -> Option<Self::Item> {
1566 let node = self.node.take();
1567 self.node = node.as_ref().and_then(self.next);
1568 node
1569 }
1570}
1571
1572impl fmt::Debug for AxisIter<'_, '_> {
1573 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
1574 f.debug_struct("AxisIter")
1575 .field("node", &self.node)
1576 .field("next", &"fn()")
1577 .finish()
1578 }
1579}
1580
1581#[derive(Clone, Debug)]
1583pub struct Children<'a, 'input: 'a> {
1584 front: Option<Node<'a, 'input>>,
1585 back: Option<Node<'a, 'input>>,
1586}
1587
1588impl<'a, 'input: 'a> Iterator for Children<'a, 'input> {
1589 type Item = Node<'a, 'input>;
1590
1591 #[inline]
1592 fn next(&mut self) -> Option<Self::Item> {
1593 if self.front == self.back {
1594 let node = self.front.take();
1595 self.back = None;
1596 node
1597 } else {
1598 let node = self.front.take();
1599 self.front = node.as_ref().and_then(Node::next_sibling);
1600 node
1601 }
1602 }
1603}
1604
1605impl<'a, 'input: 'a> DoubleEndedIterator for Children<'a, 'input> {
1606 #[inline]
1607 fn next_back(&mut self) -> Option<Self::Item> {
1608 if self.back == self.front {
1609 let node = self.back.take();
1610 self.front = None;
1611 node
1612 } else {
1613 let node = self.back.take();
1614 self.back = node.as_ref().and_then(Node::prev_sibling);
1615 node
1616 }
1617 }
1618}
1619
1620#[derive(Clone)]
1622pub struct Descendants<'a, 'input> {
1623 doc: &'a Document<'input>,
1624 nodes: core::iter::Enumerate<core::slice::Iter<'a, NodeData<'input>>>,
1625 from: usize,
1626}
1627
1628impl<'a, 'input> Descendants<'a, 'input> {
1629 #[inline]
1630 fn new(start: Node<'a, 'input>) -> Self {
1631 let from = start.id.get_usize();
1632
1633 let until = start
1634 .d
1635 .next_subtree
1636 .map(NodeId::get_usize)
1637 .unwrap_or(start.doc.nodes.len());
1638
1639 let nodes = start.doc.nodes[from..until].iter().enumerate();
1640
1641 Self {
1642 doc: start.doc,
1643 nodes,
1644 from,
1645 }
1646 }
1647}
1648
1649impl<'a, 'input> Iterator for Descendants<'a, 'input> {
1650 type Item = Node<'a, 'input>;
1651
1652 #[inline]
1653 fn next(&mut self) -> Option<Self::Item> {
1654 self.nodes.next().map(|(idx, data)| Node {
1655 id: NodeId::from(self.from + idx),
1656 d: data,
1657 doc: self.doc,
1658 })
1659 }
1660
1661 #[inline]
1662 fn nth(&mut self, n: usize) -> Option<Self::Item> {
1663 self.nodes.nth(n).map(|(idx, data)| Node {
1664 id: NodeId::from(self.from + idx),
1665 d: data,
1666 doc: self.doc,
1667 })
1668 }
1669
1670 #[inline]
1671 fn size_hint(&self) -> (usize, Option<usize>) {
1672 self.nodes.size_hint()
1673 }
1674}
1675
1676impl<'a, 'input> DoubleEndedIterator for Descendants<'a, 'input> {
1677 #[inline]
1678 fn next_back(&mut self) -> Option<Self::Item> {
1679 self.nodes.next_back().map(|(idx, data)| Node {
1680 id: NodeId::from(self.from + idx),
1681 d: data,
1682 doc: self.doc,
1683 })
1684 }
1685}
1686
1687impl ExactSizeIterator for Descendants<'_, '_> {}
1688
1689impl fmt::Debug for Descendants<'_, '_> {
1690 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
1691 f.debug_struct("Descendants")
1692 .field("nodes", &self.nodes)
1693 .field("from", &self.from)
1694 .finish()
1695 }
1696}
1697
1698#[derive(Clone)]
1700pub struct NamespaceIter<'a, 'input> {
1701 doc: &'a Document<'input>,
1702 namespaces: core::slice::Iter<'a, NamespaceIdx>,
1703}
1704
1705impl<'a, 'input> Iterator for NamespaceIter<'a, 'input> {
1706 type Item = &'a Namespace<'input>;
1707
1708 #[inline]
1709 fn next(&mut self) -> Option<Self::Item> {
1710 self.namespaces
1711 .next()
1712 .map(|idx| self.doc.namespaces.get(*idx))
1713 }
1714
1715 #[inline]
1716 fn nth(&mut self, n: usize) -> Option<Self::Item> {
1717 self.namespaces
1718 .nth(n)
1719 .map(|idx| self.doc.namespaces.get(*idx))
1720 }
1721
1722 #[inline]
1723 fn size_hint(&self) -> (usize, Option<usize>) {
1724 self.namespaces.size_hint()
1725 }
1726}
1727
1728impl<'a, 'input> DoubleEndedIterator for NamespaceIter<'a, 'input> {
1729 #[inline]
1730 fn next_back(&mut self) -> Option<Self::Item> {
1731 self.namespaces
1732 .next()
1733 .map(|idx| self.doc.namespaces.get(*idx))
1734 }
1735}
1736
1737impl ExactSizeIterator for NamespaceIter<'_, '_> {}
1738
1739impl fmt::Debug for NamespaceIter<'_, '_> {
1740 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
1741 f.debug_struct("NamespaceIter")
1742 .field("namespaces", &self.namespaces)
1743 .finish()
1744 }
1745}