use std::collections::{BTreeMap, LinkedList};
use enums::{Error, ExtractResult, Warning};
use issues::Issues;
use item_value::ItemValue;
use notify::Notify;
use toml_data::TomlData;
pub struct TomlBuilder
{
group : String,
items : LinkedList<(String, ItemValue)>,
issues : Issues
}
impl TomlBuilder
{
pub fn new<T:AsRef<str>>(
group : T
) -> TomlBuilder
{
TomlBuilder {
group : String::from(group.as_ref()),
items : LinkedList::new(),
issues : Issues::new()
}
}
pub fn result(mut self) -> Result<TomlData, Issues>
{
if self.issues.has_errors() == false
{
let mut result = BTreeMap::new();
while let Some((key, item)) = self.items.pop_front()
{
result.insert(key, item);
}
Ok(TomlData::new(result, self.issues.warnings))
}
else
{
Err(self.issues)
}
}
pub fn full_name<T:AsRef<str>>(
&self,
name : T
) -> String
{
if self.group.len() > 0
{
let mut full_name = String::with_capacity(name.as_ref().len() + self.group.len() + 1);
full_name.push_str(&self.group);
full_name.push('.');
full_name.push_str(name.as_ref());
full_name
}
else
{
String::from(name.as_ref())
}
}
pub fn undefined_item<T:AsRef<str>>(
&mut self,
name : T
)
{
self.issues.warnings.push_back(Warning::Undefined(String::from(name.as_ref())));
}
pub fn add<T:AsRef<str>>(
&mut self,
name : T,
item : ExtractResult,
notify : Option<&Box<Notify>>
)
{
let full_name = self.full_name(name);
match item
{
ExtractResult::Item(item) => {
if let Some(notify) = notify
{
notify.send(&item);
}
self.items.push_back((full_name, item));
},
ExtractResult::Error(err) => {
self.issues.errors.push_back(
Error::Validation(full_name, err)
);
},
ExtractResult::Group(mut builder) => {
self.issues.errors.append(&mut builder.issues.errors);
self.issues.warnings.append(&mut builder.issues.warnings);
self.items.append(&mut builder.items);
}
}
}
pub fn missing_item<T:AsRef<str>>(
&mut self,
name : T,
optional : bool
)
{
let full_name = self.full_name(name);
if optional == false
{
self.issues.errors.push_back(Error::Missing(full_name));
}
else
{
self.issues.warnings.push_back(Warning::Missing(full_name));
}
}
}