use std::str::FromStr;
use xml::{Element};
use xml::Xml::{ElementNode, CharacterNode};
pub fn parse_string_to_vector<T: FromStr>(string: &str) -> Vec<T> {
string.trim()
.split(" ")
.map(|s| s.parse().ok().expect("Error parsing array in COLLADA file"))
.collect()
}
pub fn get_array_content<T: FromStr>(element: &Element) -> Option<Vec<T>> {
match element.children[0] {
CharacterNode(ref contents) => Some(parse_string_to_vector(contents)),
_ => None,
}
}
pub fn has_attribute_with_value(e: &Element, name: &str, value: &str) -> bool {
if let Some(s) = e.get_attribute(name, None) {
s == value
} else {
false
}
}
pub fn to_matrix_array(float_array: Vec<f32>) -> Vec<[[f32; 4]; 4]> {
float_array.chunks(16).map(|chunk| {
let mut matrix = [[0f32; 4]; 4];
for (&chunk_value, matrix_value) in chunk.iter().zip(matrix.iter_mut().flat_map(|n| n.iter_mut())) {
*matrix_value = chunk_value;
}
matrix
}).collect()
}
pub fn pre_order_iter<'a>(root: &'a Element) -> PreOrderIterator<'a> {
PreOrderIterator { stack: vec![root] }
}
pub fn pre_order_with_depth_iter<'a>(root: &'a Element) -> PreOrderWithDepthIterator<'a> {
PreOrderWithDepthIterator { stack: vec![(root, 0)] }
}
pub struct PreOrderIterator<'a> {
stack: Vec<&'a Element>
}
impl<'a> Iterator for PreOrderIterator<'a> {
type Item = &'a Element;
fn next(&mut self) -> Option<&'a Element> {
let current_element = self.stack.pop();
match current_element {
Some(element) => {
for child in element.children.iter().rev() {
if let ElementNode(ref e) = *child {
self.stack.push(e);
}
}
}
None => ()
}
current_element
}
}
pub struct PreOrderWithDepthIterator<'a> {
stack: Vec<(&'a Element, usize)>
}
impl<'a> Iterator for PreOrderWithDepthIterator<'a> {
type Item = (&'a Element, usize);
fn next(&mut self) -> Option<(&'a Element, usize)> {
match self.stack.pop() {
Some((element, depth)) => {
for child in element.children.iter().rev() {
if let ElementNode(ref e) = *child {
self.stack.push((e, depth + 1));
}
}
Some((element, depth))
}
None => None
}
}
}