Skip to main content

xrust/trees/
smite.rs

1/*! # A tree structure for XDM
2
3This module implements the Item module's [Node](crate::item::Node) trait.
4
5This implementation uses interior mutability to create and manage a tree structure that is both mutable and fully navigable.
6
7To create a tree, use [Node::new()](crate::trees::smite::Node) to make a Document-type node.
8To add a node, first create it using a creation method, defined by the [Node](crate::item::Node) trait, such as new_element() or new_text(),
9then use the push(), insert_before(), or add_attribute() method to attach it to a node in the tree.
10
11NB. The Item module's Node trait is implemented for Rc\<smite::Node\>. For convenience, this is defined as the type [RNode](crate::trees::smite::RNode).
12
13```rust
14use std::rc::Rc;
15use xrust::trees::smite::RNode;
16use xrust::item::{Node as ItemNode, NodeType};
17use qualname::{QName, NcName};
18use xrust::value::Value;
19use xrust::xdmerror::Error;
20
21//pub(crate) type ExtDTDresolver = fn(Option<String>, String) -> Result<String, Error>;
22
23// A document always has a NodeType::Document node as the toplevel node.
24let mut doc = RNode::new_document();
25
26// Create an element-type node. Upon creation, it is *not* attached to the tree.
27let mut top = doc.new_element(
28    QName::from_local_name(NcName::try_from("Top-Level").unwrap())
29).expect("unable to create element node");
30
31// Nodes are Rc-shared, so it is cheap to clone them.
32// Now attach the element node to the tree.
33// In this case, it is being attached to the document node, so it will become the root element.
34doc.push(top.clone())
35    .expect("unable to append child node");
36
37// Now create a text node and attach it to the root element.
38top.push(
39    doc.new_text(Rc::new(Value::from("content of the element")))
40        .expect("unable to create text node")
41).expect("unable to append child node");
42
43assert_eq!(doc.to_xml(), "<Top-Level>content of the element</Top-Level>")
44*/
45
46use crate::item::{Node as ItemNode, NodeType};
47use crate::output::{OutputDefinition, OutputSpec};
48use crate::parser::xml::qname::qualname_to_qname;
49use crate::parser::{ParseError, ParserStateBuilder, StaticStateBuilder};
50use crate::validators::{Schema, ValidationError};
51use crate::value::{Value, ValueData};
52use crate::xdmerror::*;
53use crate::xmldecl::{DTD, XMLDecl, XMLDeclBuilder};
54use qualname::{NamespacePrefix, NamespaceUri, NcName, QName};
55use regex::Regex;
56use std::cell::RefCell;
57use std::cmp::Ordering;
58use std::collections::BTreeMap;
59use std::collections::btree_map::IntoIter;
60use std::fmt;
61use std::fmt::{Debug, Formatter};
62use std::rc::{Rc, Weak};
63
64/// A node in a tree.
65pub type RNode = Rc<Node>;
66
67enum NodeInner {
68    Document(
69        RefCell<Option<XMLDecl>>,
70        RefCell<Vec<RNode>>, // Child nodes
71        RefCell<Vec<RNode>>, // Unattached nodes
72        RefCell<Option<DTD>>,
73    ), // to be well-formed, only one of the child nodes can be an element-type node
74    Element(
75        RefCell<Weak<Node>>,             // Parent: must be a Document or an Element
76        QName,                           // name
77        RefCell<BTreeMap<QName, RNode>>, // attributes
78        RefCell<Vec<RNode>>,             // children
79        Rc<RefCell<BTreeMap<Option<NamespacePrefix>, RNode>>>, // namespace declarations
80    ),
81    Text(RefCell<Weak<Node>>, Rc<Value>),
82    Attribute(RefCell<Weak<Node>>, QName, Rc<Value>),
83    Comment(RefCell<Weak<Node>>, Rc<Value>),
84    ProcessingInstruction(RefCell<Weak<Node>>, Rc<Value>, Rc<Value>),
85    Namespace(
86        RefCell<Weak<Node>>, // Parent
87        Option<NamespacePrefix>,
88        NamespaceUri,
89        bool, // Active status (Namespaces in XML 1.1 allows namespaces to be descoped)
90    ),
91}
92pub struct Node(NodeInner);
93
94impl Node {
95    /// Only documents are created new. All other types of nodes are created using new_* methods.
96    fn new() -> Self {
97        Node(NodeInner::Document(
98            RefCell::new(None),
99            RefCell::new(vec![]),
100            RefCell::new(vec![]),
101            None.into(),
102        ))
103    }
104    fn ns_prefix(&self) -> Option<NamespacePrefix> {
105        match &self.0 {
106            NodeInner::Namespace(_, prefix, _, _) => prefix.clone(),
107            _ => None,
108        }
109    }
110    fn ns_uri(&self) -> Option<NamespaceUri> {
111        match &self.0 {
112            NodeInner::Namespace(_, _, nsuri, _) => Some(nsuri.clone()),
113            _ => None,
114        }
115    }
116    // Whether the namespace declaration is active, i.e. in-scope
117    fn ns_in_scope(&self) -> bool {
118        match &self.0 {
119            NodeInner::Namespace(_, _, _, a) => *a,
120            _ => false,
121        }
122    }
123}
124
125impl PartialEq for Node {
126    fn eq(&self, other: &Self) -> bool {
127        match (&self.0, &other.0) {
128            (NodeInner::Document(_, c, _, _), NodeInner::Document(_, d, _, _)) => {
129                c.borrow()
130                    .iter()
131                    .zip(d.borrow().iter())
132                    .fold(true, |mut acc, (c, d)| {
133                        if acc {
134                            acc = c == d;
135                            acc
136                        } else {
137                            acc
138                        }
139                    })
140                // TODO: use a method that terminates early on non-equality
141            }
142            (
143                NodeInner::Element(_, name, atts, c, _),
144                NodeInner::Element(_, o_name, o_atts, d, _),
145            ) => {
146                if name == o_name {
147                    // Attributes must match
148                    let b_atts = atts.borrow();
149                    let b_o_atts = o_atts.borrow();
150                    if b_atts.len() == b_o_atts.len() {
151                        let mut at_names: Vec<QName> = b_atts.keys().cloned().collect();
152                        at_names.sort();
153                        if at_names.iter().fold(true, |mut acc, qn| {
154                            if acc {
155                                acc = b_atts.get(qn) == b_o_atts.get(qn);
156                                acc
157                            } else {
158                                acc
159                            }
160                        }) {
161                            // Content
162                            c.borrow().iter().zip(d.borrow().iter()).fold(
163                                true,
164                                |mut acc, (c, d)| {
165                                    if acc {
166                                        acc = c == d;
167                                        acc
168                                    } else {
169                                        acc
170                                    }
171                                },
172                            )
173                            // TODO: use a method that terminates early on non-equality
174                        } else {
175                            false
176                        }
177                    } else {
178                        false
179                    }
180                    // Content must match
181                } else {
182                    false
183                }
184            }
185            (NodeInner::Text(_, v), NodeInner::Text(_, u)) => v == u,
186            (NodeInner::Attribute(_, name, v), NodeInner::Attribute(_, o_name, o_v)) => {
187                if name == o_name { v == o_v } else { false }
188            }
189            (
190                NodeInner::ProcessingInstruction(_, name, v),
191                NodeInner::ProcessingInstruction(_, o_name, o_v),
192            ) => name == o_name && v == o_v,
193            _ => false,
194        }
195    }
196}
197
198impl ItemNode for RNode {
199    type NodeIterator = Box<dyn Iterator<Item = RNode>>;
200
201    fn new_document() -> Self {
202        Rc::new(Node::new())
203    }
204
205    fn unattached(&self) -> Vec<Self> {
206        match &self.0 {
207            NodeInner::Document(_, _, u, _) => u.borrow().clone(),
208            _ => vec![],
209        }
210    }
211    fn is_unattached(&self) -> bool {
212        match &self.0 {
213            NodeInner::Element(p, _, _, _, _)
214            | NodeInner::Text(p, _)
215            | NodeInner::Attribute(p, _, _)
216            | NodeInner::Comment(p, _)
217            | NodeInner::ProcessingInstruction(p, _, _) => {
218                if let Some(q) = p.borrow().upgrade() {
219                    match &q.0 {
220                        NodeInner::Document(_, _, u, _) => {
221                            u.borrow().iter().any(|a| a.is_same(self))
222                        }
223                        _ => false,
224                    }
225                } else {
226                    false
227                }
228            }
229            _ => false,
230        }
231    }
232
233    fn node_type(&self) -> NodeType {
234        match &self.0 {
235            NodeInner::Document(_, _, _, _) => NodeType::Document,
236            NodeInner::Element(_, _, _, _, _) => NodeType::Element,
237            NodeInner::Attribute(_, _, _) => NodeType::Attribute,
238            NodeInner::Text(_, _) => NodeType::Text,
239            NodeInner::Comment(_, _) => NodeType::Comment,
240            NodeInner::ProcessingInstruction(_, _, _) => NodeType::ProcessingInstruction,
241            NodeInner::Namespace(_, _, _, _) => NodeType::Namespace,
242        }
243    }
244    fn name(&self) -> Option<QName> {
245        match &self.0 {
246            NodeInner::Element(_, qn, _, _, _) | NodeInner::Attribute(_, qn, _) => Some(qn.clone()),
247            NodeInner::ProcessingInstruction(_, nm, _) => {
248                // A PI's target is a Name, which may not be a valid NcName
249                // But it is also not a QName
250                // Best we can do is treat it as an unprefixed name
251                // If this fails then return None
252                NcName::try_from(nm.to_string().as_str())
253                    .map_or(None, |ncn| Some(QName::from_local_name(ncn)))
254            }
255            NodeInner::Namespace(_, p, _, _) => {
256                p.as_ref().map(|pf| QName::from_local_name(pf.to_ncname()))
257            }
258            _ => None,
259        }
260    }
261    fn to_qname(&self, name: impl AsRef<str>) -> Result<QName, Error> {
262        // Parse the prefixed name
263        // Use the namespace iterator to set up namespace declarations
264        // First, make sure the supplied is valid
265        let mut ss = StaticStateBuilder::new()
266            .namespace(|prefix: &NamespacePrefix| {
267                self.namespace_iter()
268                    .find(|ns| {
269                        // TODO: it's annoying to have to convert the namespace node name back to a prefix when we know it is a prefix
270                        // Ignore default namespace, since there is no prefix to map
271                        ns.name().is_some_and(|nsprefix| {
272                            NamespacePrefix::try_from(nsprefix.local_name().to_string().as_str())
273                                .unwrap()
274                                == *prefix
275                        })
276                    })
277                    .map_or_else(
278                        || Err(ParseError::MissingNameSpace),
279                        // It's annoying to have to convert the namespace node value to a namespace URI when we already know it is a namespace URI
280                        |nsd| Ok(NamespaceUri::try_from(nsd.value().to_string().as_str()).unwrap()),
281                    )
282            })
283            .build();
284        let state = ParserStateBuilder::new().doc(self.owner_document()).build();
285        match qualname_to_qname()((name.as_ref(), state), &mut ss) {
286            Ok((_, qn)) => Ok(qn),
287            Err(_) => Err(Error::new(
288                ErrorKind::ParseError,
289                "unable to resolve qualified name",
290            )),
291        }
292    }
293    fn to_prefixed_name(&self) -> String {
294        self.name().map_or(String::new(), |qn| {
295            qn.namespace_uri().as_ref().map_or_else(
296                || qn.local_name().to_string(),
297                |nsuri| {
298                    self.to_namespace_prefix(nsuri).unwrap().map_or_else(
299                        || qn.local_name().to_string(),
300                        |prefix| format!("{}:{}", prefix.to_string(), qn.local_name().to_string()),
301                    )
302                },
303            )
304        })
305    }
306    fn to_namespace_prefix(&self, nsuri: &NamespaceUri) -> Result<Option<NamespacePrefix>, Error> {
307        self.namespace_iter()
308            .find(|nsd| nsd.as_namespace_uri().unwrap() == nsuri)
309            .map_or(
310                Err(Error::new(ErrorKind::DynamicAbsent, "namespace not found")),
311                |nsd| Ok(nsd.as_namespace_prefix().unwrap().cloned()),
312            )
313    }
314    fn to_namespace_uri(&self, prefix: &Option<NamespacePrefix>) -> Result<NamespaceUri, Error> {
315        self.namespace_iter()
316            .find(|nsd| nsd.ns_in_scope() && nsd.as_namespace_prefix().unwrap() == prefix.as_ref())
317            .map_or(
318                Err(Error::new(ErrorKind::DynamicAbsent, "namespace not found")),
319                |nsd| Ok(nsd.as_namespace_uri().unwrap().clone()),
320            )
321    }
322    fn as_namespace_prefix(&self) -> Result<Option<&NamespacePrefix>, Error> {
323        match &self.0 {
324            NodeInner::Namespace(_, p, _, _) => Ok(p.as_ref()),
325            _ => Err(Error::new(ErrorKind::TypeError, "not a namespace node")),
326        }
327    }
328    fn as_namespace_uri(&self) -> Result<&NamespaceUri, Error> {
329        match &self.0 {
330            NodeInner::Namespace(_, _, u, _) => Ok(u),
331            _ => Err(Error::new(ErrorKind::TypeError, "not a namespace node")),
332        }
333    }
334    fn is_in_scope(&self) -> bool {
335        match &self.0 {
336            NodeInner::Namespace(_, _, _, s) => *s,
337            _ => false,
338        }
339    }
340    fn value(&self) -> Rc<Value> {
341        match &self.0 {
342            NodeInner::Text(_, v)
343            | NodeInner::Comment(_, v)
344            | NodeInner::ProcessingInstruction(_, _, v)
345            | NodeInner::Attribute(_, _, v) => v.clone(),
346            NodeInner::Namespace(_, _, ns, inscope) => Rc::new(if *inscope {
347                Value::from(ns.clone())
348            } else {
349                Value::from("")
350            }),
351            _ => Rc::new(Value::from("")),
352        }
353    }
354
355    fn get_id(&self) -> String {
356        format!("{:#p}", &(self).0 as *const NodeInner)
357    }
358
359    fn to_string(&self) -> String {
360        match &self.0 {
361            NodeInner::Document(_, c, _, _) | NodeInner::Element(_, _, _, c, _) => {
362                c.borrow().iter().fold(String::new(), |mut acc, n| {
363                    acc.push_str(n.to_string().as_str());
364                    acc
365                })
366            }
367            NodeInner::Attribute(_, _, v)
368            | NodeInner::Text(_, v)
369            | NodeInner::Comment(_, v)
370            | NodeInner::ProcessingInstruction(_, _, v) => v.to_string(),
371            NodeInner::Namespace(_, _, uri, inscope) => {
372                if *inscope {
373                    uri.to_string()
374                } else {
375                    String::new()
376                }
377            }
378        }
379    }
380    fn to_xml(&self) -> String {
381        to_xml_int(self, &OutputDefinition::new(), 0, vec![])
382    }
383    fn to_xml_with_options(&self, od: &OutputDefinition) -> std::string::String {
384        to_xml_int(self, od, 0, vec![])
385    }
386    fn is_same(&self, other: &Self) -> bool {
387        Rc::ptr_eq(self, other)
388    }
389    fn is_attached(&self) -> bool {
390        match &self.0 {
391            NodeInner::Document(_, _, _, _) => false,
392            NodeInner::Namespace(_, _, _, _) => false,
393            _ => {
394                if let NodeInner::Document(_, _, u, _) = &self.owner_document().0 {
395                    u.borrow()
396                        .iter()
397                        .find(|p| self.is_same(p))
398                        .is_none_or(|_| false)
399                } else {
400                    // shouldn't get here
401                    false
402                }
403            }
404        }
405    }
406    fn document_order(&self) -> Vec<usize> {
407        doc_order(self)
408    }
409    // Find the document node, given an arbitrary node in the tree.
410    // There is always a document node, so this will not panic.
411    fn owner_document(&self) -> Self {
412        match &self.0 {
413            NodeInner::Document(_, _, _, _) => self.clone(),
414            _ => self.ancestor_iter().last().unwrap(),
415        }
416    }
417    fn cmp_document_order(&self, other: &Self) -> Ordering {
418        let this_order = self.document_order();
419        let other_order = other.document_order();
420        let mut this_it = this_order.iter();
421        let mut other_it = other_order.iter();
422        for _i in 0.. {
423            match (this_it.next(), other_it.next()) {
424                (Some(t), Some(o)) => {
425                    match t.cmp(o) {
426                        Ordering::Greater => return Ordering::Greater,
427                        Ordering::Less => return Ordering::Less,
428                        Ordering::Equal => {}
429                    }
430                    // otherwise continue the loop
431                }
432                (Some(_), None) => return Ordering::Greater,
433                (None, Some(_)) => return Ordering::Less,
434                (None, None) => return Ordering::Equal,
435            }
436        }
437        // Will never reach here
438        Ordering::Equal
439    }
440    fn child_iter(&self) -> Self::NodeIterator {
441        Box::new(Children::new(self))
442    }
443    fn ancestor_iter(&self) -> Self::NodeIterator {
444        Box::new(Ancestors::new(self))
445    }
446    fn descend_iter(&self) -> Self::NodeIterator {
447        Box::new(Descendants::new(self))
448    }
449    fn next_iter(&self) -> Self::NodeIterator {
450        Box::new(Siblings::new(self, 1))
451    }
452    fn prev_iter(&self) -> Self::NodeIterator {
453        Box::new(Siblings::new(self, -1))
454    }
455    fn attribute_iter(&self) -> Self::NodeIterator {
456        Box::new(Attributes::new(self))
457    }
458    /// Iterator for in-scope namespaces for a node.
459    /// For a document-type node, if there is a document element then it's in-scope namespaces are returned.
460    /// If the document has multiple top-level elements, then the namespaces of the first element-type node are returned.
461    /// Otherwise, the default "xml" namespace is returned.
462    fn namespace_iter(&self) -> Self::NodeIterator {
463        Box::new(NamespaceNodes::new(self.clone()))
464    }
465    fn get_attribute(&self, a: &QName) -> Rc<Value> {
466        match &self.0 {
467            NodeInner::Element(_, _, att, _, _) => att
468                .borrow()
469                .get(a)
470                .map_or(Rc::new(Value::from(String::new())), |v| v.value()),
471            _ => Rc::new(Value::from(String::new())),
472        }
473    }
474    fn get_attribute_node(&self, a: &QName) -> Option<Self> {
475        match &self.0 {
476            NodeInner::Element(_, _, att, _, _) => att.borrow().get(a).cloned(),
477            _ => None,
478        }
479    }
480    fn new_element(&self, qn: QName) -> Result<Self, Error> {
481        let child = Rc::new(Node(NodeInner::Element(
482            RefCell::new(Rc::downgrade(&self.owner_document())),
483            qn,
484            RefCell::new(BTreeMap::new()),
485            RefCell::new(vec![]),
486            Rc::new(RefCell::new(BTreeMap::new())),
487        )));
488        unattached(self, child.clone());
489        Ok(child)
490    }
491    fn new_namespace(
492        &self,
493        ns: NamespaceUri,
494        prefix: Option<NamespacePrefix>,
495        in_scope: bool,
496    ) -> Result<Self, Error> {
497        let ns_node = Rc::new(Node(NodeInner::Namespace(
498            RefCell::new(Rc::downgrade(&self.owner_document())),
499            prefix,
500            ns,
501            in_scope,
502        )));
503        unattached(self, ns_node.clone());
504        Ok(ns_node)
505    }
506    fn new_text(&self, v: Rc<Value>) -> Result<Self, Error> {
507        let child = Rc::new(Node(NodeInner::Text(
508            RefCell::new(Rc::downgrade(&self.owner_document())),
509            v,
510        )));
511        unattached(self, child.clone());
512        Ok(child)
513    }
514    fn new_attribute(&self, qn: QName, v: Rc<Value>) -> Result<Self, Error> {
515        //TODO if the attribute is xml:id then type needs to be set as ID, regardless of DTD.
516        let att = Rc::new(Node(NodeInner::Attribute(
517            RefCell::new(Rc::downgrade(self)),
518            qn.clone(),
519            v,
520        )));
521        unattached(self, att.clone());
522        Ok(att)
523    }
524    fn new_comment(&self, v: Rc<Value>) -> Result<Self, Error> {
525        let child = Rc::new(Node(NodeInner::Comment(
526            RefCell::new(Rc::downgrade(&self.owner_document())),
527            v,
528        )));
529        unattached(self, child.clone());
530        Ok(child)
531    }
532    fn new_processing_instruction(&self, qn: Rc<Value>, v: Rc<Value>) -> Result<Self, Error> {
533        let child = Rc::new(Node(NodeInner::ProcessingInstruction(
534            RefCell::new(Rc::downgrade(&self.owner_document())),
535            qn.clone(),
536            v,
537        )));
538        unattached(self, child.clone());
539        Ok(child)
540    }
541    // Append a node to the child list of the new parent.
542    // Must first detach the node from its current position in the tree.
543    fn push(&mut self, n: Self) -> Result<(), Error> {
544        if n.node_type() == NodeType::Document
545            || n.node_type() == NodeType::Attribute
546            || n.node_type() == NodeType::Namespace
547        {
548            return Err(Error::new(
549                ErrorKind::TypeError,
550                String::from(
551                    "document, namespace, or attribute type nodes cannot be inserted as a child",
552                ),
553            ));
554        }
555
556        let mut m = n.clone();
557        m.pop()?;
558        detach(m);
559        push_node(self, n)?;
560        Ok(())
561    }
562    // Remove a node from the tree. If the node is unattached, then this has no effect.
563    // The node is added to the unattached list of the owner document.
564    fn pop(&mut self) -> Result<(), Error> {
565        match &self.0 {
566            NodeInner::Document(_, _, _, _) => {
567                return Err(Error::new(
568                    ErrorKind::TypeError,
569                    String::from("cannot remove document node"),
570                ));
571            }
572            NodeInner::Attribute(parent, qn, _) => {
573                // Remove this node from the attribute hashmap
574                let myp = Weak::upgrade(&parent.borrow()); // make borrow temporary
575                match myp {
576                    Some(p) => {
577                        match &p.0 {
578                            NodeInner::Element(_, _, att, _, _) => {
579                                att.borrow_mut().remove(qn).ok_or(Error::new(
580                                    ErrorKind::DynamicAbsent,
581                                    String::from("unable to find attribute"),
582                                ))?;
583                                let doc = self.owner_document();
584                                unattached(&doc, self.clone());
585                            }
586                            NodeInner::Document(_, _, _, _) => {} // attr was in the unattached list
587                            _ => {
588                                return Err(Error::new(
589                                    ErrorKind::TypeError,
590                                    String::from("parent is not an element"),
591                                ));
592                            }
593                        }
594                    }
595                    None => {
596                        return Err(Error::new(
597                            ErrorKind::Unknown,
598                            String::from("unable to find parent"),
599                        ));
600                    }
601                }
602            }
603            NodeInner::Namespace(parent, prefix, _, _) => {
604                // Remove this node from the namespace hashmap
605                match Weak::upgrade(&parent.borrow()) {
606                    Some(p) => {
607                        match &p.0 {
608                            NodeInner::Element(_, _, _, _, namespaces) => {
609                                namespaces
610                                    .borrow_mut()
611                                    .remove_entry(prefix)
612                                    .ok_or(Error::new(
613                                        ErrorKind::DynamicAbsent,
614                                        String::from("unable to find namespace"),
615                                    ))?;
616                                let doc = self.owner_document();
617                                unattached(&doc, self.clone());
618                            }
619                            NodeInner::Document(_, _, _, _) => {} // attr was in the unattached list
620                            _ => {
621                                return Err(Error::new(
622                                    ErrorKind::TypeError,
623                                    String::from("parent is not an element"),
624                                ));
625                            }
626                        }
627                    }
628                    None => {
629                        return Err(Error::new(
630                            ErrorKind::Unknown,
631                            String::from("unable to find parent"),
632                        ));
633                    }
634                }
635            }
636            NodeInner::Element(parent, _, _, _, _)
637            | NodeInner::Text(parent, _)
638            | NodeInner::Comment(parent, _)
639            | NodeInner::ProcessingInstruction(parent, _, _) => {
640                // Remove this node from the old parent's child list
641                let p = if let Some(q) = Weak::upgrade(&parent.borrow()) {
642                    q
643                } else {
644                    return Err(Error::new(
645                        ErrorKind::Unknown,
646                        String::from("unable to access parent"),
647                    ));
648                };
649                match &p.0 {
650                    NodeInner::Element(_, _, _, c, _) => {
651                        let idx = find_index(&p, self)?;
652                        c.borrow_mut().remove(idx);
653                        let doc = self.owner_document();
654                        unattached(&doc, self.clone())
655                    }
656                    NodeInner::Document(_, c, _, _) => {
657                        let idx = find_index(&p, self);
658                        match idx {
659                            Ok(u) => {
660                                c.borrow_mut().remove(u);
661                                let doc = self.owner_document();
662                                unattached(&doc, self.clone())
663                            }
664                            Err(_) => {} // node was in the unattached list
665                        }
666                    }
667                    _ => {
668                        return Err(Error::new(
669                            ErrorKind::TypeError,
670                            String::from("parent is not an element"),
671                        ));
672                    }
673                }
674            }
675        };
676        Ok(())
677    }
678    fn add_attribute(&self, att: Self) -> Result<(), Error> {
679        if att.node_type() != NodeType::Attribute {
680            return Err(Error::new(
681                ErrorKind::TypeError,
682                String::from("node is not an attribute"),
683            ));
684        }
685
686        match &self.0 {
687            NodeInner::Element(_, _, patt, _, _) => {
688                // Short-circuit: Is this attribute already attached to this element?
689                if let Some(b) = patt.borrow().get(&att.name().unwrap()) {
690                    if att.is_same(b) {
691                        return Ok(());
692                    } else {
693                        return Err(Error::new_with_code(
694                            ErrorKind::DuplicateAttribute,
695                            format!(
696                                "attribute named \"{}\" already exists",
697                                self.name().unwrap()
698                            ),
699                            Some(QName::new_from_parts(
700                                NcName::try_from("SXXP0003").unwrap(),
701                                Some(
702                                    NamespaceUri::try_from("http://www.w3.org/2005/xqt-errors")
703                                        .unwrap(),
704                                ),
705                            )),
706                        ));
707                    }
708                }
709                // Firstly, make sure the node is removed from its old parent
710                let mut m = att.clone();
711                m.pop()?;
712                // Popping will put the node in the unattached list,
713                // so remove it from there
714                detach(m.clone());
715                // Now add to this parent
716                // TODO: deal with same name being redefined
717                if let NodeInner::Attribute(_, qn, _) = &m.0 {
718                    let _ = patt.borrow_mut().insert(qn.clone(), m.clone());
719                }
720                make_parent(m, self.clone());
721                Ok(())
722            }
723            _ => Err(Error::new(
724                ErrorKind::TypeError,
725                String::from("cannot add an attribute to this type of node"),
726            )),
727        }
728    }
729    /// Add a namespace declaration to this element-type node.
730    /// NOTE: does NOT update the namespace values of the element itself.
731    // TODO: confirm what the behaviour of this should be.
732    fn add_namespace(&self, ns: Self) -> Result<(), Error> {
733        if ns.node_type() != NodeType::Namespace {
734            return Err(Error::new(
735                ErrorKind::TypeError,
736                String::from("node is not a namespace"),
737            ));
738        }
739
740        match &self.0 {
741            NodeInner::Element(_, _, _, _, n) => {
742                // Firstly, make sure the node is removed from its old parent
743                let mut m = ns.clone();
744                m.pop()?;
745                // Popping will put the node in the unattached list,
746                // so remove it from there
747                detach(ns.clone());
748                // Now add to this parent
749                // TODO: deal with same name being redefined
750                if let NodeInner::Namespace(_, prefix, _, _) = &m.0 {
751                    let _ = n.borrow_mut().insert(prefix.clone(), ns.clone());
752                }
753
754                make_parent(ns, self.clone());
755                Ok(())
756            }
757            _ => Err(Error::new(
758                ErrorKind::TypeError,
759                String::from("cannot add a namespace declaration to this type of node"),
760            )),
761        }
762    }
763    fn insert_before(&mut self, n: Self) -> Result<(), Error> {
764        if n.node_type() == NodeType::Document
765            || n.node_type() == NodeType::Attribute
766            || n.node_type() == NodeType::Namespace
767        {
768            return Err(Error::new(
769                ErrorKind::TypeError,
770                String::from("cannot insert document, namespace, or attribute node"),
771            ));
772        }
773
774        // Detach from current location
775        let mut m = n.clone();
776        m.pop()?;
777        detach(n.clone());
778        // Now insert into parent's child list
779        match &self.0 {
780            NodeInner::Element(p, _, _, _, _)
781            | NodeInner::Text(p, _)
782            | NodeInner::Comment(p, _)
783            | NodeInner::ProcessingInstruction(p, _, _) => {
784                let parent = Weak::upgrade(&p.borrow()).unwrap();
785                let idx = find_index(&parent, self)?;
786                match &parent.0 {
787                    NodeInner::Document(_, children, _, _)
788                    | NodeInner::Element(_, _, _, children, _) => {
789                        children.borrow_mut().insert(idx, n.clone());
790                        make_parent(n, parent.clone())
791                    }
792                    _ => {
793                        return Err(Error::new(
794                            ErrorKind::TypeError,
795                            String::from("parent is not an element"),
796                        ));
797                    }
798                }
799            }
800            _ => {
801                return Err(Error::new(
802                    ErrorKind::TypeError,
803                    String::from("unable to find parent"),
804                ));
805            }
806        }
807        Ok(())
808    }
809    fn shallow_copy(&self) -> Result<Self, Error> {
810        // All new nodes are parentless, i.e. they are unattached to the tree
811        // The new element will have the same set of in-scope namespaces as the original element.
812        match &self.0 {
813            NodeInner::Document(x, _, _, _) => Ok(Rc::new(Node(NodeInner::Document(
814                x.clone(),
815                RefCell::new(vec![]),
816                RefCell::new(vec![]),
817                None.into(),
818            )))),
819            NodeInner::Element(p, qn, _, _, ns) => {
820                let new = Rc::new(Node(NodeInner::Element(
821                    p.clone(),
822                    qn.clone(),
823                    RefCell::new(BTreeMap::new()),
824                    RefCell::new(vec![]),
825                    ns.clone(),
826                )));
827                unattached(self, new.clone());
828                Ok(new)
829            }
830            NodeInner::Attribute(p, qn, v) => Ok(Rc::new(Node(NodeInner::Attribute(
831                p.clone(),
832                qn.clone(),
833                v.clone(),
834            )))),
835            NodeInner::Text(p, v) => {
836                let new = Rc::new(Node(NodeInner::Text(p.clone(), v.clone())));
837                unattached(&self.parent().unwrap(), new.clone());
838                Ok(new)
839            }
840            NodeInner::Comment(p, v) => {
841                let new = Rc::new(Node(NodeInner::Comment(p.clone(), v.clone())));
842                unattached(&self.parent().unwrap(), new.clone());
843                Ok(new)
844            }
845            NodeInner::ProcessingInstruction(p, qn, v) => {
846                let new = Rc::new(Node(NodeInner::ProcessingInstruction(
847                    p.clone(),
848                    qn.clone(),
849                    v.clone(),
850                )));
851                unattached(&self.parent().unwrap(), new.clone());
852                Ok(new)
853            }
854            NodeInner::Namespace(p, pre, uri, in_scope) => {
855                let new = Rc::new(Node(NodeInner::Namespace(
856                    p.clone(),
857                    pre.clone(),
858                    uri.clone(),
859                    *in_scope,
860                )));
861                unattached(&self.parent().unwrap(), new.clone());
862                Ok(new)
863            }
864        }
865    }
866    fn deep_copy(&self) -> Result<Self, Error> {
867        let mut new = self.shallow_copy()?;
868        self.attribute_iter().try_for_each(|a| {
869            new.add_attribute(a.deep_copy()?)?;
870            Ok(())
871        })?;
872        self.child_iter().try_for_each(|c| {
873            new.push(c.deep_copy()?)?;
874            Ok(())
875        })?;
876        Ok(new)
877    }
878    // For special character escaping rules, see section 3.4.
879    fn get_canonical(&self) -> Result<Self, Error> {
880        match &self.0 {
881            NodeInner::Document(_, e, _, _) => {
882                let mut result = self.shallow_copy()?;
883                for n in e.borrow().iter() {
884                    if let Ok(rn) = n.get_canonical() {
885                        result.push(rn)?
886                    }
887                }
888                Ok(result)
889            }
890            NodeInner::ProcessingInstruction(_, _, _) => self.shallow_copy(),
891            NodeInner::Comment(_, _) | NodeInner::Namespace(_, _, _, _) => Err(Error::new(
892                ErrorKind::TypeError,
893                "invalid node type".to_string(),
894            )),
895            NodeInner::Text(_, _) => self.shallow_copy(),
896            NodeInner::Attribute(_, _, _) => self.shallow_copy(),
897            NodeInner::Element(_, _, _, _, _) => {
898                let mut result = self.shallow_copy()?;
899
900                let d = result.owner_document();
901                self.attribute_iter().try_for_each(|a| {
902                    //Replace any number of spaces with a single space.
903                    let re = Regex::new(r"\s+").unwrap();
904                    result.add_attribute(
905                        d.new_attribute(
906                            a.name().unwrap(),
907                            Rc::new(Value::from(
908                                re.replace_all(a.clone().value().to_string().trim(), " ")
909                                    .to_string(),
910                            )),
911                        )?,
912                    )?;
913                    //result.add_attribute(a.get_canonical()?)?;
914                    Ok::<(), Error>(())
915                })?;
916
917                self.child_iter().try_for_each(|c| {
918                    if let Ok(rn) = c.get_canonical() {
919                        result.push(rn)?
920                    }
921                    Ok::<(), Error>(())
922                })?;
923
924                Ok(result)
925            }
926        }
927    }
928    fn set_xmldecl(&mut self, decl: XMLDecl) -> Result<(), Error> {
929        match &self.0 {
930            NodeInner::Document(x, _, _, _) => {
931                *x.borrow_mut() = Some(decl);
932                Ok(())
933            }
934            // TODO: traverse to the document node
935            _ => Err(Error::new(
936                ErrorKind::TypeError,
937                String::from("not a Document node"),
938            )),
939        }
940    }
941    fn xmldecl(&self) -> XMLDecl {
942        match &self.0 {
943            NodeInner::Document(d, _, _, _) => d
944                .borrow()
945                .clone()
946                .map_or_else(|| XMLDeclBuilder::new().build(), |x| x.clone()),
947            _ => self.owner_document().xmldecl(),
948        }
949    }
950
951    fn is_id(&self) -> bool {
952        match &self.0 {
953            //TODO Add Element XML ID support
954            NodeInner::Attribute(_, _, v) => matches!(v.as_ref().value, ValueData::ID(_)),
955            _ => false,
956        }
957    }
958
959    fn is_idrefs(&self) -> bool {
960        match &self.0 {
961            //TODO Add Element XML ID REF support
962            NodeInner::Attribute(_, _, v) => {
963                matches!(v.as_ref().value, ValueData::IDREF(_) | ValueData::IDREFS(_))
964            }
965            _ => false,
966        }
967    }
968
969    fn get_dtd(&self) -> Option<DTD> {
970        match &self.0 {
971            NodeInner::Document(_, _, _, dtd) => dtd.borrow().clone(),
972            _ => self.owner_document().get_dtd(),
973        }
974    }
975
976    fn set_dtd(&self, dtd: DTD) -> Result<(), Error> {
977        match &self.0 {
978            NodeInner::Document(_, _, _, d) => {
979                *d.borrow_mut() = Some(dtd);
980                Ok(())
981            }
982            // TODO: traverse to the document node
983            _ => Err(Error::new(
984                ErrorKind::TypeError,
985                String::from("not a Document node"),
986            )),
987        }
988    }
989
990    fn validate(&self, sch: Schema) -> Result<(), ValidationError> {
991        crate::validators::validate(self, sch)
992    }
993}
994
995impl Debug for Node {
996    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
997        match &self.0 {
998            NodeInner::Document(_, _, _, _) => write!(f, "document"),
999            NodeInner::Element(_, qn, ats, _, _) => {
1000                let attrs = ats.borrow();
1001                write!(
1002                    f,
1003                    "element-type node \"{}\"@[{}]",
1004                    qn,
1005                    format_attrs(&attrs.clone())
1006                )
1007            }
1008            NodeInner::Attribute(_, qn, _) => {
1009                write!(f, "attribute-type node \"{}\"", qn)
1010            }
1011            NodeInner::Text(_, v) => write!(f, "text-type node \"{}\"", v),
1012            NodeInner::Comment(_, v) => write!(f, "comment-type node \"{}\"", v),
1013            NodeInner::ProcessingInstruction(_, qn, _) => {
1014                write!(f, "PI-type node \"{}\"", qn)
1015            }
1016            NodeInner::Namespace(_, pre, uri, in_scope) => {
1017                write!(
1018                    f,
1019                    "namespace-type node \"{}:{}\" (in-scope: {})",
1020                    pre.clone().map_or("".to_string(), |v| v.to_string()),
1021                    uri.to_string(),
1022                    in_scope
1023                )
1024            }
1025        }
1026    }
1027}
1028
1029fn format_attrs(ats: &BTreeMap<QName, RNode>) -> String {
1030    let mut result = String::new();
1031    ats.iter()
1032        .for_each(|(k, v)| result.push_str(format!(" {}='{}'", k, v.to_string()).as_str()));
1033    result
1034}
1035
1036// Debugging aid - produce a detailed view of the given document
1037pub fn dump_tree(d: &RNode) -> String {
1038    if let NodeInner::Document(decl, children, _, dtd) = &d.0 {
1039        format!(
1040            "XML Declaration: {:?}\nDTD: {:?}\n{}",
1041            decl.borrow(),
1042            dtd.borrow(),
1043            dump_tree_children(children.borrow().clone(), 0)
1044        )
1045    } else {
1046        String::from("supply a Document node")
1047    }
1048}
1049fn dump_tree_children(cv: Vec<RNode>, indent: usize) -> String {
1050    let mut result = String::new();
1051    cv.iter().for_each(|c| {
1052        result.push('\n');
1053        (0..indent).for_each(|_| result.push(' '));
1054        match &c.0 {
1055            NodeInner::Document(_, _, _, _) => result.push_str("child node cannot be a Document"),
1056            NodeInner::Element(_parent, qn, attrs, children, nsd) => {
1057                result.push_str(format!("Element node \"{:?}\"\n", qn).as_str());
1058                (0..indent + 4).for_each(|_| result.push(' '));
1059                result.push_str("Attributes: ");
1060                attrs.borrow().iter().for_each(|(_, a)| {
1061                    result.push_str(format!(" {:?}={}", a.name().unwrap(), a.value()).as_str())
1062                });
1063                result.push('\n');
1064                (0..indent + 4).for_each(|_| result.push(' '));
1065                result.push_str("Namespace declarations: ");
1066                nsd.borrow().iter().for_each(|(_, ns)| {
1067                    result.push_str(
1068                        format!(
1069                            " xmlns:{:?}={}",
1070                            ns.as_namespace_prefix().unwrap(),
1071                            ns.as_namespace_uri().unwrap().to_string()
1072                        )
1073                        .as_str(),
1074                    )
1075                });
1076                result.push('\n');
1077                (0..indent + 4).for_each(|_| result.push(' '));
1078                result.push_str("Content:\n");
1079                result.push_str(dump_tree_children(children.borrow().clone(), indent + 2).as_str())
1080            }
1081            NodeInner::Text(_parent, val) => {
1082                result.push_str(format!("Text node \"{}\"", val).as_str())
1083            }
1084            NodeInner::Comment(_parent, val) => {
1085                result.push_str(format!("Comment node \"{}\"", val).as_str())
1086            }
1087            NodeInner::ProcessingInstruction(_parent, name, val) => {
1088                result.push_str(format!("PI node \"{}\"-\"{}\"", name, val).as_str())
1089            }
1090            _ => result.push_str("shouldn't have attribute or namespace nodes here"),
1091        }
1092    });
1093
1094    result
1095}
1096
1097// Put the given node in the unattached list for the document "d".
1098// This is for use when the node is newly created.
1099fn unattached(d: &RNode, n: RNode) {
1100    // Is it already in the unattached list? If so then do nothing
1101    match &d.0 {
1102        NodeInner::Document(_, _, u, _) => {
1103            if u.borrow().iter().any(|f| f.is_same(&n)) {
1104                return;
1105            }
1106            u.borrow_mut().push(n.clone());
1107            make_parent(n.clone(), d.clone());
1108        }
1109        NodeInner::Element(_, _, _, _, _) => {
1110            let doc = d.owner_document();
1111            if let NodeInner::Document(_, _, u, _) = &doc.0 {
1112                if u.borrow().iter().any(|f| f.is_same(&n)) {
1113                    return;
1114                }
1115                u.borrow_mut().push(n.clone());
1116                make_parent(n.clone(), doc.clone());
1117            } else {
1118                panic!("cannot find document node")
1119            }
1120        }
1121        _ => panic!("not a document node"),
1122    }
1123}
1124// Make the parent of the node be the given new parent.
1125fn make_parent(n: RNode, b: RNode) {
1126    match &n.0 {
1127        NodeInner::Element(p, _, _, _, _)
1128        | NodeInner::Attribute(p, _, _)
1129        | NodeInner::Text(p, _)
1130        | NodeInner::Comment(p, _)
1131        | NodeInner::Namespace(p, _, _, _)
1132        | NodeInner::ProcessingInstruction(p, _, _) => *p.borrow_mut() = Rc::downgrade(&b),
1133        _ => panic!("unable to change parent"),
1134    }
1135}
1136// Remove an unattached node from the unattached list.
1137// This is in preparation for it being added to the tree.
1138fn detach(n: RNode) {
1139    match &n.0 {
1140        NodeInner::Element(p, _, _, _, _)
1141        | NodeInner::Attribute(p, _, _)
1142        | NodeInner::Text(p, _)
1143        | NodeInner::Comment(p, _)
1144        | NodeInner::Namespace(p, _, _, _)
1145        | NodeInner::ProcessingInstruction(p, _, _) => {
1146            let doc = Weak::upgrade(&p.borrow()).unwrap();
1147            match &doc.0 {
1148                NodeInner::Document(_, _, u, _) => {
1149                    let i = u.borrow().iter().position(|x| Rc::ptr_eq(x, &n));
1150                    if let Some(i) = i {
1151                        u.borrow_mut().remove(i);
1152                    }
1153                }
1154                _ => panic!("not a document"),
1155            }
1156        }
1157        _ => panic!("unable to change parent"),
1158    }
1159}
1160
1161fn push_node(parent: &RNode, child: RNode) -> Result<(), Error> {
1162    if child.node_type() == NodeType::Attribute || child.node_type() == NodeType::Document {
1163        return Err(Error::new(
1164            ErrorKind::TypeError,
1165            String::from("cannot append an attribute or document node as a child node"),
1166        ));
1167    }
1168    match &parent.0 {
1169        NodeInner::Document(_, c, _, _) => {
1170            c.borrow_mut().push(child.clone());
1171        }
1172        NodeInner::Element(_, _, _, c, _) => {
1173            c.borrow_mut().push(child.clone());
1174        }
1175        _ => {
1176            return Err(Error::new(
1177                ErrorKind::TypeError,
1178                String::from("unable to add child node"),
1179            ));
1180        }
1181    }
1182    make_parent(child, parent.clone());
1183    Ok(())
1184}
1185
1186// Find the document order of ancestors
1187fn doc_order(n: &RNode) -> Vec<usize> {
1188    match &n.0 {
1189        NodeInner::Document(_, _, _, _) => vec![1usize],
1190        NodeInner::Attribute(_, _, _) => {
1191            let mut a = doc_order(&n.parent().unwrap());
1192            a.push(2);
1193            a
1194        }
1195        NodeInner::Namespace(_, _, _, _) => {
1196            let mut a = doc_order(&n.parent().unwrap());
1197            a.push(2);
1198            a
1199        }
1200        NodeInner::Element(p, _, _, _, _)
1201        | NodeInner::Text(p, _)
1202        | NodeInner::Comment(p, _)
1203        | NodeInner::ProcessingInstruction(p, _, _) => match Weak::upgrade(&p.borrow()) {
1204            Some(q) => {
1205                // TODO: this may occur in a temporary tree
1206                let idx = find_index(&q, n).unwrap_or(0);
1207                //.expect("unable to locate node in parent");
1208                let mut a = doc_order(&q);
1209                a.push(idx + 2);
1210                a
1211            }
1212            None => vec![1usize],
1213        },
1214    }
1215}
1216
1217// Find the position of this node in the parent's child list.
1218fn find_index(parent: &RNode, child: &RNode) -> Result<usize, Error> {
1219    let idx = match &parent.0 {
1220        NodeInner::Document(_, c, _, _) | NodeInner::Element(_, _, _, c, _) => {
1221            c.borrow().iter().enumerate().fold(None, |mut acc, (i, v)| {
1222                if Rc::ptr_eq(child, v) {
1223                    acc = Some(i)
1224                    // TODO: stop here
1225                }
1226                acc
1227            })
1228        }
1229        _ => {
1230            return Err(Error::new(
1231                ErrorKind::TypeError,
1232                String::from("parent is not an element"),
1233            ));
1234        }
1235    };
1236    idx.ok_or(Error::new(
1237        ErrorKind::Unknown,
1238        std::string::String::from("unable to find child"),
1239    ))
1240}
1241
1242/// Resolve the node's name (a [QName]) to a prefixed name.
1243/// If the QName has no Namespace URI then the returned string will be an unprefixed name.
1244/// Otherwise, the in-scope namespaces are used to find the prefix.
1245/// Nodes that don't have a name return an empty string.
1246fn to_prefixed_name(n: &RNode) -> String {
1247    match &n.0 {
1248        NodeInner::Element(_, qn, _, _, _) | NodeInner::Attribute(_, qn, _) => {
1249            let ns = qn.namespace_uri();
1250            if ns.is_none() {
1251                // Unprefixed name
1252                qn.local_name().to_string()
1253            } else {
1254                let uns = ns.unwrap();
1255                n.namespace_iter()
1256                    .find(|m| m.ns_uri().unwrap() == uns)
1257                    .map_or_else(
1258                        || panic!("unable to find namespace"),
1259                        |p| {
1260                            p.ns_prefix().map_or_else(
1261                                || qn.local_name().to_string(),
1262                                |q| format!("{}:{}", q.to_string(), qn.local_name().to_string()),
1263                            )
1264                        },
1265                    )
1266            }
1267        }
1268        _ => String::new(),
1269    }
1270}
1271
1272// This handles the XML serialisation of the document.
1273// "indent" is the current level of indentation.
1274fn to_xml_int(
1275    node: &RNode,
1276    od: &OutputDefinition,
1277    indent: usize,
1278    ns_in_scope: Vec<NamespaceUri>,
1279) -> String {
1280    match &node.0 {
1281        NodeInner::Document(_, _, _, _) => {
1282            node.child_iter().fold(String::new(), |mut result, c| {
1283                result.push_str(to_xml_int(&c, od, indent + 2, ns_in_scope.clone()).as_str());
1284                result
1285            })
1286        }
1287        NodeInner::Element(_, _qn, _, _, ns) => {
1288            let mut new_in_scope = ns_in_scope.clone();
1289            let mut result = String::from("<");
1290            result.push_str(to_prefixed_name(node).as_str());
1291
1292            // Namespace declarations
1293            ns.borrow().iter().for_each(|(_, nsd)| {
1294                if !ns_in_scope
1295                    .iter()
1296                    .any(|insns| insns == nsd.as_namespace_uri().unwrap())
1297                {
1298                    let nsd_nsuri = nsd.as_namespace_uri().unwrap();
1299                    new_in_scope.push(nsd_nsuri.clone());
1300                    let decl = nsd.as_namespace_prefix().unwrap().map_or_else(
1301                        || format!(" xmlns='{}'", nsd_nsuri.to_string()),
1302                        |p| format!(" xmlns:{}='{}'", p.to_string(), nsd_nsuri.to_string()),
1303                    );
1304                    result.push_str(decl.as_str());
1305                }
1306            });
1307
1308            // Attributes
1309            node.attribute_iter().for_each(|a| {
1310                result.push_str(
1311                    format!(" {}='{}'", to_prefixed_name(&a), serialise(&a.value())).as_str(),
1312                )
1313            });
1314
1315            // deal with the empty element case and emit a self-closing tag e.g. <tag/> instead of <tag></tag>
1316            if node.first_child().is_none() {
1317                result.push_str("/>");
1318                return result;
1319            }
1320
1321            result.push('>');
1322
1323            // Content of the element.
1324            // If the indent option is enabled, then if no child is a text node then add spacing.
1325            let do_indent: bool = od
1326                .get_indent()
1327                .then(|| {
1328                    node.child_iter().fold(true, |mut acc, c| {
1329                        if acc && c.node_type() == NodeType::Text {
1330                            acc = false
1331                        }
1332                        acc
1333                    })
1334                })
1335                .is_some_and(|b| b);
1336
1337            node.child_iter().for_each(|c| {
1338                if do_indent {
1339                    result.push('\n');
1340                    (0..indent).for_each(|_| result.push(' '))
1341                }
1342                result.push_str(to_xml_int(&c, od, indent + 2, new_in_scope.clone()).as_str())
1343            });
1344            if do_indent && indent > 1 {
1345                result.push('\n');
1346                (0..(indent - 2)).for_each(|_| result.push(' '))
1347            }
1348            result.push_str("</");
1349            result.push_str(to_prefixed_name(node).as_str());
1350            result.push('>');
1351            result
1352        }
1353        NodeInner::Text(_, v) => serialise(v),
1354        NodeInner::Comment(_, v) => {
1355            let mut result = String::from("<!--");
1356            result.push_str(v.to_string().as_str());
1357            result.push_str("-->");
1358            result
1359        }
1360        NodeInner::ProcessingInstruction(_, qn, v) => {
1361            let mut result = String::from("<?");
1362            result.push_str(qn.to_string().as_str());
1363            result.push(' ');
1364            result.push_str(v.to_string().as_str());
1365            result.push_str("?>");
1366            result
1367        }
1368        _ => String::new(),
1369    }
1370}
1371
1372// Serialise a [Value]. If necessary, perform output escaping
1373fn serialise(v: &Rc<Value>) -> String {
1374    if v.output == OutputSpec::NoEscape {
1375        v.to_string()
1376    } else {
1377        // Escape special characters
1378        v.to_string()
1379            .replace("&", "&amp;")
1380            .replace("'", "&apos;")
1381            .replace('"', "&quot;")
1382            .replace("<", "&lt;")
1383            .replace(">", "&gt;")
1384    }
1385}
1386
1387pub struct Children {
1388    v: Vec<RNode>,
1389    i: usize,
1390}
1391impl Children {
1392    fn new(n: &RNode) -> Self {
1393        match &n.0 {
1394            NodeInner::Document(_, c, _, _) | NodeInner::Element(_, _, _, c, _) => Children {
1395                v: c.borrow().clone(),
1396                i: 0,
1397            },
1398            _ => Children { v: vec![], i: 0 },
1399        }
1400    }
1401}
1402impl Iterator for Children {
1403    type Item = RNode;
1404
1405    fn next(&mut self) -> Option<RNode> {
1406        match self.v.get(self.i) {
1407            Some(c) => {
1408                self.i += 1;
1409                Some(c.clone())
1410            }
1411            None => None,
1412        }
1413    }
1414}
1415
1416pub struct Ancestors {
1417    cur: RNode,
1418}
1419
1420impl Ancestors {
1421    fn new(n: &RNode) -> Self {
1422        Ancestors { cur: n.clone() }
1423    }
1424}
1425
1426impl Iterator for Ancestors {
1427    type Item = RNode;
1428
1429    fn next(&mut self) -> Option<RNode> {
1430        let parent = match &self.cur.0 {
1431            NodeInner::Document(_, _, _, _) => None,
1432            NodeInner::Element(p, _, _, _, _)
1433            | NodeInner::Attribute(p, _, _)
1434            | NodeInner::Text(p, _)
1435            | NodeInner::Comment(p, _)
1436            | NodeInner::ProcessingInstruction(p, _, _)
1437            | NodeInner::Namespace(p, _, _, _) => Weak::upgrade(&p.borrow()),
1438        };
1439        parent.inspect(|q| {
1440            self.cur = q.clone();
1441        })
1442    }
1443}
1444
1445// This implementation eagerly constructs a list of nodes to traverse.
1446// A better approach would be to lazily traverse the descendants.
1447pub struct Descendants {
1448    v: Vec<RNode>,
1449    cur: usize,
1450}
1451impl Descendants {
1452    fn new(n: &RNode) -> Self {
1453        Descendants {
1454            v: n.child_iter().fold(vec![], |mut acc, c| {
1455                let mut d = descendant_add(&c);
1456                acc.append(&mut d);
1457                acc
1458            }),
1459            cur: 0,
1460        }
1461    }
1462}
1463fn descendant_add(n: &RNode) -> Vec<RNode> {
1464    let mut result = vec![n.clone()];
1465    n.child_iter().for_each(|c| {
1466        let mut l = descendant_add(&c);
1467        result.append(&mut l);
1468    });
1469    result
1470}
1471impl Iterator for Descendants {
1472    type Item = RNode;
1473
1474    fn next(&mut self) -> Option<RNode> {
1475        match self.v.get(self.cur) {
1476            Some(n) => {
1477                self.cur += 1;
1478                Some(n.clone())
1479            }
1480            None => None,
1481        }
1482    }
1483}
1484
1485// Store the parent node and the index of the child node that we want the sibling of.
1486pub struct Siblings(RNode, usize, i32);
1487impl Siblings {
1488    fn new(n: &RNode, dir: i32) -> Self {
1489        match n.parent() {
1490            Some(p) => {
1491                find_index(&p, n).map_or_else(
1492                    |_| {
1493                        // Something has gone wrong, so iterator will just return None
1494                        // TODO: improve handling of this situation - e.g. current node is an attribute
1495                        Siblings(n.clone(), 0, -1)
1496                    },
1497                    |i| Siblings(p.clone(), i, dir),
1498                )
1499            }
1500            None => {
1501                // Document nodes don't have siblings
1502                Siblings(n.clone(), 0, -1)
1503            }
1504        }
1505    }
1506}
1507impl Iterator for Siblings {
1508    type Item = RNode;
1509
1510    fn next(&mut self) -> Option<RNode> {
1511        if self.1 == 0 && self.2 < 0 {
1512            None
1513        } else {
1514            let newidx = if self.2 < 0 {
1515                self.1 - self.2.wrapping_abs() as usize
1516            } else {
1517                self.1 + self.2 as usize
1518            };
1519            if let NodeInner::Element(_, _, _, children, _) = &self.0.0 {
1520                match children.borrow().get(newidx) {
1521                    Some(n) => {
1522                        self.1 = newidx;
1523                        Some(n.clone())
1524                    }
1525                    None => None,
1526                }
1527            } else {
1528                None
1529            }
1530        }
1531    }
1532}
1533
1534pub struct Attributes {
1535    it: Option<<BTreeMap<QName, RNode> as IntoIterator>::IntoIter>,
1536}
1537impl Attributes {
1538    fn new(n: &RNode) -> Self {
1539        if let NodeInner::Element(_, _, attributes, _, _) = &n.0 {
1540            let b = attributes.borrow();
1541            Attributes {
1542                it: Some(b.clone().into_iter()),
1543            }
1544        } else {
1545            // Other types of nodes don't have attributes, so always return None
1546            Attributes { it: None }
1547        }
1548    }
1549}
1550impl Iterator for Attributes {
1551    type Item = RNode;
1552
1553    fn next(&mut self) -> Option<RNode> {
1554        self.it.as_mut().and_then(|i| i.next().map(|(_, n)| n))
1555    }
1556}
1557
1558// Return the in-scope namespaces
1559pub struct NamespaceNodes {
1560    //in_scope: Vec<NamespaceUri>, // namespaces that are already in scope, masking outer declarations
1561    cur_element: RNode,
1562    ancestor_it: Box<dyn Iterator<Item = RNode>>,
1563    ns_it: Option<IntoIter<Option<NamespacePrefix>, RNode>>,
1564    descoped: Vec<Option<NamespacePrefix>>, // Namespaces that have been descoped
1565    xmlns: bool,                            // The undeclared, but always in-scope, "xml" namespace
1566}
1567
1568impl NamespaceNodes {
1569    fn new(n: RNode) -> Self {
1570        match &n.0 {
1571            NodeInner::Document(_, _, _, _) => {
1572                let top = n.child_iter().find(|c| c.node_type() == NodeType::Element);
1573                if let Some(t) = top {
1574                    NamespaceNodes::new(t)
1575                } else {
1576                    NamespaceNodes {
1577                        //in_scope: vec![],
1578                        cur_element: n.clone(),
1579                        ancestor_it: n.clone().ancestor_iter(),
1580                        ns_it: None,
1581                        descoped: vec![],
1582                        xmlns: false,
1583                    }
1584                }
1585            }
1586            NodeInner::Element(_, _, _, _, ns) => {
1587                let nsit = ns.borrow().clone().into_iter();
1588                NamespaceNodes {
1589                    //in_scope: vec![],
1590                    cur_element: n.clone(),
1591                    ancestor_it: n.clone().ancestor_iter(),
1592                    ns_it: Some(nsit),
1593                    descoped: vec![],
1594                    xmlns: false,
1595                }
1596            }
1597            _ => {
1598                eprintln!("Namespace Nodes: n {:?}", n);
1599                NamespaceNodes {
1600                    //in_scope: vec![],
1601                    cur_element: n.parent().unwrap(),
1602                    ancestor_it: n.parent().unwrap().ancestor_iter(),
1603                    ns_it: None,
1604                    descoped: vec![],
1605                    xmlns: false,
1606                }
1607            }
1608        }
1609    }
1610}
1611impl Iterator for NamespaceNodes {
1612    type Item = RNode;
1613
1614    fn next(&mut self) -> Option<RNode> {
1615        find_ns(self).or_else(|| {
1616            if self.xmlns {
1617                None
1618            } else {
1619                self.xmlns = true;
1620                Some(
1621                    self.cur_element
1622                        .owner_document()
1623                        // TODO: setup a LazyLock value to avoid repeatedly parsing fixed values
1624                        .new_namespace(
1625                            NamespaceUri::try_from("http://www.w3.org/XML/1998/namespace").unwrap(),
1626                            Some(NamespacePrefix::try_from("xml").unwrap()),
1627                            true,
1628                        )
1629                        .expect("unable to create namespace node"),
1630                )
1631            }
1632        })
1633    }
1634}
1635// Recursively ascend the ancestors looking for the first namespace node
1636fn find_ns(nn: &mut NamespaceNodes) -> Option<RNode> {
1637    if nn.cur_element.node_type() == NodeType::Element {
1638        if nn.ns_it.is_some() {
1639            // Iterating through the current element's namespace declarations
1640            let mut nsiter = nn.ns_it.take().unwrap();
1641            match nsiter.next() {
1642                Some((p, n)) => {
1643                    // Is this a descope ns node?
1644                    if nn.descoped.iter().any(|nsp| *nsp == p) {
1645                        // This namespace has been descoped, so skip it
1646                        nn.ns_it = Some(nsiter);
1647                        find_ns(nn)
1648                    } else if n.ns_in_scope() {
1649                        nn.ns_it = Some(nsiter);
1650                        Some(n.clone())
1651                    } else {
1652                        nn.descoped.push(p);
1653                        nn.ns_it = Some(nsiter);
1654                        find_ns(nn)
1655                    }
1656                }
1657                None => {
1658                    // Move to the parent
1659                    nn.ns_it = None;
1660                    match nn.ancestor_it.next() {
1661                        Some(c) => {
1662                            nn.cur_element = c;
1663                            // nn.ns_it = None; take() has already done this
1664                            find_ns(nn)
1665                        }
1666                        None => None,
1667                    }
1668                }
1669            }
1670        } else {
1671            // Haven't looked at this element's namespaces yet
1672            if let NodeInner::Element(_, _, _, _, ns) = &nn.cur_element.0 {
1673                let mut nsiter = ns.borrow().clone().into_iter();
1674                match nsiter.next() {
1675                    Some((p, n)) => {
1676                        // Is this a descope ns node?
1677                        if nn.descoped.iter().any(|nsp| *nsp == p) {
1678                            // This namespace has been descoped, so skip it
1679                            nn.ns_it = Some(nsiter);
1680                            find_ns(nn)
1681                        } else if n.ns_in_scope() {
1682                            nn.ns_it = Some(nsiter);
1683                            Some(n.clone())
1684                        } else {
1685                            nn.descoped.push(p);
1686                            nn.ns_it = Some(nsiter);
1687                            find_ns(nn)
1688                        }
1689                    }
1690                    None => {
1691                        nn.ns_it = None;
1692                        match nn.ancestor_it.next() {
1693                            Some(b) => {
1694                                nn.cur_element = b;
1695                                find_ns(nn)
1696                            }
1697                            None => None,
1698                        }
1699                    }
1700                }
1701            } else {
1702                // can't happen
1703                None
1704            }
1705        }
1706    } else {
1707        None
1708    }
1709}
1710
1711#[cfg(test)]
1712mod tests {
1713    use super::*;
1714    use crate::xmldecl::XMLDeclBuilder;
1715
1716    #[test]
1717    fn smite_new() {
1718        let _ = Node::new();
1719        assert!(true)
1720    }
1721
1722    #[test]
1723    fn smite_xmldecl() {
1724        let mut d = Rc::new(Node::new());
1725        let x = XMLDeclBuilder::new().version(String::from("1.1")).build();
1726        d.set_xmldecl(x).expect("unable to set XML Declaration");
1727        assert!(true)
1728    }
1729    #[test]
1730    fn smite_element_1() {
1731        let mut root = Rc::new(Node::new());
1732        let c = root
1733            .new_element(QName::try_from("Test").expect("not a QName"))
1734            .expect("unable to create element node");
1735        root.push(c).expect("unable to add node");
1736        assert_eq!(root.to_xml(), "<Test/>")
1737    }
1738    #[test]
1739    fn smite_element_2() {
1740        let mut root = Rc::new(Node::new());
1741        let mut child1 = root
1742            .new_element(QName::try_from("Test").expect("not a QName"))
1743            .expect("unable to create element node");
1744        root.push(child1.clone()).expect("unable to add node");
1745        let child2 = child1
1746            .new_element(QName::try_from("MoreTest").expect("not a QName"))
1747            .expect("unable to create child element");
1748        child1.push(child2).expect("unable to add node");
1749        assert_eq!(root.to_xml(), "<Test><MoreTest/></Test>")
1750    }
1751
1752    #[test]
1753    fn smite_generate_id_1() {
1754        let mut root = Rc::new(Node::new());
1755        let mut child1 = root
1756            .new_element(QName::try_from("Test").expect("not a QName"))
1757            .expect("unable to create element node");
1758        root.push(child1.clone()).expect("unable to add node");
1759        let child2 = child1
1760            .new_element(QName::try_from("MoreTest").expect("not a QName"))
1761            .expect("unable to create child element");
1762        child1.push(child2.clone()).expect("unable to add node");
1763        assert_ne!(child1.get_id(), child2.get_id())
1764    }
1765
1766    #[test]
1767    fn smite_attached_1() {
1768        let mut root = Rc::new(Node::new());
1769        let child1 = root
1770            .new_element(QName::from_local_name(NcName::try_from("Test").unwrap()))
1771            .expect("unable to create element node");
1772        assert_eq!(child1.is_attached(), false);
1773        root.push(child1.clone()).expect("unable to add node");
1774        assert_eq!(child1.is_attached(), true);
1775        assert_eq!(root.child_iter().count(), 1)
1776    }
1777
1778    #[test]
1779    fn smite_ns_1() {
1780        let root = Rc::new(Node::new());
1781        assert_eq!(root.namespace_iter().count(), 1)
1782    }
1783    #[test]
1784    fn smite_ns_2() {
1785        let mut root = Rc::new(Node::new());
1786        let child1 = root
1787            .new_element(QName::from_local_name(NcName::try_from("Test").unwrap()))
1788            .expect("unable to create element node");
1789        root.push(child1.clone()).expect("unable to add node");
1790        assert_eq!(root.namespace_iter().count(), 1)
1791    }
1792}