use serde::Serialize;
#[derive(Clone, Debug, Serialize)]
pub struct Cookware(cooklang::Cookware);
impl From<cooklang::Cookware> for Cookware {
fn from(cookware: cooklang::Cookware) -> Self {
Self(cookware)
}
}
impl From<Cookware> for minijinja::Value {
fn from(value: Cookware) -> Self {
Self::from_object(value)
}
}
impl minijinja::value::Object for Cookware {
fn repr(self: &std::sync::Arc<Self>) -> minijinja::value::ObjectRepr {
minijinja::value::ObjectRepr::Plain
}
fn get_value(self: &std::sync::Arc<Self>, key: &minijinja::Value) -> Option<minijinja::Value> {
match key.as_str()? {
"name" => Some(minijinja::Value::from(&self.0.name)),
"note" => self.0.note.as_ref().map(minijinja::Value::from),
"alias" => self.0.alias.as_ref().map(minijinja::Value::from),
"quantity" => self
.0
.quantity
.as_ref()
.map(ToString::to_string)
.map(minijinja::Value::from),
_ => None,
}
}
fn render(self: &std::sync::Arc<Self>, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
where
Self: Sized + 'static,
{
write!(f, "{}", self.0.display_name())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::model::tests::get_recipe_and_env;
use minijinja::{Value, context};
use test_case::test_case;
#[test_case("Crack @egg{1} into #frying pan{}.", "{{ cookware }}", "frying pan"; "just name")]
#[test_case("Crack @egg{1} into #frying pan{1}.", "{{ cookware }}", "frying pan"; "name and quantity")]
fn cookware(recipe: &str, template: &str, result: &str) {
let (recipe, env) = get_recipe_and_env(recipe, template);
let context = context! {
cookware => Value::from(Cookware(recipe.cookware[0].clone()))
};
let template = env.get_template("test").unwrap();
assert_eq!(result, template.render(context).unwrap());
}
}