use std::collections::BTreeMap;
use crate::{Escaper, Templates, Type};
pub mod value;
pub use value::Value;
mod error;
pub use error::Error;
pub(crate) use error::WRONG_TYPE_MESSAGE;
mod context;
pub(crate) use context::write_tmpl;
fn param_matches_ty(param: &Value, ty: &Type) -> bool {
match (param, ty) {
(Value::Bool(_), Type::Bool)
| (Value::Float(_), Type::Float)
| (Value::Int(_), Type::Int) => true,
(v, Type::Text(_)) => v.is_printable(),
(Value::ArrayOrTuple(values), Type::Array(inner)) => {
let array_type = inner
.as_ref()
.expect("array type should be known here")
.as_ref();
values
.iter()
.all(|value| param_matches_ty(value, array_type))
}
(Value::ArrayOrTuple(values), Type::Tuple(tuple_types)) => {
values.len() == tuple_types.len()
&& values
.iter()
.zip(tuple_types.iter())
.all(|(value, ty)| param_matches_ty(value, ty))
}
(Value::Struct(values), Type::Struct(struct_types)) => {
values.len() == struct_types.len()
&& values
.iter()
.zip(struct_types.iter())
.all(|((key1, value), (key2, ty))| key1 == key2 && param_matches_ty(value, ty))
}
_ => false,
}
}
pub(crate) fn tmpl_output<Esc: Escaper>(
tmpls: &Templates<Esc>,
index: usize,
args: BTreeMap<String, Value>,
) -> Result<String, Error> {
let mut result = String::new();
write_tmpl(&mut result, tmpls, index, args)?;
Ok(result)
}