use std::convert::TryFrom;
use std::collections::HashMap;
use std::collections::hash_map::Iter;
use generational_arena::{Arena, Index};
use crate::qname::QualifiedName;
use crate::output::OutputDefinition;
use crate::xdmerror::{Error, ErrorKind};
use crate::value::Value;
use crate::item::NodeType;
#[derive(Clone)]
pub struct Forest {
a: Vec<Tree>,
}
pub type TreeIndex = usize;
impl Forest {
pub fn new() -> Forest {
Forest{a: vec![]}
}
pub fn plant_tree(&mut self) -> TreeIndex {
let i = self.a.len();
self.a.push(Tree::new(i));
i
}
pub fn get_ref(&self, i: TreeIndex) -> Option<&Tree> {
self.a.get(i)
}
pub fn get_ref_mut(&mut self, i: TreeIndex) -> Option<&mut Tree> {
self.a.get_mut(i)
}
pub fn grow_tree(&mut self, s: &str) -> Result<TreeIndex, Error> {
Result::Err(Error::new(ErrorKind::NotImplemented, String::from("not implemented yet")))
}
}
#[derive(Clone)]
pub struct Tree {
i: TreeIndex, a: Arena<NodeContent>,
d: Index, }
impl Tree
{
pub fn new(i: TreeIndex) -> Self {
let mut a = Arena::new();
let d = a.insert(
NodeBuilder::new(NodeType::Document).build()
);
Tree {
i: i,
a: a,
d: d,
}
}
fn get(&self, i: Index) -> Option<&NodeContent> {
self.a.get(i)
}
fn get_mut(&mut self, i: Index) -> Option<&mut NodeContent> {
self.a.get_mut(i)
}
pub fn get_doc_node(&self) -> Node {
Node::new(self.d, self.i)
}
pub fn push_doc_node(&mut self, n: Node) -> Result<(), Error> {
self.get_mut(n.0).unwrap().parent = Some(Node::new(self.d, self.i));
self.get_mut(self.d)
.map_or_else(
|| Result::Err(Error::new(ErrorKind::Unknown, String::from("no document node"))),
|e| {
e.children.push(n);
Ok(())
}
)
}
pub fn new_element(&mut self, name: QualifiedName) -> Result<Node, Error> {
Ok(
Node::new(
self.a
.insert(NodeBuilder::new(NodeType::Element).name(name).build()),
self.i
)
)
}
pub fn new_text(&mut self, c: Value) -> Result<Node, Error> {
Ok(
Node::new(
self.a
.insert(NodeBuilder::new(NodeType::Text).value(c).build()),
self.i
)
)
}
pub fn new_attribute(&mut self, name: QualifiedName, v: Value) -> Result<Node, Error> {
Ok(
Node::new(
self.a
.insert(
NodeBuilder::new(NodeType::Attribute)
.name(name)
.value(v)
.build()
),
self.i
)
)
}
pub fn new_comment(&mut self, v: Value) -> Result<Node, Error> {
Ok(
Node::new(
self.a
.insert(NodeBuilder::new(NodeType::Comment).value(v).build()),
self.i
),
)
}
pub fn new_processing_instruction(&mut self, name: QualifiedName, v: Value) -> Result<Node, Error> {
Ok(
Node::new(self.a
.insert(
NodeBuilder::new(NodeType::ProcessingInstruction)
.name(name)
.value(v)
.build()
),
self.i
),
)
}
}
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct Node(Index, TreeIndex);
impl Node {
fn new(i: Index, t: TreeIndex) -> Self {
Node(i, t)
}
fn get<'a>(&self, f: &'a Forest) -> Option<&'a NodeContent> {
f.get_ref(self.1).unwrap().get(self.0)
}
pub fn fmt_debug(&self, f: &Forest) -> String {
let mut result = String::from(self.node_type(f).to_string());
result.push_str("-type node");
match self.node_type(f) {
NodeType::Element => {
result.push_str(" \"");
result.push_str(self.to_name(f).to_string().as_str());
result.push_str("\"");
}
NodeType::Text => {
result.push_str(" \"");
result.push_str(self.to_value(f).to_string().as_str()); result.push_str("\"");
}
_ => {} }
result
}
pub fn to_string(&self, f: &Forest) -> String {
match f.get_ref(self.1) {
Some(e) => e,
None => return String::from(""),
};
match self.node_type(f) {
NodeType::Element => {
String::new()
}
NodeType::Text |
NodeType::Attribute |
NodeType::Comment => {
self.get(f).unwrap().value().as_ref().map_or(
String::new(),
|v| v.to_string()
)
}
_ => String::new(),
}
}
pub fn to_xml(&self, f: &Forest) -> String {
let mut ns: HashMap<String, Option<String>> = HashMap::new();
self.to_xml_int(f, &OutputDefinition::new(), 0, &mut ns)
}
fn to_xml_int(
&self,
f: &Forest,
od: &OutputDefinition,
indent: usize,
ns: &mut HashMap<String, Option<String>>
) -> String {
let d = match f.get_ref(self.1) {
Some(e) => e,
None => return String::from(""),
};
let nc = match d.get(self.0) {
Some(e) => e,
None => return String::from(""),
};
match nc.node_type() {
NodeType::Element => {
let mut result = String::from("<");
let name = nc.name().as_ref().unwrap();
let mut newns: Vec<(Option<String>, String)> = vec![];
if let Some(uri) = name.get_nsuri() {
match name.get_prefix() {
Some(p) => {
match ns.get(uri.as_str()) {
Some(op) => {
match op {
Some(q) => {
if p != *q {
ns.insert(uri.clone(), Some(p.clone()));
newns.push((Some(p), uri));
} }
None => {
ns.insert(uri.clone(), Some(p.clone()));
newns.push((Some(p), uri));
}
}
}
None => {
ns.insert(uri.clone(), Some(p.clone()));
newns.push((Some(p), uri));
}
}
}
None => {
match ns.get(uri.as_str()) {
Some(_) => {
ns.insert(uri.clone(), None);
newns.push((None, uri));
}
None => {
}
}
}
}
}
result.push_str(name.to_string().as_str());
newns.iter().for_each(|(p, u)| {
result.push_str(" xmlns");
if let Some(q) = p {
result.push(':');
result.push_str(q.as_str());
}
result.push_str("='");
result.push_str(u);
result.push('\'');
});
nc.attributes.iter().for_each(|(k, v)| {
if let Some(uri) = k.get_nsuri() {
if ns.get(uri.as_str()).is_none() {
ns.insert(uri.clone(), k.get_prefix());
result.push_str(" xmlns:");
result.push_str(k.get_prefix().unwrap().as_str());
result.push_str("='");
result.push_str(uri.as_str());
result.push('\'');
}
}
result.push(' ');
result.push_str(k.to_string().as_str());
result.push_str("='");
result.push_str(v.to_string(f).as_str());
result.push('\'');
});
result.push_str(">");
let do_indent: bool = if od.get_indent() {
let mut acc = true;
let mut children = self.child_iter();
loop {
match children.next(f) {
Some(c) => {
if c.node_type(f) == NodeType::Text {
acc = false
}
}
None => break,
}
}
acc
} else {
false
};
let mut children = self.child_iter();
loop {
match children.next(f) {
Some(c) => {
if do_indent {
result.push('\n');
(0..indent).for_each(|_| result.push(' '));
};
result.push_str(c.to_xml_int(f, od, indent, ns).as_str());
}
None => break,
}
};
if do_indent {
result.push('\n');
(0..(indent - 2)).for_each(|_| result.push(' '));
};
result.push_str("</");
result.push_str(name.to_string().as_str());
result.push_str(">");
result
}
NodeType::Text => {
nc.value().as_ref().unwrap().to_string()
}
NodeType::Comment => {
let mut result = String::from("<!--");
result.push_str(nc.value().as_ref().unwrap().to_string().as_str());
result.push_str("-->");
result
}
NodeType::ProcessingInstruction => {
let mut result = String::from("<?");
result.push_str(nc.name().as_ref().unwrap().to_string().as_str());
result.push(' ');
result.push_str(nc.value().as_ref().unwrap().to_string().as_str());
result.push_str("?>");
result
}
_ => {
String::from("-- not implemented --")
}
}
}
pub fn to_xml_with_options(&self, f: &Forest, od: &OutputDefinition) -> String {
let mut ns: HashMap<String, Option<String>> = HashMap::new();
self.to_xml_int(f, od, 2, &mut ns)
}
pub fn to_json(&self, _f: &Forest) -> String {
String::from("not implemented yet")
}
pub fn to_int(&self, f: &Forest) -> Result<i64, Error> {
self.to_string(f).parse::<i64>()
.map_err(|e| Error::new(ErrorKind::Unknown, e.to_string()))
}
pub fn to_double(&self, f: &Forest) -> f64 {
match self.to_string(f).parse::<f64>() {
Ok(g) => g,
Err(_) => f64::NAN,
}
}
pub fn to_name(&self, f: &Forest) -> QualifiedName {
f.get_ref(self.1)
.map_or(
QualifiedName::new(None, None, String::from("")),
|d| d.get(self.0)
.map_or(
QualifiedName::new(None, None, String::from("")),
|o| o.name().as_ref().map_or(
QualifiedName::new(None, None, String::from("")),
|p| p.clone(),
)
),
)
}
pub fn to_value(&self, f: &Forest) -> Value {
f.get_ref(self.1)
.map_or(
Value::from(""),
|d| d.get(self.0)
.map_or(
Value::from(""),
|o| o.value().as_ref().map_or(
Value::from(""),
|p| p.clone()
)
)
)
}
pub fn node_type(&self, f: &Forest) -> NodeType {
f.get_ref(self.1)
.map_or(
NodeType::Unknown,
|d| d.get(self.0)
.map_or(
NodeType::Unknown,
|m| m.node_type(),
),
)
}
pub fn append_child(&self, f: &mut Forest, c: Node) -> Result<(), Error> {
if self.node_type(f) != NodeType::Element {
return Result::Err(Error::new(
ErrorKind::Unknown,
String::from("must be an element"),
));
}
if c.node_type(f) == NodeType::Attribute {
return Result::Err(Error::new(
ErrorKind::Unknown,
String::from("cannot append an attribute as a child"),
));
}
if self.1 == c.1 {
c.remove(f)?;
f.get_ref_mut(self.1)
.ok_or(Error::new(
ErrorKind::Unknown,
String::from("unable to find tree"),
))?
.get_mut(c.0)
.ok_or(Error::new(
ErrorKind::Unknown,
String::from("unable to find node"),
))?
.parent = Some(self.clone());
f.get_ref_mut(self.1)
.ok_or(Error::new(
ErrorKind::Unknown,
String::from("unable to find tree"),
))?
.get_mut(self.0)
.ok_or(Error::new(
ErrorKind::Unknown,
String::from("unable to find node"),
))?
.children.push(c);
} else {
let cp = c.deep_copy(f, Some(self.1))?;
f.get_ref_mut(self.1)
.ok_or(Error::new(
ErrorKind::Unknown,
String::from("unable to find tree"),
))?
.get_mut(cp.0)
.ok_or(Error::new(
ErrorKind::Unknown,
String::from("unable to find node"),
))?
.parent = Some(self.clone());
f.get_ref_mut(self.1)
.ok_or(Error::new(
ErrorKind::Unknown,
String::from("unable to find tree"),
))?
.get_mut(self.0)
.ok_or(Error::new(
ErrorKind::Unknown,
String::from("unable to find node"),
))?
.children.push(cp);
}
Ok(())
}
pub fn insert_before(&self, f: &mut Forest, insert: Node) -> Result<(), Error> {
let p = self.parent(f)
.ok_or(Error::new(ErrorKind::Unknown, String::from("unable to insert before document node")))?;
if self.1 == insert.1 {
insert.remove(f)?;
let d = f.get_ref_mut(self.1)
.ok_or(Error::new(
ErrorKind::Unknown,
String::from("unable to find tree"),
))?;
let cl = &mut d.get_mut(p.0).unwrap().children;
let i = cl.iter()
.enumerate()
.skip_while(|(_, x)| x.0 != self.0)
.nth(0)
.map(|(e, _)| e)
.unwrap();
cl.insert(i, insert);
d.get_mut(insert.0).unwrap().parent = Some(p);
} else {
let d = f.get_ref(self.1)
.ok_or(Error::new(
ErrorKind::Unknown,
String::from("unable to find tree"),
))?;
let i = d.get(p.0).unwrap().children.iter()
.enumerate()
.skip_while(|(_, x)| x.0 != self.0)
.nth(0)
.map(|(e, _)| e)
.unwrap();
let cp = insert.deep_copy(f, Some(self.1))?;
let clm = &mut f.get_ref_mut(self.1)
.ok_or(Error::new(
ErrorKind::Unknown,
String::from("unable to find tree"),
))?
.get_mut(p.0).unwrap().children;
clm.insert(i, cp);
f.get_ref_mut(self.1)
.ok_or(Error::new(
ErrorKind::Unknown,
String::from("unable to find tree"),
))?
.get_mut(cp.0).unwrap().parent = Some(p);
}
Ok(())
}
pub fn remove(&self, f: &mut Forest) -> Result<(), Error> {
let d = f.get_ref_mut(self.1)
.ok_or(Error::new(
ErrorKind::Unknown,
String::from("unable to find tree"),
))?;
let p = match d.get(self.0).unwrap().parent {
Some(q) => q.0,
None => return Ok(()),
};
let cl = &mut d.get_mut(p).unwrap().children;
let i = cl.iter()
.enumerate()
.skip_while(|(_, x)| x.0 != self.0)
.nth(0)
.map(|(e, _)| e)
.unwrap();
cl.remove(i);
d.get_mut(self.0).unwrap().parent = None;
Ok(())
}
pub fn add_attribute(&self, f: &mut Forest, a: Node) -> Result<(), Error> {
if self.node_type(f) != NodeType::Element {
return Result::Err(Error::new(
ErrorKind::Unknown,
String::from("must be an element"),
));
}
if a.node_type(f) != NodeType::Attribute {
return Result::Err(Error::new(
ErrorKind::Unknown,
String::from("argument must be an attribute"),
));
}
let d = match f.get_ref_mut(self.1) {
Some(e) => e,
None => return Result::Err(Error::new(
ErrorKind::Unknown,
String::from("unable to find tree"),
))
};
d.get_mut(a.0).unwrap().parent = Some(self.clone());
let qn = d.get(a.0).unwrap().name().as_ref().unwrap().clone();
d.get_mut(self.0).unwrap().attributes.insert(qn, a);
Ok(())
}
pub fn ancestor_iter(&self) -> Ancestors {
Ancestors::new(self.0, self.1)
}
pub fn parent(&self, f: &Forest) -> Option<Node> {
self.ancestor_iter().next(f).map(|p| p)
}
pub fn child_iter(&self) -> Children {
Children::new(self.0, self.1)
}
pub fn get_first_element(&self, f: &Forest) -> Option<Node> {
let mut cit = self.child_iter();
let mut ret = None;
loop {
match cit.next(f) {
Some(n) => {
match n.node_type(f) {
NodeType::Element => {
ret = Some(n);
break
}
_ => {}
}
}
None => break,
}
}
ret
}
pub fn next_iter(&self, f: &Forest) -> Siblings {
Siblings::new(self.0, self.1, 1, f)
}
pub fn prev_iter(&self, f: &Forest) -> Siblings {
Siblings::new(self.0, self.1, -1, f)
}
pub fn descend_iter(&self, f: &Forest) -> Descendants {
Descendants::new(self.0, self.1, f)
}
pub fn attribute_iter<'a>(&self, f: &'a Forest) -> Attributes<'a> {
Attributes::new(self.0, f.get_ref(self.1).unwrap())
}
pub fn get_attribute(&self, f: &Forest, qn: &QualifiedName) -> Option<Node> {
match f.get_ref(self.1) {
Some(d) => {
match d.get(self.0) {
Some(nc) => {
match nc.attributes.get(qn) {
Some(m) => Some(m.clone()),
None => None,
}
}
None => None,
}
}
None => None,
}
}
pub fn is_element(&self, f: &Forest) -> bool {
match f.get_ref(self.1) {
Some(d) => {
match d.get(self.0) {
Some(nc) => {
nc.t == NodeType::Element
}
None => false,
}
}
None => false,
}
}
pub fn deep_copy(&self, f: &mut Forest, t: Option<TreeIndex>) -> Result<Node, Error> {
let cptreeidx = t.map_or_else(
|| self.1,
|u| u,
);
match self.node_type(f) {
NodeType::Element => {
let nm = self.to_name(f);
let new = f.get_ref_mut(cptreeidx).unwrap().new_element(nm)?;
let mut attrs = vec![];
let mut ait = self.attribute_iter(f);
loop {
match ait.next() {
Some(a) => {
attrs.push(a)
}
None => break,
}
}
attrs.iter().for_each(|a| {
let cp = a.deep_copy(f, t).expect("unable to copy attribute");
new.add_attribute(f, cp).expect("unable to add attribute");
});
let mut cit = self.child_iter();
loop {
match cit.next(f) {
Some(d) => {
let cp = d.deep_copy(f, t)?;
new.append_child(f, cp)?;
}
None => break,
}
}
Ok(new)
}
NodeType::Attribute => {
let nm = self.to_name(f);
let v = self.to_value(f);
f.get_ref_mut(cptreeidx).unwrap().new_attribute(nm, v)
}
NodeType::Text => {
let v = self.to_value(f);
f.get_ref_mut(cptreeidx).unwrap().new_text(v)
}
NodeType::Comment => {
let v = self.to_value(f);
f.get_ref_mut(cptreeidx).unwrap().new_comment(v)
}
NodeType::ProcessingInstruction => {
let nm = self.to_name(f);
let v = self.to_value(f);
f.get_ref_mut(cptreeidx).unwrap().new_processing_instruction(nm, v)
}
_ => Result::Err(Error::new(ErrorKind::Unknown, String::from("unable to copy node")))
}
}
}
pub struct Ancestors {
t: TreeIndex,
cur: Index,
}
impl Ancestors {
fn new(cur: Index, t: TreeIndex) -> Ancestors {
Ancestors{t, cur}
}
pub fn next(&mut self, f: &Forest) -> Option<Node> {
if let Some(d) = f.get_ref(self.t) {
if let Some(c) = d.get(self.cur) {
if let Some(p) = c.parent {
if p.node_type(f) == NodeType::Document {
None
} else {
self.cur = p.0;
Some(p)
}
} else {
None
}
} else {
None
}
} else {
None
}
}
}
pub struct Descendants {
t: TreeIndex,
start: Index,
cur: Index,
stack: Vec<(Index, usize)>,
}
impl Descendants {
fn new(cur: Index, t: TreeIndex, f: &Forest) -> Descendants {
let d = f.get_ref(t).unwrap();
let pi = d.get(cur).unwrap().parent.unwrap().0;
let p = d.get(pi).unwrap();
let q = p.children.iter().enumerate()
.skip_while(|(_, i)| i.0 != cur)
.nth(0)
.map(|(e, _)| e)
.unwrap();
Descendants{
t,
start: cur,
cur: cur,
stack: vec![(pi, q)],
}
}
pub fn next(&mut self, f: &Forest) -> Option<Node> {
if self.stack.is_empty() {
None
} else {
match Node::new(self.cur, self.t).child_iter().next(f) {
Some(n) => {
self.stack.push((self.cur, 0));
self.cur = n.0;
Some(n)
}
None => {
let d = f.get_ref(self.t).unwrap();
let (i, mut s) = self.stack.last_mut().unwrap();
let pnc = d.get(*i).unwrap();
if pnc.children.len() < s {
s += 1;
self.cur = pnc.children.get(s).unwrap().0;
Some(Node::new(self.cur, self.t))
} else {
let result: Option<Node>;
loop {
self.stack.pop();
if self.stack.is_empty() {
result = None;
break
} else {
let l = self.stack.last_mut().unwrap();
let (j, mut t) = l;
let qnc = d.get(*j).unwrap();
if qnc.children.len() > t + 1 {
t += 1;
*l = (*j, t);
self.cur = qnc.children.get(t).unwrap().0;
result = Some(Node::new(self.cur, self.t));
break
} else {
if *j == self.start {
result = None;
break
}
}
}
}
result
}
}
}
}
}
}
pub struct Children {
t: TreeIndex,
parent: Index,
cur: usize,
}
impl Children {
fn new(parent: Index, t: TreeIndex) -> Children {
Children{t, parent, cur: 0}
}
pub fn next(&mut self, f: &Forest) -> Option<Node> {
if let Some(d) = f.get_ref(self.t) {
if let Some(n) = d.get(self.parent) {
if n.children.len() > self.cur {
self.cur += 1;
Some(n.children[self.cur - 1])
} else {
None
}
} else {
None
}
} else {
None
}
}
}
pub struct Siblings {
t: TreeIndex,
parent: Index,
cur: usize,
dir: i16,
}
impl Siblings {
fn new(n: Index, t: TreeIndex, dir: i16, f: &Forest) -> Siblings {
let d = f.get_ref(t).unwrap();
let nc = d.get(n).unwrap();
let pnc = d.get(nc.parent.unwrap().0).unwrap();
let cur = pnc.children.iter().enumerate()
.skip_while(|(_, i)| i.0 != n)
.nth(0)
.map(|(e, _)| e)
.unwrap();
Siblings{
t,
parent: nc.parent.unwrap().0,
dir,
cur: cur,
}
}
pub fn next(&mut self, f: &Forest) -> Option<Node> {
if let Some(d) = f.get_ref(self.t) {
if let Some(n) = d.get(self.parent) {
if self.dir > 0 && n.children.len() > self.cur + 1 {
self.cur += 1;
Some(n.children[self.cur])
} else if self.dir < 0 && self.cur > 0 {
self.cur -= 1;
Some(n.children[self.cur])
} else {
None
}
} else {
None
}
} else {
None
}
}
}
pub struct Attributes<'a>{
it: Iter<'a, QualifiedName, Node>,
}
impl<'a> Attributes<'a> {
fn new(i: Index, d: &'a Tree) -> Attributes {
Attributes{
it: d.get(i).unwrap().attributes.iter()
}
}
pub fn next(&mut self) -> Option<Node> {
self.it.next().map(|(_, n)| *n)
}
}
#[derive(Clone, Default)]
pub struct NodeContent {
t: NodeType,
name: Option<QualifiedName>,
v: Option<Value>,
parent: Option<Node>, attributes: HashMap<QualifiedName, Node>, children: Vec<Node>, }
impl NodeContent {
pub fn new(t: NodeType) -> Self {
NodeContent {
t,
..Default::default()
}
}
pub fn node_type(&self) -> NodeType {
self.t
}
pub fn name(&self) -> &Option<QualifiedName> {
&self.name
}
pub fn value(&self) -> &Option<Value> {
&self.v
}
}
struct NodeBuilder(NodeContent);
impl NodeBuilder {
pub fn new(t: NodeType) -> Self {
NodeBuilder(NodeContent::new(t))
}
pub fn name(mut self, qn: QualifiedName) -> Self {
self.0.name = Some(qn);
self
}
pub fn value(mut self, v: Value) -> Self {
self.0.v = Some(v);
self
}
pub fn build(self) -> NodeContent {
self.0
}
}
pub trait AncestorIterator {
type Node;
fn next(&mut self, t: Tree) -> Option<Self::Node>;
}
pub trait ChildIterator {
type Node;
fn next(&mut self, t: Tree) -> Option<Self::Node>;
}
pub trait DocChildIterator {
type Node;
fn next(&mut self, t: Tree) -> Option<Self::Node>;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn emptydoc() {
let mut f = Forest::new();
f.plant_tree();
assert!(true)
}
#[test]
fn root_element() {
let mut f = Forest::new();
let ti = f.plant_tree();
let e = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Test")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap()
.push_doc_node(e)
.expect("unable to add node to doc");
assert_eq!(e.to_xml(&f), "<Test></Test>")
}
#[test]
fn add_element() {
let mut f = Forest::new();
let ti = f.plant_tree();
let e = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Test")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap()
.push_doc_node(e)
.expect("unable to add node to doc");
let l1 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l1).expect("unable to append node");
assert_eq!(e.to_xml(&f), "<Test><Level-1></Level-1></Test>")
}
#[test]
fn add_text() {
let mut f = Forest::new();
let ti = f.plant_tree();
let e = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Test")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap()
.push_doc_node(e)
.expect("unable to add node to doc");
let l1 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l1).expect("unable to append node");
let txt = f.get_ref_mut(ti).unwrap()
.new_text(Value::from("this is a test"))
.expect("unable to create text node");
l1.append_child(&mut f, txt).expect("unable to append node");
assert_eq!(e.to_xml(&f), "<Test><Level-1>this is a test</Level-1></Test>")
}
#[test]
fn add_attribute() {
let mut f = Forest::new();
let ti = f.plant_tree();
let e = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Test")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap()
.push_doc_node(e)
.expect("unable to add node to doc");
let l1 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l1).expect("unable to append node");
let txt = f.get_ref_mut(ti).unwrap()
.new_attribute(QualifiedName::new(None, None, String::from("data")), Value::from("this is a test"))
.expect("unable to create text node");
l1.add_attribute(&mut f, txt).expect("unable to add attribute");
assert_eq!(e.to_xml(&f), "<Test><Level-1 data='this is a test'></Level-1></Test>")
}
#[test]
fn add_comment() {
let mut f = Forest::new();
let ti = f.plant_tree();
let e = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Test")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap()
.push_doc_node(e)
.expect("unable to add node to doc");
let l1 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l1).expect("unable to append node");
let c = f.get_ref_mut(ti).unwrap()
.new_comment(Value::from("this is a comment"))
.expect("unable to create comment node");
l1.append_child(&mut f, c).expect("unable to append node");
assert_eq!(e.to_xml(&f), "<Test><Level-1><!--this is a comment--></Level-1></Test>")
}
#[test]
fn add_pi() {
let mut f = Forest::new();
let ti = f.plant_tree();
let e = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Test")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap().push_doc_node(e)
.expect("unable to add node to doc");
let l1 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l1).expect("unable to append node");
let pi = f.get_ref_mut(ti).unwrap()
.new_processing_instruction(QualifiedName::new(None, None, String::from("testPI")), Value::from("this is a PI"))
.expect("unable to create processing instruction node");
l1.append_child(&mut f, pi).expect("unable to append node");
assert_eq!(e.to_xml(&f), "<Test><Level-1><?testPI this is a PI?></Level-1></Test>")
}
#[test]
fn remove() {
let mut f = Forest::new();
let ti = f.plant_tree();
let e = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Test")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap().push_doc_node(e)
.expect("unable to add node to doc");
let l1 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l1).expect("unable to append node");
let t1 = f.get_ref_mut(ti).unwrap()
.new_text(Value::from("one"))
.expect("unable to create text node");
l1.append_child(&mut f, t1).expect("unable to append node");
let l2 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l2).expect("unable to append node");
let t2 = f.get_ref_mut(ti).unwrap()
.new_text(Value::from("two"))
.expect("unable to create text node");
l2.append_child(&mut f, t2).expect("unable to append node");
assert_eq!(e.to_xml(&f), "<Test><Level-1>one</Level-1><Level-1>two</Level-1></Test>");
l1.remove(&mut f).expect("unable to remove node");
assert_eq!(e.to_xml(&f), "<Test><Level-1>two</Level-1></Test>");
}
#[test]
fn children() {
let mut f = Forest::new();
let ti = f.plant_tree();
let e = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Test")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap().push_doc_node(e)
.expect("unable to add node to doc");
let l1 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l1).expect("unable to append node");
let t1 = f.get_ref_mut(ti).unwrap()
.new_text(Value::from("one"))
.expect("unable to create text node");
l1.append_child(&mut f, t1).expect("unable to append node");
let l2 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l2).expect("unable to append node");
let t2 = f.get_ref_mut(ti).unwrap()
.new_text(Value::from("two"))
.expect("unable to create text node");
l2.append_child(&mut f, t2).expect("unable to append node");
assert_eq!(e.to_xml(&f), "<Test><Level-1>one</Level-1><Level-1>two</Level-1></Test>");
let mut children = e.child_iter();
assert_eq!(children.next(&f), Some(l1));
assert_eq!(children.next(&f), Some(l2));
assert_eq!(children.next(&f), None)
}
#[test]
fn ancestors() {
let mut f = Forest::new();
let ti = f.plant_tree();
let e = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Test")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap().push_doc_node(e)
.expect("unable to add node to doc");
let l1 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l1).expect("unable to append node");
let t1 = f.get_ref_mut(ti).unwrap()
.new_text(Value::from("one"))
.expect("unable to create text node");
l1.append_child(&mut f, t1).expect("unable to append node");
let l2 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l2).expect("unable to append node");
let t2 = f.get_ref_mut(ti).unwrap()
.new_text(Value::from("two"))
.expect("unable to create text node");
l2.append_child(&mut f, t2).expect("unable to append node");
assert_eq!(e.to_xml(&f), "<Test><Level-1>one</Level-1><Level-1>two</Level-1></Test>");
let mut ancestors = t2.ancestor_iter();
assert_eq!(ancestors.next(&f), Some(l2));
assert_eq!(ancestors.next(&f), Some(e));
assert_eq!(ancestors.next(&f), None)
}
#[test]
fn parent() {
let mut f = Forest::new();
let ti = f.plant_tree();
let e = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Test")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap()
.push_doc_node(e)
.expect("unable to add node to doc");
let l1 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l1).expect("unable to append node");
let t1 = f.get_ref_mut(ti).unwrap()
.new_text(Value::from("one"))
.expect("unable to create text node");
l1.append_child(&mut f, t1).expect("unable to append node");
let l2 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l2).expect("unable to append node");
let t2 = f.get_ref_mut(ti).unwrap()
.new_text(Value::from("two"))
.expect("unable to create text node");
l2.append_child(&mut f, t2).expect("unable to append node");
assert_eq!(e.to_xml(&f), "<Test><Level-1>one</Level-1><Level-1>two</Level-1></Test>");
assert_eq!(t2.parent(&f), Some(l2));
}
#[test]
fn following_sibling() {
let mut f = Forest::new();
let ti = f.plant_tree();
let e = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Test")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap()
.push_doc_node(e)
.expect("unable to add node to doc");
let l1 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l1).expect("unable to append node");
let t1 = f.get_ref_mut(ti).unwrap()
.new_text(Value::from("one"))
.expect("unable to create text node");
l1.append_child(&mut f, t1).expect("unable to append node");
let l2 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l2).expect("unable to append node");
let t2 = f.get_ref_mut(ti).unwrap()
.new_text(Value::from("two"))
.expect("unable to create text node");
l2.append_child(&mut f, t2).expect("unable to append node");
assert_eq!(e.to_xml(&f), "<Test><Level-1>one</Level-1><Level-1>two</Level-1></Test>");
let mut follow = l1.next_iter(&f);
assert_eq!(follow.next(&f), Some(l2));
assert_eq!(follow.next(&f), None)
}
#[test]
fn preceding_sibling() {
let mut f = Forest::new();
let ti = f.plant_tree();
let e = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Test")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap()
.push_doc_node(e)
.expect("unable to add node to doc");
let l1 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l1).expect("unable to append node");
let t1 = f.get_ref_mut(ti).unwrap()
.new_text(Value::from("one"))
.expect("unable to create text node");
l1.append_child(&mut f, t1).expect("unable to append node");
let l2 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l2).expect("unable to append node");
let t2 = f.get_ref_mut(ti).unwrap()
.new_text(Value::from("two"))
.expect("unable to create text node");
l2.append_child(&mut f, t2).expect("unable to append node");
assert_eq!(e.to_xml(&f), "<Test><Level-1>one</Level-1><Level-1>two</Level-1></Test>");
let mut pre = l2.prev_iter(&f);
assert_eq!(pre.next(&f), Some(l1));
assert_eq!(pre.next(&f), None)
}
#[test]
fn descendants() {
let mut f = Forest::new();
let ti = f.plant_tree();
let e = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Test")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap()
.push_doc_node(e)
.expect("unable to add node to doc");
let g = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Another")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap()
.push_doc_node(g)
.expect("unable to add node to doc");
let l1 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l1).expect("unable to append node");
let t1 = f.get_ref_mut(ti).unwrap()
.new_text(Value::from("one"))
.expect("unable to create text node");
l1.append_child(&mut f, t1).expect("unable to append node");
let l2 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l2).expect("unable to append node");
let t2 = f.get_ref_mut(ti).unwrap()
.new_text(Value::from("two"))
.expect("unable to create text node");
l2.append_child(&mut f, t2).expect("unable to append node");
assert_eq!(e.to_xml(&f), "<Test><Level-1>one</Level-1><Level-1>two</Level-1></Test>");
let mut desc = e.descend_iter(&f);
assert_eq!(desc.next(&f), Some(l1));
assert_eq!(desc.next(&f), Some(t1));
assert_eq!(desc.next(&f), Some(l2));
assert_eq!(desc.next(&f), Some(t2));
assert_eq!(desc.next(&f), None)
}
#[test]
fn get_first_element() {
let mut f = Forest::new();
let ti = f.plant_tree();
let cm = f.get_ref_mut(ti).unwrap()
.new_comment(Value::from(" not an element "))
.expect("unable to create comment");
f.get_ref_mut(ti).unwrap()
.push_doc_node(cm)
.expect("unable to add comment node to doc");
let e = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Test")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap()
.push_doc_node(e)
.expect("unable to add node to doc");
let g = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Another")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap()
.push_doc_node(g)
.expect("unable to add node to doc");
assert_eq!(f.get_ref(ti).unwrap().get_doc_node().get_first_element(&f).unwrap(), e)
}
#[test]
fn serialise_1() {
let mut f = Forest::new();
let ti = f.plant_tree();
let e = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Test")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap()
.push_doc_node(e)
.expect("unable to add node to doc");
let g = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Another")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap()
.push_doc_node(g)
.expect("unable to add node to doc");
let l1 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l1).expect("unable to append node");
let t1 = f.get_ref_mut(ti).unwrap()
.new_text(Value::from("one"))
.expect("unable to create text node");
l1.append_child(&mut f, t1).expect("unable to append node");
let l2 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(None, None, String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l2).expect("unable to append node");
let t2 = f.get_ref_mut(ti).unwrap()
.new_text(Value::from("two"))
.expect("unable to create text node");
l2.append_child(&mut f, t2).expect("unable to append node");
assert_eq!(e.to_xml(&f), "<Test><Level-1>one</Level-1><Level-1>two</Level-1></Test>");
let mut od = OutputDefinition::new();
od.set_indent(true);
assert_eq!(e.to_xml_with_options(&f, &od), "<Test>
<Level-1>one</Level-1>
<Level-1>two</Level-1>
</Test>");
}
#[test]
fn serialise_2() {
let mut f = Forest::new();
let ti = f.plant_tree();
let e = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(Some(String::from("http://testing.org/ns")), Some(String::from("tst")), String::from("Test")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap()
.push_doc_node(e)
.expect("unable to add node to doc");
let g = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(Some(String::from("http://testing.org/ns")), Some(String::from("tst")), String::from("Another")))
.expect("unable to create element node");
f.get_ref_mut(ti).unwrap()
.push_doc_node(g)
.expect("unable to add node to doc");
let l1 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(Some(String::from("http://testing.org/ns")), Some(String::from("tst")), String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l1).expect("unable to append node");
let t1 = f.get_ref_mut(ti).unwrap()
.new_text(Value::from("one"))
.expect("unable to create text node");
l1.append_child(&mut f, t1).expect("unable to append node");
let l2 = f.get_ref_mut(ti).unwrap()
.new_element(QualifiedName::new(Some(String::from("http://testing.org/ns")), Some(String::from("tst")), String::from("Level-1")))
.expect("unable to create element node");
e.append_child(&mut f, l2).expect("unable to append node");
let t2 = f.get_ref_mut(ti).unwrap()
.new_text(Value::from("two"))
.expect("unable to create text node");
l2.append_child(&mut f, t2).expect("unable to append node");
assert_eq!(e.to_xml(&f), "<tst:Test xmlns:tst='http://testing.org/ns'><tst:Level-1>one</tst:Level-1><tst:Level-1>two</tst:Level-1></tst:Test>");
let mut od = OutputDefinition::new();
od.set_indent(true);
assert_eq!(e.to_xml_with_options(&f, &od), "<tst:Test xmlns:tst='http://testing.org/ns'>
<tst:Level-1>one</tst:Level-1>
<tst:Level-1>two</tst:Level-1>
</tst:Test>");
}
#[test]
fn parse() {
let mut f = Forest::new();
let ti = f.grow_tree("<Test><empty/>
<data mode='mixed'>This contains <i>mixed</i> content.</data>
<special>Some escaped chars <&></special>
</Test>")
.expect("unable to parse");
assert_eq!(f.get_ref(ti).unwrap().get_doc_node().child_iter().next(&f).unwrap().to_xml(&f), "<Test><empty></empty>
<data mode='mixed'>This contains <i>mixed</i> content.</data>
<special>Some escaped chars <&></special>
</Test>")
}
#[test]
fn deep_copy_1() {
let mut f = Forest::new();
let t1 = f.grow_tree("<Test><one/><two/><three/></Test>")
.expect("unable to parse document 1");
let t1root = f.get_ref(t1).unwrap().get_doc_node().child_iter().next(&f).unwrap();
let mut cit = t1root.child_iter();
let _t1one = cit.next(&f).unwrap();
let t1two = cit.next(&f).unwrap();
let t1three = cit.next(&f).unwrap();
t1two.insert_before(&mut f, t1three)
.expect("unable to insert node");
assert_eq!(t1root.to_xml(&f), "<Test><one></one><three></three><two></two></Test>");
}
#[test]
fn deep_copy_2() {
let mut f = Forest::new();
let t1 = f.grow_tree("<Test><one/><two/><three/></Test>")
.expect("unable to parse document 1");
let t2 = f.grow_tree("<Another><test>document</test></Another>")
.expect("unable to parse document 1");
let t1root = f.get_ref(t1).unwrap().get_doc_node().child_iter().next(&f).unwrap();
let mut t1it = t1root.child_iter();
let _t1one = t1it.next(&f).unwrap();
let t1two = t1it.next(&f).unwrap();
let t2root = f.get_ref(t2).unwrap().get_doc_node().child_iter().next(&f).unwrap();
t1two.insert_before(&mut f, t2root)
.expect("unable to insert node");
assert_eq!(t1root.to_xml(&f), "<Test><one></one><Another><test>document</test></Another><two></two><three></three></Test>");
}
#[test]
fn deep_copy_3() {
let mut f = Forest::new();
let t1 = f.grow_tree("<Test><one/><two/><three/></Test>")
.expect("unable to parse document 1");
let t2 = f.grow_tree("<Another><test>document</test></Another>")
.expect("unable to parse document 1");
let t1root = f.get_ref(t1).unwrap().get_doc_node().child_iter().next(&f).unwrap();
let mut t1it = t1root.child_iter();
let _t1one = t1it.next(&f).unwrap();
let t1two = t1it.next(&f).unwrap();
let t2root = f.get_ref(t2).unwrap().get_doc_node().child_iter().next(&f).unwrap();
t1two.append_child(&mut f, t2root)
.expect("unable to append node");
assert_eq!(t1root.to_xml(&f), "<Test><one></one><two><Another><test>document</test></Another></two><three></three></Test>");
}
}