use alloc::collections::BTreeMap;
use tap::Pipe;
use crate::{
TemplateResolver,
error::{ResolverError, ResolverResult},
parsers::parse_value_or_map_err,
resolver::TemplateAST,
};
impl TryFrom<&[(&str, &str)]> for TemplateResolver {
type Error = ResolverError;
fn try_from(value: &[(&str, &str)]) -> Result<Self, Self::Error> {
Self::try_from_slice(value)
}
}
impl<const N: usize> TryFrom<[(&str, &str); N]> for TemplateResolver {
type Error = ResolverError;
fn try_from(value: [(&str, &str); N]) -> Result<Self, Self::Error> {
Self::try_from_str_entries(value.into_iter())
}
}
impl<K, V> TryFrom<BTreeMap<K, V>> for TemplateResolver
where
K: AsRef<str>,
V: AsRef<str>,
{
type Error = ResolverError;
fn try_from(value: BTreeMap<K, V>) -> Result<Self, Self::Error> {
Self::try_from_str_entries(value.into_iter())
}
}
impl TemplateResolver {
pub fn try_from_slice(raw: &[(&str, &str)]) -> ResolverResult<Self> {
Self::try_from_str_entries(raw.iter().copied())
}
pub fn try_from_str_entries<K, V, I>(iter: I) -> ResolverResult<Self>
where
K: AsRef<str>,
V: AsRef<str>,
I: Iterator<Item = (K, V)>,
{
iter
.map(|(key, value)| {
parse_value_or_map_err(key.as_ref(), value.as_ref()) .map(|tmpl| (convert_map_key(key.as_ref()), tmpl))
})
.collect::<Result<TemplateAST, _>>()?
.pipe(Self)
.pipe(Ok)
}
}
#[cfg(not(feature = "std"))]
fn convert_map_key(key: &str) -> crate::MiniStr {
key.into()
}
#[cfg(feature = "std")]
fn convert_map_key(key: &str) -> kstring::KString {
key.pipe(kstring::KString::from_ref)
}
#[cfg(test)]
mod tests {
use super::*;
#[ignore]
#[test]
fn test_try_from_slice() -> ResolverResult<()> {
let _res = [
("g", "Good"),
("greeting", "{g} { time-period }! { $name }"),
(
"time-period",
"$period ->
[morning] Morning
*[other] {$period}",
),
]
.pipe_as_ref(TemplateResolver::try_from_slice)?;
Ok(())
}
}