use crate::parser::get_converter;
use cooklang::quantity::GroupedQuantity;
use minijinja::{State, Value};
use std::collections::BTreeMap;
pub fn aisled(state: &State, ingredients: Value) -> Value {
let aisle_content = state
.lookup("aisle_content")
.and_then(|v| v.as_str().map(String::from));
let mut result = BTreeMap::new();
if let Some(content) = aisle_content {
let parse_result = cooklang::aisle::parse_lenient(&content);
if let Some(aisle_conf) = parse_result.output() {
let mut ingredient_list = cooklang::ingredient_list::IngredientList::new();
if let Ok(iter) = ingredients.try_iter() {
for item in iter {
let name = item
.get_attr("name")
.ok()
.and_then(|v| v.as_str().map(String::from))
.unwrap_or_default();
ingredient_list.add_ingredient(
name,
&GroupedQuantity::default(),
get_converter(),
);
}
}
let categorized = ingredient_list.categorize(aisle_conf);
for (category, list) in categorized.categories {
let mut category_items = Vec::new();
for (ingredient_name, _) in list {
if let Ok(iter) = ingredients.try_iter() {
for item in iter {
if let Ok(name) = item.get_attr("name")
&& name.as_str() == Some(&ingredient_name) {
category_items.push(item);
break;
}
}
}
}
if !category_items.is_empty() {
result.insert(category, Value::from(category_items));
}
}
if !categorized.other.is_empty() {
let mut other_items = Vec::new();
for (ingredient_name, _) in categorized.other {
if let Ok(iter) = ingredients.try_iter() {
for item in iter {
if let Ok(name) = item.get_attr("name")
&& name.as_str() == Some(&ingredient_name) {
other_items.push(item);
break;
}
}
}
}
if !other_items.is_empty() {
result.insert("other".to_string(), Value::from(other_items));
}
}
} else {
eprintln!(
"Warning: Failed to parse aisle configuration. All ingredients will be placed under 'other' category."
);
result.insert("other".to_string(), ingredients);
}
} else {
eprintln!(
"Warning: No aisle configuration provided. All ingredients will be placed under 'other' category. To configure aisles, use Config::builder().aisle_path(path)"
);
result.insert("other".to_string(), ingredients);
}
Value::from_iter(result)
}