Closed bbstilson closed 1 year ago
I think you are looking for cooklang/cooklang-rs (crates.io), it was part of this repository before but now it has been moved to the cooklang org.
That is the library that does all the parsing and combining ingredients.
Half of that function is just resolving the recipe names into file names, reading the recipes and scaling them. The key part implemented by cooklang-rs
is in the recipe.ingredient_list()
and the GroupedQuantity::merge
. I really need to improve the documentation in the library 😅 .
But as you can see here, once the recipe has been parsed and scaled, I iterate over the ingredient list of each recipe and merge their quantities by ingredient name.
Thanks for your help! I was able to get my weekend hackathon working. At a high-level, I have a function that chooses 3 random recipes, then adds those ingredients to a todoist project where each category from cooklang gets its own section in the todoist project.
There's a couple things I noticed that could be improved to make things a bit easier on users.
First, a small thing, there's a typo: cooklang::aisle::AileConf
should be cooklang::aisle::AisleConf
(missing an s
)
Second, I had to pull in a bunch of code from the guts of cooklang
internal functions to get the categorized ingredients list. A much more convenient api would have two functions, I think.
The first would be a simple function that returns the recipes in a directory or returns a single recipe if it's a file path instead of a directory.
The second would be a function that, given a recipe, returns a categorized (or uncategorized) ingredient list. This response model should also be significantly simplified. Something like (somewhat pseudocode):
pub type CategorizedIngredients: HashMap<String, Vec<Ingredient>>;
pub struct Ingredient {
name: String,
amount: f64,
unit: Unit
}
impl Display for Ingredient {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} {} {}", self.amount, self.unit, self.name)
}
}
Finally, a resolver for the Many(quanities)
would be really helpful. I just picked the first one from the vec and used that one, but I'm not sure if that's correct.
The first two should be pretty straightforward to add, and I would be happy to take the first pass in a PR if that sounds appealing.
Thanks again for your help 🙂
Thanks for the feedback 😃 . In order:
Oops, I will fix the typo.
The function that returns recipes in a directory or a single recipe may be a good fit in cooklang-fs
, a supporting library to interact with the file system, as I intend to keep the main cooklang
lib independent from the way recipes are stored.
[Recipe::ingredient_list_grouped
] could be added to return a categorized list. I think that's a good idea. Also, a function to merge 2 ingredient lists, grouped or not.
The main problem with the current ingredient list model I think is the index
. I didn't want to copy the whole ingredient but wanted to still have access to all the data of the ingredient definition. I know it's not perfect, but I can't think of a better one. While development I tried putting the ingredients behind an Arc but I wasn't convinced.
The Many(quantities)
confusion is just lacking documentation. It is needed that way. For example, if you are trying to merge 2 recipes where the same ingredient is used with units that can't be added, the total quantity will be Many
. For example, one recipe may use 1 bottle of wine
and another 0.5 litres of wine
. In that case Many
will have 2 items because I cannot add 1 bottle
and 0.5 litres
into the same quantity.
If you want to try a PR of 2 (in this repo in the cooklang-fs
crate) go for it. As for point 3, they are relatively simple functions and I am in the process of version 0.4 of the library, so I have no problem adding them myself. However if you think you have a good idea for the model, submit a PR in https://github.com/cooklang/cooklang-rs
Hi there. I love the project, but I would like to interact with a few components as a library so that I can create a more automated experience.
Specifically, what I'm trying to do is get access to the combined ingredients given a list of recipes so that I can programmatically update my grocery list.
It doesn't seem like this is directly possible, but I am somewhat new to Rust, so I might be missing something. If it is not possible, I'm happy to tackle abstracting this as a PR if that's inline with what you have in mind for the future of the project.