use std::collections::HashMap;
use std::mem;
use uil_shared::markup::{Node, NodeType, TemplateData, View, Template};
use ErrorReporter;
pub struct Library<E> {
pub views: HashMap<String, View>,
pub templates: HashMap<String, Template>,
err: E,
}
impl<E> Library<E>
where E: ErrorReporter
{
pub fn new(reporter: E,
views: HashMap<String, View>,
templates: HashMap<String, Template>) -> Library<E>
{
Library {
err: reporter,
views: views,
templates: templates
}
}
pub fn get<S: ToString>(&self, s: S) -> Option<&View> {
self.views.get(&s.to_string())
}
pub fn merge(&mut self, other: Library<E>) {
for (key, val) in other.views.into_iter() {
self.views.insert(key, val);
}
for (key, val) in other.templates.into_iter() {
self.templates.insert(key, val);
}
}
pub fn resolve_templates(&mut self) {
let ref mut views = self.views;
let ref templates = self.templates;
let ref err = self.err;
for (_, view) in views.iter_mut() {
for node in view.children.iter_mut() {
Library::<E>::resolve_templates_for_node(
&err,
&templates,
node
);
}
}
}
fn resolve_templates_for_node(err: &E,
templates: &HashMap<String, Template>,
node: &mut Node)
{
for child in node.children.iter_mut() {
let mut is_empty = None;
let test = match child.node_type {
NodeType::Template(TemplateData { ref path }) => {
is_empty = Some(path.clone());
templates.get(path)
}
_ => None
};
match test {
Some(found) => {
mem::swap(
child,
&mut Node::from_template(
found,
NodeType::Group
)
);
}
None => match is_empty {
Some(name) => err.log(
format!("Warning `{}` template name not found", name)
),
None => ()
}
}
}
for child in node.children.iter_mut() {
Library::<E>::resolve_templates_for_node(err, templates, child);
}
}
}