sxd_document/
dom.rs

1//! A traditional DOM tree interface for navigating and manipulating
2//! XML documents.
3
4use std::{fmt,hash};
5
6use super::QName;
7use super::raw;
8
9type SiblingFn<T> = unsafe fn(&raw::Connections, T) -> raw::SiblingIter;
10
11/// An XML document
12#[derive(Copy,Clone)]
13pub struct Document<'d> {
14    storage: &'d raw::Storage,
15    connections: &'d raw::Connections,
16}
17
18macro_rules! wrapper(
19    ($name:ident, $wrapper:ident, $inner:ty) => (
20        fn $name(self, node: *mut $inner) -> $wrapper<'d> {
21            $wrapper {
22                document: self,
23                node: node,
24            }
25        }
26    )
27);
28
29impl<'d> Document<'d> {
30    wrapper!(wrap_root, Root, raw::Root);
31    wrapper!(wrap_element, Element, raw::Element);
32    wrapper!(wrap_attribute, Attribute, raw::Attribute);
33    wrapper!(wrap_text, Text, raw::Text);
34    wrapper!(wrap_comment, Comment, raw::Comment);
35    wrapper!(wrap_pi, ProcessingInstruction, raw::ProcessingInstruction);
36
37    #[doc(hidden)]
38    pub fn new(storage: &'d raw::Storage, connections: &'d raw::Connections) -> Document<'d> {
39        Document {
40            storage: storage,
41            connections: connections,
42        }
43    }
44
45    fn wrap_parent_of_child(self, node: raw::ParentOfChild) -> ParentOfChild<'d> {
46        match node {
47            raw::ParentOfChild::Root(n) => ParentOfChild::Root(self.wrap_root(n)),
48            raw::ParentOfChild::Element(n) => ParentOfChild::Element(self.wrap_element(n)),
49        }
50    }
51
52    fn wrap_child_of_root(self, node: raw::ChildOfRoot) -> ChildOfRoot<'d> {
53        match node {
54            raw::ChildOfRoot::Element(n) => ChildOfRoot::Element(self.wrap_element(n)),
55            raw::ChildOfRoot::Comment(n) => ChildOfRoot::Comment(self.wrap_comment(n)),
56            raw::ChildOfRoot::ProcessingInstruction(n) => ChildOfRoot::ProcessingInstruction(self.wrap_pi(n)),
57        }
58    }
59
60    fn wrap_child_of_element(self, node: raw::ChildOfElement) -> ChildOfElement<'d> {
61        match node {
62            raw::ChildOfElement::Element(n) => ChildOfElement::Element(self.wrap_element(n)),
63            raw::ChildOfElement::Text(n) => ChildOfElement::Text(self.wrap_text(n)),
64            raw::ChildOfElement::Comment(n) => ChildOfElement::Comment(self.wrap_comment(n)),
65            raw::ChildOfElement::ProcessingInstruction(n) => ChildOfElement::ProcessingInstruction(self.wrap_pi(n)),
66        }
67    }
68
69    pub fn root(self) -> Root<'d> {
70        self.wrap_root(self.connections.root())
71    }
72
73    pub fn create_element<'n, N>(self, name: N) -> Element<'d>
74        where N: Into<QName<'n>>
75    {
76        self.wrap_element(self.storage.create_element(name))
77    }
78
79    pub fn create_text(self, text: &str) -> Text<'d> {
80        self.wrap_text(self.storage.create_text(text))
81    }
82
83    pub fn create_comment(self, text: &str) -> Comment<'d> {
84        self.wrap_comment(self.storage.create_comment(text))
85    }
86
87    pub fn create_processing_instruction(self, target: &str, value: Option<&str>) -> ProcessingInstruction<'d> {
88        self.wrap_pi(self.storage.create_processing_instruction(target, value))
89    }
90
91    fn siblings<T>(self, f: SiblingFn<T>, node: T) -> Vec<ChildOfElement<'d>> {
92        // This is safe because we don't allow the connection
93        // information to leak outside of this method.
94        unsafe {
95            f(self.connections, node).map(|n| self.wrap_child_of_element(n)).collect()
96        }
97    }
98}
99
100impl<'d> PartialEq for Document<'d> {
101    fn eq(&self, other: &Document<'d>) -> bool {
102        (self.storage as *const raw::Storage, self.connections as *const raw::Connections)
103            == (other.storage as *const raw::Storage, other.connections as *const raw::Connections)
104    }
105}
106
107impl<'d> fmt::Debug for Document<'d> {
108    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
109        write!(f, "Document {{ {:?} }}", self as *const Document)
110    }
111}
112
113macro_rules! node(
114    ($name:ident, $raw:ty, $doc:expr) => (
115        #[doc = $doc]
116        #[derive(Copy,Clone)]
117        pub struct $name<'d> {
118            document: Document<'d>,
119            node: *mut $raw,
120        }
121
122        impl<'d> $name<'d> {
123            #[allow(dead_code)]
124            fn node(&self) -> &'d $raw { unsafe { &*self.node } }
125
126            pub fn document(&self) -> Document<'d> { self.document }
127        }
128
129        impl<'d> PartialEq for $name<'d> {
130            fn eq(&self, other: &$name<'d>) -> bool {
131                self.node == other.node
132            }
133        }
134
135        impl<'d> Eq for $name<'d> {}
136
137        impl<'d> hash::Hash for $name<'d> {
138            fn hash<H>(&self, state: &mut H)
139                where H: hash::Hasher
140            {
141                self.node.hash(state)
142            }
143        }
144    )
145);
146
147node!(
148    Root, raw::Root,
149    "The logical ancestor of every other node type"
150);
151
152impl<'d> Root<'d> {
153    pub fn append_child<C>(&self, child: C)
154        where C: Into<ChildOfRoot<'d>>
155    {
156        let child = child.into();
157        self.document.connections.append_root_child(child.as_raw());
158    }
159
160    pub fn append_children<I>(&self, children: I)
161        where I: IntoIterator,
162              I::Item: Into<ChildOfRoot<'d>>,
163    {
164        for c in children {
165            self.append_child(c.into());
166        }
167    }
168
169    pub fn replace_children<I>(&self, children: I)
170        where I: IntoIterator,
171              I::Item: Into<ChildOfRoot<'d>>,
172    {
173        self.clear_children();
174        self.append_children(children);
175    }
176
177    pub fn remove_child<C>(&self, child: C)
178        where C: Into<ChildOfRoot<'d>>,
179    {
180        let child = child.into();
181        self.document.connections.remove_root_child(child.as_raw())
182    }
183
184    pub fn clear_children(&self) {
185        self.document.connections.clear_root_children();
186    }
187
188    pub fn children(&self) -> Vec<ChildOfRoot<'d>> {
189        // This is safe because we copy of the children, and the
190        // children are never deallocated.
191        unsafe {
192            self.document.connections.root_children().iter().map(|n| {
193                self.document.wrap_child_of_root(*n)
194            }).collect()
195        }
196    }
197}
198
199impl<'d> fmt::Debug for Root<'d> {
200    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
201        write!(f, "Root")
202    }
203}
204
205/// A mapping from a prefix to a URI
206pub struct Namespace<'d> {
207    prefix: &'d str,
208    uri: &'d str,
209}
210
211impl<'d> Namespace<'d> {
212    pub fn prefix(&self) -> &'d str { self.prefix }
213    pub fn uri(&self) -> &'d str { self.uri }
214}
215
216node!(
217    Element, raw::Element,
218    "Elements are the workhorse of a document and may contain any type of
219    node, except for the Root node"
220);
221
222impl<'d> Element<'d> {
223    pub fn name(&self) -> QName<'d> { self.node().name() }
224
225    pub fn set_name<'n, N>(&self, name: N)
226        where N: Into<QName<'n>>
227    {
228        self.document.storage.element_set_name(self.node, name)
229    }
230
231    pub fn set_default_namespace_uri(&self, namespace_uri: Option<&str>) {
232        self.document.storage.element_set_default_namespace_uri(self.node, namespace_uri);
233    }
234
235    pub fn default_namespace_uri(&self) -> Option<&'d str> {
236        self.node().default_namespace_uri()
237    }
238
239    pub fn recursive_default_namespace_uri(&self) -> Option<&'d str> {
240        self.document.connections.element_default_namespace_uri(self.node)
241    }
242
243    /// Map a prefix to a namespace URI. Any existing prefix on this
244    /// element will be replaced.
245    pub fn register_prefix(&self, prefix: &str, namespace_uri: &str) {
246        self.document.storage.element_register_prefix(self.node, prefix, namespace_uri);
247    }
248
249    /// Recursively resolve the prefix to a namespace URI.
250    pub fn namespace_uri_for_prefix(&self, prefix: &str) -> Option<&'d str> {
251        self.document.connections.element_namespace_uri_for_prefix(self.node, prefix)
252    }
253
254    /// Recursively find a prefix for the namespace URI. Since
255    /// multiple prefixes may map to the same URI, `preferred` can be
256    /// provided to select a specific prefix, if it is valid.
257    pub fn prefix_for_namespace_uri(&self, namespace_uri: &str, preferred: Option<&str>)
258                                    -> Option<&'d str>
259    {
260        self.document.connections.element_prefix_for_namespace_uri(
261            self.node, namespace_uri, preferred
262        )
263    }
264
265    /// Retrieve all namespaces that are in scope, recursively walking
266    /// up the document tree.
267    pub fn namespaces_in_scope(&self) -> Vec<Namespace<'d>> {
268        self.document.connections.element_namespaces_in_scope(self.node).map(|(prefix, uri)| {
269            Namespace { prefix: prefix, uri: uri }
270        }).collect()
271    }
272
273    pub fn preferred_prefix(&self) -> Option<&'d str> {
274        self.node().preferred_prefix()
275    }
276
277    pub fn set_preferred_prefix(&self, prefix: Option<&str>) {
278        self.document.storage.element_set_preferred_prefix(self.node, prefix);
279    }
280
281    pub fn parent(&self) -> Option<ParentOfChild<'d>> {
282        self.document.connections.element_parent(self.node).map(|n| {
283            self.document.wrap_parent_of_child(n)
284        })
285    }
286
287    pub fn remove_from_parent(&self) {
288        self.document.connections.remove_element_from_parent(self.node);
289    }
290
291    pub fn append_child<C>(&self, child: C)
292        where C: Into<ChildOfElement<'d>>
293    {
294        let child = child.into();
295        self.document.connections.append_element_child(self.node, child.as_raw());
296    }
297
298    pub fn append_children<I>(&self, children: I)
299        where I: IntoIterator,
300              I::Item: Into<ChildOfElement<'d>>,
301    {
302        for c in children {
303            self.append_child(c.into());
304        }
305    }
306
307    pub fn replace_children<I>(&self, children: I)
308        where I: IntoIterator,
309              I::Item: Into<ChildOfElement<'d>>,
310    {
311        self.clear_children();
312        self.append_children(children);
313    }
314
315    pub fn remove_child<C>(&self, child: C)
316        where C: Into<ChildOfElement<'d>>,
317    {
318        let child = child.into();
319        self.document.connections.remove_element_child(self.node, child.as_raw());
320    }
321
322    pub fn clear_children(&self) {
323        self.document.connections.clear_element_children(self.node);
324    }
325
326    pub fn children(&self) -> Vec<ChildOfElement<'d>> {
327        // This is safe because we make a copy of the children, and
328        // the children are never deallocated.
329        unsafe {
330            self.document.connections.element_children(self.node).iter().map(|n| {
331                self.document.wrap_child_of_element(*n)
332            }).collect()
333        }
334    }
335
336    pub fn preceding_siblings(&self) -> Vec<ChildOfElement<'d>> {
337        self.document.siblings(raw::Connections::element_preceding_siblings, self.node)
338    }
339
340    pub fn following_siblings(&self) -> Vec<ChildOfElement<'d>> {
341        self.document.siblings(raw::Connections::element_following_siblings, self.node)
342    }
343
344    pub fn attribute<'n, N>(&self, name: N) -> Option<Attribute<'d>>
345        where N: Into<QName<'n>>
346    {
347        self.document.connections.attribute(self.node, name).map(|n| {
348            self.document.wrap_attribute(n)
349        })
350    }
351
352    pub fn attributes(&self) -> Vec<Attribute<'d>> {
353        // This is safe because we make a copy of the children, and
354        // the children are never deallocated.
355        unsafe {
356            self.document.connections.attributes(self.node).iter().map(|n| {
357                self.document.wrap_attribute(*n)
358            }).collect()
359        }
360    }
361
362    pub fn set_attribute_value<'n, N>(&self, name: N, value: &str) -> Attribute<'d>
363        where N: Into<QName<'n>>
364    {
365        let attr = self.document.storage.create_attribute(name, value);
366        self.document.connections.set_attribute(self.node, attr);
367        self.document.wrap_attribute(attr)
368    }
369
370    pub fn attribute_value<'n, N>(&self, name: N) -> Option<&'d str>
371        where N: Into<QName<'n>>
372    {
373        self.document.connections.attribute(self.node, name).map(|a| {
374            let a_r = unsafe { &*a };
375            a_r.value()
376        })
377    }
378
379    pub fn remove_attribute<'n, N>(&self, name: N)
380        where N: Into<QName<'n>>
381    {
382        self.document.connections.remove_attribute(self.node, name);
383    }
384
385    pub fn set_text(&self, text: &str) -> Text {
386        let text = self.document.create_text(text);
387        self.clear_children();
388        self.append_child(text);
389        text
390    }
391}
392
393impl<'d> fmt::Debug for Element<'d> {
394    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
395        write!(f, "Element {{ name: {:?} }}", self.name())
396    }
397}
398
399node!(
400    Attribute, raw::Attribute,
401    "Metadata about the current element"
402);
403
404impl<'d> Attribute<'d> {
405    pub fn name(&self)  -> QName<'d> { self.node().name() }
406    pub fn value(&self) -> &'d str { self.node().value() }
407
408    pub fn preferred_prefix(&self) -> Option<&'d str> {
409        self.node().preferred_prefix()
410    }
411
412    pub fn set_preferred_prefix(&self, prefix: Option<&str>) {
413        self.document.storage.attribute_set_preferred_prefix(self.node, prefix);
414    }
415
416    pub fn parent(&self) -> Option<Element<'d>> {
417        self.document.connections.attribute_parent(self.node).map(|n| {
418            self.document.wrap_element(n)
419        })
420    }
421
422    pub fn remove_from_parent(&self) {
423        self.document.connections.remove_attribute_from_parent(self.node);
424    }
425}
426
427impl<'d> fmt::Debug for Attribute<'d> {
428    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
429        write!(f, "Attribute {{ name: {:?}, value: {:?} }}", self.name(), self.value())
430    }
431}
432
433node!(
434    Text, raw::Text,
435    "Textual data"
436);
437
438impl<'d> Text<'d> {
439    pub fn text(&self) -> &'d str { self.node().text() }
440
441    pub fn set_text(&self, text: &str) {
442        self.document.storage.text_set_text(self.node, text)
443    }
444
445    pub fn parent(&self) -> Option<Element<'d>> {
446        self.document.connections.text_parent(self.node).map(|n| {
447            self.document.wrap_element(n)
448        })
449    }
450
451    pub fn remove_from_parent(&self) {
452        self.document.connections.remove_text_from_parent(self.node);
453    }
454
455    pub fn preceding_siblings(&self) -> Vec<ChildOfElement<'d>> {
456        self.document.siblings(raw::Connections::text_preceding_siblings, self.node)
457    }
458
459    pub fn following_siblings(&self) -> Vec<ChildOfElement<'d>> {
460        self.document.siblings(raw::Connections::text_following_siblings, self.node)
461    }
462}
463
464impl<'d> fmt::Debug for Text<'d> {
465    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
466        write!(f, "Text {{ text: {:?} }}", self.text())
467    }
468}
469
470node!(
471    Comment, raw::Comment,
472    "Information only relevant to humans"
473);
474
475impl<'d> Comment<'d> {
476    pub fn text(&self) -> &'d str { self.node().text() }
477
478    pub fn set_text(&self, new_text: &str) {
479        self.document.storage.comment_set_text(self.node, new_text)
480    }
481
482    pub fn parent(&self) -> Option<ParentOfChild<'d>> {
483        self.document.connections.comment_parent(self.node).map(|n| {
484            self.document.wrap_parent_of_child(n)
485        })
486    }
487
488    pub fn remove_from_parent(&self) {
489        self.document.connections.remove_comment_from_parent(self.node);
490    }
491
492    pub fn preceding_siblings(&self) -> Vec<ChildOfElement<'d>> {
493        self.document.siblings(raw::Connections::comment_preceding_siblings, self.node)
494    }
495
496    pub fn following_siblings(&self) -> Vec<ChildOfElement<'d>> {
497        self.document.siblings(raw::Connections::comment_following_siblings, self.node)
498    }
499}
500
501impl<'d> fmt::Debug for Comment<'d> {
502    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
503        write!(f, "Comment {{ text: {:?} }}", self.text())
504    }
505}
506
507node!(
508    ProcessingInstruction, raw::ProcessingInstruction,
509    "Metadata relevant to the application, but not the XML processor or humans"
510);
511
512impl<'d> ProcessingInstruction<'d> {
513    pub fn target(&self) -> &'d str { self.node().target() }
514    pub fn value(&self) -> Option<&'d str> { self.node().value() }
515
516    pub fn set_target(&self, new_target: &str) {
517        self.document.storage.processing_instruction_set_target(self.node, new_target);
518    }
519
520    pub fn set_value(&self, new_value: Option<&str>) {
521        self.document.storage.processing_instruction_set_value(self.node, new_value);
522    }
523
524    pub fn parent(&self) -> Option<ParentOfChild<'d>> {
525        self.document.connections.processing_instruction_parent(self.node).map(|n| {
526            self.document.wrap_parent_of_child(n)
527        })
528    }
529
530    pub fn remove_from_parent(&self) {
531        self.document.connections.remove_processing_instruction_from_parent(self.node);
532    }
533
534    pub fn preceding_siblings(&self) -> Vec<ChildOfElement<'d>> {
535        self.document.siblings(raw::Connections::processing_instruction_preceding_siblings, self.node)
536    }
537
538    pub fn following_siblings(&self) -> Vec<ChildOfElement<'d>> {
539        self.document.siblings(raw::Connections::processing_instruction_following_siblings, self.node)
540    }
541}
542
543impl<'d> fmt::Debug for ProcessingInstruction<'d> {
544    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
545        write!(f, "ProcessingInstruction {{ target: {:?}, value: {:?} }}", self.target(), self.value())
546    }
547}
548
549macro_rules! unpack(
550    ($enum_name:ident, $name:ident, $wrapper:ident, $inner:ident) => (
551        pub fn $name(self) -> Option<$inner<'d>> {
552            match self {
553                $enum_name::$wrapper(n) => Some(n),
554                _ => None,
555            }
556        }
557    )
558);
559
560/// Nodes that may occur as a child of the root node
561#[derive(Debug,Copy,Clone,PartialEq)]
562pub enum ChildOfRoot<'d> {
563    Element(Element<'d>),
564    Comment(Comment<'d>),
565    ProcessingInstruction(ProcessingInstruction<'d>),
566}
567
568
569impl<'d> ChildOfRoot<'d> {
570    unpack!(ChildOfRoot, element, Element, Element);
571    unpack!(ChildOfRoot, comment, Comment, Comment);
572    unpack!(ChildOfRoot, processing_instruction, ProcessingInstruction, ProcessingInstruction);
573
574    fn as_raw(&self) -> raw::ChildOfRoot {
575        match *self {
576            ChildOfRoot::Element(n) => raw::ChildOfRoot::Element(n.node),
577            ChildOfRoot::Comment(n) => raw::ChildOfRoot::Comment(n.node),
578            ChildOfRoot::ProcessingInstruction(n) => raw::ChildOfRoot::ProcessingInstruction(n.node),
579        }
580    }
581}
582
583/// Nodes that may occur as a child of an element node
584#[derive(Debug,Copy,Clone,PartialEq)]
585pub enum ChildOfElement<'d> {
586    Element(Element<'d>),
587    Text(Text<'d>),
588    Comment(Comment<'d>),
589    ProcessingInstruction(ProcessingInstruction<'d>),
590}
591
592impl<'d> ChildOfElement<'d> {
593    unpack!(ChildOfElement, element, Element, Element);
594    unpack!(ChildOfElement, text, Text, Text);
595    unpack!(ChildOfElement, comment, Comment, Comment);
596    unpack!(ChildOfElement, processing_instruction, ProcessingInstruction, ProcessingInstruction);
597
598    fn as_raw(&self) -> raw::ChildOfElement {
599        match *self {
600            ChildOfElement::Element(n) => raw::ChildOfElement::Element(n.node),
601            ChildOfElement::Text(n) => raw::ChildOfElement::Text(n.node),
602            ChildOfElement::Comment(n) => raw::ChildOfElement::Comment(n.node),
603            ChildOfElement::ProcessingInstruction(n) => raw::ChildOfElement::ProcessingInstruction(n.node),
604        }
605    }
606}
607
608/// Nodes that may occur as the parent of a child node
609#[derive(Debug,Copy,Clone,PartialEq)]
610pub enum ParentOfChild<'d> {
611    Root(Root<'d>),
612    Element(Element<'d>),
613}
614
615impl<'d> ParentOfChild<'d> {
616    unpack!(ParentOfChild, root, Root, Root);
617    unpack!(ParentOfChild, element, Element, Element);
618}
619
620macro_rules! conversion_trait(
621    ($res_type:ident, {
622        $($leaf_type:ident => $variant:expr),*
623    }) => (
624        $(impl<'d> From<$leaf_type<'d>> for $res_type<'d> {
625            fn from(v: $leaf_type<'d>) -> $res_type<'d> {
626                $variant(v)
627            }
628        })*
629
630        $(impl<'a, 'd> From<&'a $leaf_type<'d>> for $res_type<'d> {
631            fn from(v: &'a $leaf_type<'d>) -> $res_type<'d> {
632                $variant(*v)
633            }
634        })*
635    )
636);
637
638conversion_trait!(
639    ChildOfRoot, {
640        Element               => ChildOfRoot::Element,
641        Comment               => ChildOfRoot::Comment,
642        ProcessingInstruction => ChildOfRoot::ProcessingInstruction
643    }
644);
645
646conversion_trait!(
647    ChildOfElement, {
648        Element               => ChildOfElement::Element,
649        Text                  => ChildOfElement::Text,
650        Comment               => ChildOfElement::Comment,
651        ProcessingInstruction => ChildOfElement::ProcessingInstruction
652    }
653);
654
655impl<'d> From<ChildOfRoot<'d>> for ChildOfElement<'d> {
656    fn from(v: ChildOfRoot<'d>) -> ChildOfElement<'d> {
657        match v {
658            ChildOfRoot::Element(n) => ChildOfElement::Element(n),
659            ChildOfRoot::Comment(n) => ChildOfElement::Comment(n),
660            ChildOfRoot::ProcessingInstruction(n) => ChildOfElement::ProcessingInstruction(n),
661        }
662    }
663}
664
665#[cfg(test)]
666mod test {
667    use super::super::{Package,QName};
668    use super::{ChildOfRoot,ChildOfElement,ParentOfChild};
669
670    macro_rules! assert_qname_eq(
671        ($l:expr, $r:expr) => (assert_eq!(Into::<QName>::into($l), $r.into()));
672    );
673
674    #[test]
675    fn the_root_belongs_to_a_document() {
676        let package = Package::new();
677        let doc = package.as_document();
678
679        let root = doc.root();
680
681        assert_eq!(doc, root.document());
682    }
683
684    #[test]
685    fn root_can_have_element_children() {
686        let package = Package::new();
687        let doc = package.as_document();
688
689        let root = doc.root();
690        let element = doc.create_element("alpha");
691
692        root.append_child(element);
693
694        let children = root.children();
695        assert_eq!(1, children.len());
696        assert_eq!(children[0], ChildOfRoot::Element(element));
697    }
698
699    #[test]
700    fn root_has_maximum_of_one_element_child() {
701        let package = Package::new();
702        let doc = package.as_document();
703
704        let root = doc.root();
705        let alpha = doc.create_element("alpha");
706        let beta = doc.create_element("beta");
707
708        root.append_child(alpha);
709        root.append_child(beta);
710
711        let children = root.children();
712        assert_eq!(1, children.len());
713        assert_eq!(children[0], ChildOfRoot::Element(beta));
714    }
715
716    #[test]
717    fn root_can_have_comment_children() {
718        let package = Package::new();
719        let doc = package.as_document();
720
721        let root = doc.root();
722        let comment = doc.create_comment("Now is the winter of our discontent.");
723
724        root.append_child(comment);
725
726        let children = root.children();
727        assert_eq!(1, children.len());
728        assert_eq!(children[0], ChildOfRoot::Comment(comment));
729    }
730
731    #[test]
732    fn root_can_have_processing_instruction_children() {
733        let package = Package::new();
734        let doc = package.as_document();
735
736        let root = doc.root();
737        let pi = doc.create_processing_instruction("device", None);
738
739        root.append_child(pi);
740
741        let children = root.children();
742        assert_eq!(1, children.len());
743        assert_eq!(children[0], ChildOfRoot::ProcessingInstruction(pi));
744    }
745
746    #[test]
747    fn root_can_append_multiple_children() {
748        let package = Package::new();
749        let doc = package.as_document();
750
751        let root = doc.root();
752        let alpha = doc.create_comment("alpha");
753        let beta = doc.create_comment("beta");
754
755        root.append_children(&[alpha, beta]);
756
757        let children = root.children();
758        assert_eq!(2, children.len());
759        assert_eq!(children[0], ChildOfRoot::Comment(alpha));
760        assert_eq!(children[1], ChildOfRoot::Comment(beta));
761    }
762
763    #[test]
764    fn root_can_replace_children() {
765        let package = Package::new();
766        let doc = package.as_document();
767
768        let root = doc.root();
769        let alpha = doc.create_comment("alpha");
770        let beta = doc.create_comment("beta");
771        let gamma = doc.create_comment("gamma");
772        root.append_child(alpha);
773
774        root.replace_children(&[beta, gamma]);
775
776        let children = root.children();
777        assert_eq!(2, children.len());
778        assert_eq!(children[0], ChildOfRoot::Comment(beta));
779        assert_eq!(children[1], ChildOfRoot::Comment(gamma));
780    }
781
782    #[test]
783    fn root_can_remove_children() {
784        let package = Package::new();
785        let doc = package.as_document();
786
787        let root = doc.root();
788        let element = doc.create_element("alpha");
789        root.append_child(element);
790
791        root.remove_child(element);
792
793        assert!(root.children().is_empty());
794        assert!(element.parent().is_none());
795    }
796
797    #[test]
798    fn root_can_clear_children() {
799        let package = Package::new();
800        let doc = package.as_document();
801
802        let root = doc.root();
803        let element = doc.create_element("alpha");
804        root.append_child(element);
805
806        root.clear_children();
807
808        assert!(root.children().is_empty());
809        assert!(element.parent().is_none());
810    }
811
812    #[test]
813    fn root_child_knows_its_parent() {
814        let package = Package::new();
815        let doc = package.as_document();
816
817        let root = doc.root();
818        let alpha = doc.create_element("alpha");
819
820        root.append_child(alpha);
821
822        assert_eq!(Some(ParentOfChild::Root(root)), alpha.parent());
823    }
824
825    #[test]
826    fn elements_belong_to_a_document() {
827        let package = Package::new();
828        let doc = package.as_document();
829
830        let element = doc.create_element("alpha");
831
832        assert_eq!(doc, element.document());
833    }
834
835    #[test]
836    fn elements_can_have_element_children() {
837        let package = Package::new();
838        let doc = package.as_document();
839
840        let alpha = doc.create_element("alpha");
841        let beta  = doc.create_element("beta");
842
843        alpha.append_child(beta);
844
845        let children = alpha.children();
846
847        assert_eq!(children[0], ChildOfElement::Element(beta));
848    }
849
850    #[test]
851    fn elements_can_append_multiple_children() {
852        let package = Package::new();
853        let doc = package.as_document();
854
855        let alpha = doc.create_element("alpha");
856        let beta = doc.create_element("beta");
857        let gamma = doc.create_element("gamma");
858
859        alpha.append_children(&[beta, gamma]);
860
861        let children = alpha.children();
862        assert_eq!(2, children.len());
863        assert_eq!(children[0], ChildOfElement::Element(beta));
864        assert_eq!(children[1], ChildOfElement::Element(gamma));
865    }
866
867    #[test]
868    fn elements_can_replace_children() {
869        let package = Package::new();
870        let doc = package.as_document();
871
872        let alpha = doc.create_element("alpha");
873        let beta = doc.create_element("beta");
874        let gamma = doc.create_element("gamma");
875        let zeta = doc.create_element("zeta");
876        alpha.append_child(zeta);
877
878        alpha.replace_children(&[beta, gamma]);
879
880        let children = alpha.children();
881        assert_eq!(2, children.len());
882        assert_eq!(children[0], ChildOfElement::Element(beta));
883        assert_eq!(children[1], ChildOfElement::Element(gamma));
884    }
885
886    #[test]
887    fn elements_can_remove_children() {
888        let package = Package::new();
889        let doc = package.as_document();
890
891        let alpha = doc.create_element("alpha");
892        let beta  = doc.create_element("beta");
893        alpha.append_child(beta);
894
895        alpha.remove_child(beta);
896
897        assert!(alpha.children().is_empty());
898        assert!(beta.parent().is_none());
899    }
900
901    #[test]
902    fn elements_can_be_removed_from_parent() {
903        let package = Package::new();
904        let doc = package.as_document();
905
906        let alpha = doc.create_element("alpha");
907        let beta  = doc.create_element("beta");
908        alpha.append_child(beta);
909
910        beta.remove_from_parent();
911
912        assert!(alpha.children().is_empty());
913        assert!(beta.parent().is_none());
914    }
915
916    #[test]
917    fn elements_can_clear_children() {
918        let package = Package::new();
919        let doc = package.as_document();
920
921        let alpha = doc.create_element("alpha");
922        let beta  = doc.create_element("beta");
923        alpha.append_child(beta);
924
925        alpha.clear_children();
926
927        assert!(alpha.children().is_empty());
928        assert!(beta.parent().is_none());
929    }
930
931    #[test]
932    fn element_children_are_ordered() {
933        let package = Package::new();
934        let doc = package.as_document();
935
936        let greek = doc.create_element("greek");
937        let alpha = doc.create_element("alpha");
938        let omega = doc.create_element("omega");
939
940        greek.append_child(alpha);
941        greek.append_child(omega);
942
943        let children = greek.children();
944
945        assert_eq!(children[0], ChildOfElement::Element(alpha));
946        assert_eq!(children[1], ChildOfElement::Element(omega));
947    }
948
949    #[test]
950    fn element_children_know_their_parent() {
951        let package = Package::new();
952        let doc = package.as_document();
953
954        let alpha = doc.create_element("alpha");
955        let beta  = doc.create_element("beta");
956
957        alpha.append_child(beta);
958
959        assert_eq!(Some(ParentOfChild::Element(alpha)), beta.parent());
960    }
961
962    #[test]
963    fn elements_know_preceding_siblings() {
964        let package = Package::new();
965        let doc = package.as_document();
966
967        let parent = doc.create_element("parent");
968        let a = doc.create_element("a");
969        let b = doc.create_element("b");
970        let c = doc.create_element("c");
971        let d = doc.create_element("d");
972
973        parent.append_child(a);
974        parent.append_child(b);
975        parent.append_child(c);
976        parent.append_child(d);
977
978        assert_eq!(vec![ChildOfElement::Element(a), ChildOfElement::Element(b)], c.preceding_siblings());
979    }
980
981    #[test]
982    fn elements_know_following_siblings() {
983        let package = Package::new();
984        let doc = package.as_document();
985
986        let parent = doc.create_element("parent");
987        let a = doc.create_element("a");
988        let b = doc.create_element("b");
989        let c = doc.create_element("c");
990        let d = doc.create_element("d");
991
992        parent.append_child(a);
993        parent.append_child(b);
994        parent.append_child(c);
995        parent.append_child(d);
996
997        assert_eq!(vec![ChildOfElement::Element(c), ChildOfElement::Element(d)], b.following_siblings());
998    }
999
1000    #[test]
1001    fn changing_parent_of_element_removes_element_from_original_parent() {
1002        let package = Package::new();
1003        let doc = package.as_document();
1004
1005        let parent1 = doc.create_element("parent1");
1006        let parent2 = doc.create_element("parent2");
1007        let child = doc.create_element("child");
1008
1009        parent1.append_child(child);
1010        parent2.append_child(child);
1011
1012        assert!(parent1.children().is_empty());
1013        assert_eq!(1, parent2.children().len());
1014    }
1015
1016    #[test]
1017    fn elements_can_be_renamed() {
1018        let package = Package::new();
1019        let doc = package.as_document();
1020
1021        let alpha = doc.create_element("alpha");
1022        alpha.set_name("beta");
1023        assert_qname_eq!(alpha.name(), "beta");
1024    }
1025
1026    #[test]
1027    fn elements_know_in_scope_namespaces() {
1028        let package = Package::new();
1029        let doc = package.as_document();
1030
1031        let element = doc.create_element("alpha");
1032        element.register_prefix("a", "uri");
1033
1034        let nses = element.namespaces_in_scope();
1035        assert_eq!(2, nses.len());
1036
1037        let xml_ns = nses.iter().find(|ns| ns.prefix() == "xml").unwrap();
1038        assert_eq!("http://www.w3.org/XML/1998/namespace", xml_ns.uri());
1039
1040        let a_ns = nses.iter().find(|ns| ns.prefix() == "a").unwrap();
1041        assert_eq!("uri", a_ns.uri());
1042    }
1043
1044    #[test]
1045    fn elements_in_scope_namespaces_override_parents_with_the_same_prefix() {
1046        let package = Package::new();
1047        let doc = package.as_document();
1048
1049        let parent = doc.create_element("parent");
1050        parent.register_prefix("prefix", "uri1");
1051
1052        let child = doc.create_element("child");
1053        child.register_prefix("prefix", "uri2");
1054
1055        parent.append_child(child);
1056
1057        let nses = child.namespaces_in_scope();
1058        assert_eq!(2, nses.len());
1059
1060        let ns = nses.iter().find(|ns| ns.prefix() == "prefix").unwrap();
1061        assert_eq!("uri2", ns.uri());
1062    }
1063
1064    #[test]
1065    fn attributes_belong_to_a_document() {
1066        let package = Package::new();
1067        let doc = package.as_document();
1068
1069        let element = doc.create_element("alpha");
1070        let attr = element.set_attribute_value("hello", "world");
1071
1072        assert_eq!(doc, attr.document());
1073    }
1074
1075    #[test]
1076    fn elements_have_attributes() {
1077        let package = Package::new();
1078        let doc = package.as_document();
1079
1080        let element = doc.create_element("element");
1081
1082        element.set_attribute_value("hello", "world");
1083
1084        assert_eq!(Some("world"), element.attribute_value("hello"));
1085    }
1086
1087    #[test]
1088    fn attributes_know_their_element() {
1089        let package = Package::new();
1090        let doc = package.as_document();
1091
1092        let element = doc.create_element("element");
1093        let attr = element.set_attribute_value("hello", "world");
1094
1095        assert_eq!(Some(element), attr.parent());
1096    }
1097
1098    #[test]
1099    fn attributes_can_be_reset() {
1100        let package = Package::new();
1101        let doc = package.as_document();
1102
1103        let element = doc.create_element("element");
1104
1105        element.set_attribute_value("hello", "world");
1106        element.set_attribute_value("hello", "galaxy");
1107
1108        assert_eq!(Some("galaxy"), element.attribute_value("hello"));
1109    }
1110
1111    #[test]
1112    fn attributes_can_be_removed() {
1113        let package = Package::new();
1114        let doc = package.as_document();
1115
1116        let element = doc.create_element("element");
1117        let attribute = element.set_attribute_value("hello", "world");
1118
1119        element.remove_attribute("hello");
1120
1121        assert!(element.attribute("hello").is_none());
1122        assert!(attribute.parent().is_none());
1123    }
1124
1125    #[test]
1126    fn attributes_can_be_removed_from_parent() {
1127        let package = Package::new();
1128        let doc = package.as_document();
1129
1130        let element = doc.create_element("element");
1131        let attribute = element.set_attribute_value("hello", "world");
1132
1133        attribute.remove_from_parent();
1134
1135        assert!(element.attribute("hello").is_none());
1136        assert!(attribute.parent().is_none());
1137    }
1138
1139    #[test]
1140    fn attributes_can_be_iterated() {
1141        let package = Package::new();
1142        let doc = package.as_document();
1143
1144        let element = doc.create_element("element");
1145
1146        element.set_attribute_value("name1", "value1");
1147        element.set_attribute_value("name2", "value2");
1148
1149        let mut attrs = element.attributes();
1150        attrs.sort_by(|a, b| a.name().namespace_uri().cmp(&b.name().namespace_uri()));
1151
1152        assert_eq!(2, attrs.len());
1153        assert_qname_eq!("name1",  attrs[0].name());
1154        assert_eq!("value1", attrs[0].value());
1155        assert_qname_eq!("name2",  attrs[1].name());
1156        assert_eq!("value2", attrs[1].value());
1157    }
1158
1159    #[test]
1160    fn text_belongs_to_a_document() {
1161        let package = Package::new();
1162        let doc = package.as_document();
1163
1164        let text = doc.create_text("Now is the winter of our discontent.");
1165
1166        assert_eq!(doc, text.document());
1167    }
1168
1169    #[test]
1170    fn elements_can_have_text_children() {
1171        let package = Package::new();
1172        let doc = package.as_document();
1173
1174        let sentence = doc.create_element("sentence");
1175        let text = doc.create_text("Now is the winter of our discontent.");
1176
1177        sentence.append_child(text);
1178
1179        let children = sentence.children();
1180        assert_eq!(1, children.len());
1181        assert_eq!(children[0], ChildOfElement::Text(text));
1182    }
1183
1184    #[test]
1185    fn elements_can_set_text() {
1186        let package = Package::new();
1187        let doc = package.as_document();
1188
1189        let sentence = doc.create_element("sentence");
1190        let quote = "Now is the winter of our discontent.";
1191        let text = sentence.set_text(quote);
1192
1193        let children = sentence.children();
1194        assert_eq!(1, children.len());
1195        assert_eq!(children[0], ChildOfElement::Text(text));
1196        assert_eq!(children[0].text().unwrap().text(), quote);
1197    }
1198
1199    #[test]
1200    fn text_knows_its_parent() {
1201        let package = Package::new();
1202        let doc = package.as_document();
1203
1204        let sentence = doc.create_element("sentence");
1205        let text = doc.create_text("Now is the winter of our discontent.");
1206
1207        sentence.append_child(text);
1208
1209        assert_eq!(text.parent(), Some(sentence));
1210    }
1211
1212    #[test]
1213    fn text_can_be_removed_from_parent() {
1214        let package = Package::new();
1215        let doc = package.as_document();
1216
1217        let sentence = doc.create_element("sentence");
1218        let text = doc.create_text("Now is the winter of our discontent.");
1219        sentence.append_child(text);
1220
1221        text.remove_from_parent();
1222
1223        assert!(sentence.children().is_empty());
1224        assert!(text.parent().is_none());
1225    }
1226
1227    #[test]
1228    fn text_knows_preceding_siblings() {
1229        let package = Package::new();
1230        let doc = package.as_document();
1231
1232        let parent = doc.create_element("parent");
1233        let a = doc.create_element("a");
1234        let b = doc.create_text("b");
1235
1236        parent.append_child(a);
1237        parent.append_child(b);
1238
1239        assert_eq!(vec![ChildOfElement::Element(a)], b.preceding_siblings());
1240    }
1241
1242    #[test]
1243    fn text_knows_following_siblings() {
1244        let package = Package::new();
1245        let doc = package.as_document();
1246
1247        let parent = doc.create_element("parent");
1248        let a = doc.create_text("a");
1249        let b = doc.create_element("b");
1250
1251        parent.append_child(a);
1252        parent.append_child(b);
1253
1254        assert_eq!(vec![ChildOfElement::Element(b)], a.following_siblings());
1255    }
1256
1257    #[test]
1258    fn text_can_be_changed() {
1259        let package = Package::new();
1260        let doc = package.as_document();
1261
1262        let text = doc.create_text("Now is the winter of our discontent.");
1263
1264        text.set_text("Made glorious summer by this sun of York");
1265
1266        assert_eq!(text.text(), "Made glorious summer by this sun of York");
1267    }
1268
1269    #[test]
1270    fn comment_belongs_to_a_document() {
1271        let package = Package::new();
1272        let doc = package.as_document();
1273
1274        let comment = doc.create_comment("Now is the winter of our discontent.");
1275
1276        assert_eq!(doc, comment.document());
1277    }
1278
1279    #[test]
1280    fn elements_can_have_comment_children() {
1281        let package = Package::new();
1282        let doc = package.as_document();
1283
1284        let sentence = doc.create_element("sentence");
1285        let comment = doc.create_comment("Now is the winter of our discontent.");
1286
1287        sentence.append_child(comment);
1288
1289        let children = sentence.children();
1290        assert_eq!(1, children.len());
1291        assert_eq!(children[0], ChildOfElement::Comment(comment));
1292    }
1293
1294    #[test]
1295    fn comment_knows_its_parent() {
1296        let package = Package::new();
1297        let doc = package.as_document();
1298
1299        let sentence = doc.create_element("sentence");
1300        let comment = doc.create_comment("Now is the winter of our discontent.");
1301
1302        sentence.append_child(comment);
1303
1304        assert_eq!(comment.parent(), Some(ParentOfChild::Element(sentence)));
1305    }
1306
1307    #[test]
1308    fn comments_can_be_removed_from_parent() {
1309        let package = Package::new();
1310        let doc = package.as_document();
1311
1312        let sentence = doc.create_element("sentence");
1313        let comment = doc.create_comment("Now is the winter of our discontent.");
1314        sentence.append_child(comment);
1315
1316        comment.remove_from_parent();
1317
1318        assert!(sentence.children().is_empty());
1319        assert!(comment.parent().is_none());
1320    }
1321
1322    #[test]
1323    fn comment_knows_preceding_siblings() {
1324        let package = Package::new();
1325        let doc = package.as_document();
1326
1327        let parent = doc.create_element("parent");
1328        let a = doc.create_element("a");
1329        let b = doc.create_comment("b");
1330
1331        parent.append_child(a);
1332        parent.append_child(b);
1333
1334        assert_eq!(vec![ChildOfElement::Element(a)], b.preceding_siblings());
1335    }
1336
1337    #[test]
1338    fn comment_knows_following_siblings() {
1339        let package = Package::new();
1340        let doc = package.as_document();
1341
1342        let parent = doc.create_element("parent");
1343        let a = doc.create_comment("a");
1344        let b = doc.create_element("b");
1345
1346        parent.append_child(a);
1347        parent.append_child(b);
1348
1349        assert_eq!(vec![ChildOfElement::Element(b)], a.following_siblings());
1350    }
1351
1352    #[test]
1353    fn comment_can_be_changed() {
1354        let package = Package::new();
1355        let doc = package.as_document();
1356
1357        let comment = doc.create_comment("Now is the winter of our discontent.");
1358
1359        comment.set_text("Made glorious summer by this sun of York");
1360
1361        assert_eq!(comment.text(), "Made glorious summer by this sun of York");
1362    }
1363
1364    #[test]
1365    fn processing_instruction_belongs_to_a_document() {
1366        let package = Package::new();
1367        let doc = package.as_document();
1368
1369        let pi = doc.create_processing_instruction("device", None);
1370
1371        assert_eq!(doc, pi.document());
1372    }
1373
1374    #[test]
1375    fn elements_can_have_processing_instruction_children() {
1376        let package = Package::new();
1377        let doc = package.as_document();
1378
1379        let element = doc.create_element("element");
1380        let pi = doc.create_processing_instruction("device", None);
1381
1382        element.append_child(pi);
1383
1384        let children = element.children();
1385        assert_eq!(1, children.len());
1386        assert_eq!(children[0], ChildOfElement::ProcessingInstruction(pi));
1387    }
1388
1389    #[test]
1390    fn processing_instruction_knows_its_parent() {
1391        let package = Package::new();
1392        let doc = package.as_document();
1393
1394        let element = doc.create_element("element");
1395        let pi = doc.create_processing_instruction("device", None);
1396
1397        element.append_child(pi);
1398
1399        assert_eq!(pi.parent(), Some(ParentOfChild::Element(element)));
1400    }
1401
1402
1403    #[test]
1404    fn processing_instruction_can_be_removed_from_parent() {
1405        let package = Package::new();
1406        let doc = package.as_document();
1407
1408        let element = doc.create_element("element");
1409        let pi = doc.create_processing_instruction("device", None);
1410        element.append_child(pi);
1411
1412        pi.remove_from_parent();
1413
1414        assert!(element.children().is_empty());
1415        assert!(pi.parent().is_none());
1416    }
1417
1418    #[test]
1419    fn processing_instruction_knows_preceding_siblings() {
1420        let package = Package::new();
1421        let doc = package.as_document();
1422
1423        let parent = doc.create_element("parent");
1424        let a = doc.create_element("a");
1425        let b = doc.create_processing_instruction("b", None);
1426
1427        parent.append_child(a);
1428        parent.append_child(b);
1429
1430        assert_eq!(vec![ChildOfElement::Element(a)], b.preceding_siblings());
1431    }
1432
1433    #[test]
1434    fn processing_instruction_knows_following_siblings() {
1435        let package = Package::new();
1436        let doc = package.as_document();
1437
1438        let parent = doc.create_element("parent");
1439        let a = doc.create_processing_instruction("a", None);
1440        let b = doc.create_element("b");
1441
1442        parent.append_child(a);
1443        parent.append_child(b);
1444
1445        assert_eq!(vec![ChildOfElement::Element(b)], a.following_siblings());
1446    }
1447
1448    #[test]
1449    fn processing_instruction_can_be_changed() {
1450        let package = Package::new();
1451        let doc = package.as_document();
1452
1453        let pi = doc.create_processing_instruction("device", None);
1454
1455        pi.set_target("output");
1456        pi.set_value(Some("full-screen"));
1457
1458        assert_eq!(pi.target(), "output");
1459        assert_eq!(pi.value(), Some("full-screen"));
1460    }
1461
1462    #[test]
1463    fn can_return_a_populated_package() {
1464        fn populate() -> Package {
1465            let package = Package::new();
1466            {
1467                let doc = package.as_document();
1468
1469                let element = doc.create_element("hello");
1470                doc.root().append_child(element);
1471            }
1472
1473            package
1474        }
1475
1476        let package = populate();
1477        let doc = package.as_document();
1478        let element = doc.root().children()[0].element().unwrap();
1479        assert_qname_eq!(element.name(), "hello");
1480    }
1481
1482    #[test]
1483    #[cfg(feature = "compile_failure")]
1484    fn nodes_cannot_live_outside_of_the_document() {
1485        let package = Package::new();
1486
1487        let _ = {
1488            let doc = package.as_document();
1489
1490            doc.create_element("hello")
1491        };
1492    }
1493}