///|
pub fn ingredient(
name : String,
group : String,
amount : Int,
unit : MeasureUnit,
kcal : Int,
protein_g : Int,
fat_g : Int,
carb_g : Int,
cost_cents : Int,
allergens? : Array[String] = [],
tags? : Array[String] = [],
) -> Ingredient {
Ingredient(
name~,
group~,
quantity=Quantity(amount~, unit~),
nutrition=Nutrition(
kcal~,
protein_g~,
fat_g~,
carb_g~,
fiber_g=0,
sodium_mg=0,
),
cost_cents~,
allergens~,
tags~,
)
}
///|
pub fn example_recipe() -> Recipe {
Recipe(
title="Sesame Chicken Lunch Bowl",
servings=2,
ingredients=[
ingredient("chicken breast", "protein", 300, Gram, 495, 93, 11, 0, 1380, tags=[
"high-protein", "lean",
]),
ingredient("rice", "grain", 180, Gram, 650, 12, 2, 142, 260, tags=[
"staple",
]),
ingredient(
"sesame paste",
"sauce",
45,
Gram,
267,
8,
24,
10,
420,
allergens=["sesame"],
tags=["nutty", "sauce"],
),
ingredient(
"soy sauce",
"sauce",
30,
Milliliter,
16,
2,
0,
1,
80,
allergens=["soy"],
tags=["salty"],
),
ingredient("broccoli", "vegetable", 220, Gram, 75, 6, 1, 14, 360, tags=[
"vegetable", "fiber",
]),
ingredient("carrot", "vegetable", 120, Gram, 49, 1, 0, 12, 120, tags=[
"vegetable", "color",
]),
],
steps=[
"Cook rice until tender.", "Steam vegetables and keep them crisp.", "Cook chicken and slice it for serving.",
"Blend sauce, then adjust with pantry-safe substitutions.", "Assemble lunch bowls and print shopping gaps.",
],
notes=[
"Sample recipe intentionally contains sesame and soy so substitution planning is visible.",
"The library performs deterministic calculations; it is not a medical nutrition adviser.",
],
)
}
///|
pub fn example_profile() -> DietProfile {
DietProfile(
avoid_allergens=["sesame", "soy"],
prefer_tags=["high-protein", "vegetable"],
dislike_tags=["sugary"],
max_total_cost_cents=3600,
max_total_kcal=1800,
min_total_protein_g=80,
)
}
///|
pub fn example_pantry() -> Array[PantryItem] {
[
PantryItem(
name="chicken breast",
quantity=Quantity(amount=220, unit=Gram),
expires_in_days=1,
opened=true,
preferred=true,
),
PantryItem(
name="rice",
quantity=Quantity(amount=500, unit=Gram),
expires_in_days=90,
opened=true,
preferred=true,
),
PantryItem(
name="broccoli",
quantity=Quantity(amount=120, unit=Gram),
expires_in_days=2,
opened=false,
preferred=true,
),
PantryItem(
name="carrot",
quantity=Quantity(amount=200, unit=Gram),
expires_in_days=5,
opened=false,
preferred=true,
),
PantryItem(
name="sunflower butter",
quantity=Quantity(amount=70, unit=Gram),
expires_in_days=45,
opened=true,
preferred=true,
),
PantryItem(
name="coconut aminos",
quantity=Quantity(amount=80, unit=Milliliter),
expires_in_days=60,
opened=true,
preferred=true,
),
]
}
///|
pub fn default_substitutions() -> Array[Substitution] {
[
Substitution(
source="sesame paste",
target=ingredient(
"sunflower butter",
"sauce",
45,
Gram,
278,
10,
24,
9,
390,
tags=["seed", "sauce"],
),
ratio_percent=100,
reason="Keeps creamy texture while avoiding sesame.",
removes_allergens=["sesame"],
adds_tags=["seed-safe"],
),
Substitution(
source="soy sauce",
target=ingredient(
"coconut aminos",
"sauce",
30,
Milliliter,
25,
0,
0,
6,
130,
tags=["salty", "soy-free"],
),
ratio_percent=100,
reason="Soy-free salty seasoning.",
removes_allergens=["soy"],
adds_tags=["soy-free"],
),
Substitution(
source="rice",
target=ingredient("quinoa", "grain", 180, Gram, 666, 24, 10, 118, 560, tags=[
"high-protein", "grain",
]),
ratio_percent=100,
reason="Higher protein grain option.",
adds_tags=["high-protein"],
),
]
}
///|
pub fn example_plan() -> PantryPlan {
plan_recipe(
example_recipe(),
4,
example_profile(),
example_pantry(),
default_substitutions(),
)
}
///|
pub fn pantry_rice_bowl() -> Recipe {
Recipe(
title="Pantry Rice Bowl",
servings=2,
ingredients=[
ingredient("rice", "grain", 180, Gram, 650, 12, 2, 142, 260, tags=[
"staple",
]),
ingredient("carrot", "vegetable", 160, Gram, 66, 1, 0, 15, 160, tags=[
"vegetable", "color",
]),
ingredient("spinach", "vegetable", 120, Gram, 28, 4, 0, 4, 240, tags=[
"leafy", "vegetable",
]),
ingredient("olive oil", "fat", 15, Milliliter, 119, 0, 14, 0, 80, tags=[
"fat",
]),
],
steps=[
"Warm rice and fold in vegetables.", "Finish with oil and seasoning.", "Use this recipe as a low-effort pantry fallback.",
],
notes=[
"This recipe is intentionally simple so meal-prep ranking can compare it with higher-impact expiring-stock recipes.",
],
)
}
///|
pub fn food_catalog() -> Array[Ingredient] {
[
ingredient("oats", "grain", 100, Gram, 389, 17, 7, 66, 180, tags=[
"breakfast", "fiber",
]),
ingredient("brown rice", "grain", 100, Gram, 360, 8, 3, 76, 150, tags=[
"staple",
]),
ingredient("quinoa", "grain", 100, Gram, 370, 14, 6, 64, 310, tags=[
"high-protein",
]),
ingredient("buckwheat", "grain", 100, Gram, 343, 13, 3, 72, 280, tags=[
"gluten-free",
]),
ingredient("cornmeal", "grain", 100, Gram, 365, 9, 4, 77, 110, tags=[
"staple",
]),
ingredient("chicken breast", "protein", 100, Gram, 165, 31, 4, 0, 460, tags=[
"lean", "high-protein",
]),
ingredient("turkey mince", "protein", 100, Gram, 170, 22, 9, 0, 520, tags=[
"high-protein",
]),
ingredient(
"tofu",
"protein",
100,
Gram,
76,
8,
5,
2,
180,
allergens=["soy"],
tags=["plant-protein"],
),
ingredient(
"tempeh",
"protein",
100,
Gram,
193,
20,
11,
9,
360,
allergens=["soy"],
tags=["fermented"],
),
ingredient("lentils", "protein", 100, Gram, 116, 9, 0, 20, 160, tags=[
"plant-protein", "fiber",
]),
ingredient("chickpeas", "protein", 100, Gram, 164, 9, 3, 27, 150, tags=[
"plant-protein",
]),
ingredient("black beans", "protein", 100, Gram, 132, 9, 1, 24, 140, tags=[
"plant-protein",
]),
ingredient(
"egg",
"protein",
1,
Piece,
70,
6,
5,
1,
120,
allergens=["egg"],
tags=["breakfast"],
),
ingredient(
"milk",
"dairy",
100,
Milliliter,
61,
3,
3,
5,
90,
allergens=["milk"],
tags=["dairy"],
),
ingredient(
"yogurt",
"dairy",
100,
Gram,
59,
10,
0,
4,
160,
allergens=["milk"],
tags=["dairy", "high-protein"],
),
ingredient(
"cheddar",
"dairy",
100,
Gram,
402,
25,
33,
1,
520,
allergens=["milk"],
tags=["dairy"],
),
ingredient(
"almond milk",
"dairy-alt",
100,
Milliliter,
17,
1,
1,
0,
180,
allergens=["tree-nut"],
tags=["dairy-free"],
),
ingredient("oat milk", "dairy-alt", 100, Milliliter, 43, 1, 1, 7, 140, tags=[
"dairy-free",
]),
ingredient("broccoli", "vegetable", 100, Gram, 34, 3, 0, 7, 160, tags=[
"vegetable", "fiber",
]),
ingredient("spinach", "vegetable", 100, Gram, 23, 3, 0, 4, 120, tags=[
"vegetable", "leafy",
]),
ingredient("carrot", "vegetable", 100, Gram, 41, 1, 0, 10, 90, tags=[
"vegetable",
]),
ingredient("tomato", "vegetable", 100, Gram, 18, 1, 0, 4, 120, tags=[
"vegetable",
]),
ingredient("cucumber", "vegetable", 100, Gram, 16, 1, 0, 4, 110, tags=[
"vegetable",
]),
ingredient("mushroom", "vegetable", 100, Gram, 22, 3, 0, 3, 180, tags=[
"vegetable", "umami",
]),
ingredient("onion", "vegetable", 100, Gram, 40, 1, 0, 9, 80, tags=[
"aromatic",
]),
ingredient("garlic", "vegetable", 10, Gram, 15, 1, 0, 3, 30, tags=[
"aromatic",
]),
ingredient("apple", "fruit", 100, Gram, 52, 0, 0, 14, 130, tags=["fruit"]),
ingredient("banana", "fruit", 100, Gram, 89, 1, 0, 23, 100, tags=["fruit"]),
ingredient("orange", "fruit", 100, Gram, 47, 1, 0, 12, 120, tags=["fruit"]),
ingredient("blueberry", "fruit", 100, Gram, 57, 1, 0, 14, 420, tags=[
"fruit",
]),
ingredient("olive oil", "fat", 15, Milliliter, 119, 0, 14, 0, 80, tags=[
"fat",
]),
ingredient(
"butter",
"fat",
15,
Gram,
108,
0,
12,
0,
90,
allergens=["milk"],
tags=["fat", "dairy"],
),
ingredient("sunflower butter", "spread", 100, Gram, 617, 21, 55, 20, 860, tags=[
"seed",
]),
ingredient(
"peanut butter",
"spread",
100,
Gram,
588,
25,
50,
20,
620,
allergens=["peanut"],
tags=["nutty"],
),
ingredient(
"sesame paste",
"spread",
100,
Gram,
595,
17,
54,
21,
930,
allergens=["sesame"],
tags=["nutty"],
),
ingredient(
"soy sauce",
"sauce",
100,
Milliliter,
53,
8,
0,
5,
260,
allergens=["soy"],
tags=["salty"],
),
ingredient("coconut aminos", "sauce", 100, Milliliter, 83, 0, 0, 20, 430, tags=[
"soy-free",
]),
ingredient("honey", "sweetener", 20, Gram, 61, 0, 0, 17, 70, tags=["sweet"]),
ingredient("maple syrup", "sweetener", 20, Gram, 52, 0, 0, 13, 90, tags=[
"sweet",
]),
ingredient("salt", "seasoning", 1, Gram, 0, 0, 0, 0, 1, tags=["seasoning"]),
]
}