use std::{collections::HashMap, convert::Infallible};
use crate::formatter::{Render, Taggable, Template, TemplateError};
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct FormatTable {
table: HashMap<String, String>,
}
impl FormatTable {
pub fn new() -> Self {
Self {
table: HashMap::new(),
}
}
pub fn render(&self, template: &Template) -> String {
template.render(self)
}
pub fn render_string(&self, str: impl AsRef<str>) -> Result<String, TemplateError> {
let args = Template::try_from(str.as_ref())?;
Ok(self.render(&args))
}
pub fn add_entry(&mut self, key: impl Into<String>, value: impl Into<String>) {
self.table
.insert(key.into().to_ascii_lowercase(), value.into());
}
pub fn add_table<I, K, V>(&mut self, table: I)
where
I: IntoIterator<Item = (K, V)>,
K: Into<String>,
V: Into<String>,
{
self.table
.extend(table.into_iter().map(|(k, v)| (k.into(), v.into())));
}
pub fn extend_from_taggable<T: Taggable>(&mut self, from: &T) -> Result<(), T::Err> {
from.fill_table(self)
}
pub fn table(&self) -> &HashMap<String, String> {
&self.table
}
}
impl Taggable for FormatTable {
type Err = Infallible;
fn fill_table(&self, table: &mut FormatTable) -> Result<(), Infallible> {
table.table.extend(self.table.clone());
Ok(())
}
}
impl<I, K, V> From<I> for FormatTable
where
I: IntoIterator<Item = (K, V)>,
K: Into<String>,
V: Into<String>,
{
fn from(value: I) -> Self {
FormatTable::from_iter(value)
}
}
impl<K, V> FromIterator<(K, V)> for FormatTable
where
K: Into<String>,
V: Into<String>,
{
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
FormatTable {
table: iter
.into_iter()
.map(|(k, v)| (k.into(), v.into()))
.collect(),
}
}
}