use std::collections::HashMap;
use serde::Deserialize;
use thiserror::Error;
use crate::{map::UKHashMap, Rule};
#[derive(Debug, Error)]
pub enum Error {
#[error("duplicate template name: {0}")]
Duplicate(String),
}
#[derive(Default, Debug, Deserialize, Clone)]
pub struct Templates(UKHashMap<String, String>);
impl From<HashMap<String, String>> for Templates {
fn from(value: HashMap<String, String>) -> Self {
Self(value.into())
}
}
impl Templates {
pub fn new() -> Self {
Self::default()
}
#[inline]
pub fn insert(&mut self, name: String, template: String) -> Result<(), Error> {
if self.0.contains_key(&name) {
return Err(Error::Duplicate(name));
}
self.0.insert(name, template);
Ok(())
}
#[inline]
pub fn extend(&mut self, o: &Self) -> Result<(), Error> {
for (name, template) in o.0.iter() {
self.insert(name.clone(), template.clone())?;
}
Ok(())
}
pub fn replace(&self, r: &mut Rule) {
if let Some(matches) = r.matches.as_mut() {
for op in matches.keys().cloned().collect::<Vec<_>>() {
matches.entry(op.clone()).and_modify(|s| {
let mut new = s.clone();
self.0
.iter()
.for_each(|(name, tpl)| new = new.replace(&format!("{{{{{name}}}}}"), tpl));
*s = new;
});
}
}
}
#[inline(always)]
pub fn len(&self) -> usize {
self.0.len()
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}