use std::str::FromStr;
use xml::Element;
use xml::Xml::{CharacterNode, ElementNode};
pub fn parse_string_to_vector<T: FromStr>(string: &str) -> Vec<T> {
string
.trim()
.replace("\r\n", "\n")
.split(&[' ', '\n'][..])
.map(|s| {
let parse_result:Option<T> = s.parse().ok();
match parse_result {
Some(res) => return res,
None => {
error!("unable to parse the folling line \n{s}");
panic!();
}
}
}).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,
}
}
}