Fix parsing errors and some additional units

This commit is contained in:
Jeremy Wall 2021-11-11 20:19:20 -05:00
parent 5e36fa66e2
commit 8e0e66e8b8
4 changed files with 39 additions and 7 deletions

View File

@ -40,8 +40,8 @@ where
fn output_recipe_info(r: Recipe, print_ingredients: bool) { fn output_recipe_info(r: Recipe, print_ingredients: bool) {
println!("Title: {}", r.title); println!("Title: {}", r.title);
println!(""); println!("");
println!("Ingredients:");
if print_ingredients { if print_ingredients {
println!("Ingredients:");
for (_, ing) in r.get_ingredients() { for (_, ing) in r.get_ingredients() {
print!("\t* {}", ing.amt); print!("\t* {}", ing.amt);
println!(" {}", ing.name); println!(" {}", ing.name);

View File

@ -14,8 +14,8 @@
use std::str::FromStr; use std::str::FromStr;
use abortable_parser::{ use abortable_parser::{
ascii_digit, ascii_ws, consume_all, discard, do_each, either, eoi, make_fn, not, optional, ascii_digit, ascii_ws, consume_all, discard, do_each, either, eoi, make_fn, must, not,
peek, repeat, separated, text_token, trap, until, Result, StrIter, optional, peek, repeat, separated, text_token, trap, until, Result, StrIter,
}; };
use num_rational::Ratio; use num_rational::Ratio;
@ -91,7 +91,7 @@ make_fn!(
pub step<StrIter, Step>, pub step<StrIter, Step>,
do_each!( do_each!(
_ => step_prefix, _ => step_prefix,
ingredients => ingredient_list, ingredients => must!(ingredient_list),
_ => para_separator, _ => para_separator,
desc => description, desc => description,
_ => either!(discard!(para_separator), eoi), _ => either!(discard!(para_separator), eoi),
@ -101,7 +101,15 @@ make_fn!(
make_fn!( make_fn!(
pub step_list<StrIter, Vec<Step>>, pub step_list<StrIter, Vec<Step>>,
repeat!(step) do_each!(
first_step => must!(step),
rest => repeat!(step),
({
let mut steps = vec![first_step];
steps.extend(rest);
steps
})
)
); );
make_fn!(ws<StrIter, &str>, make_fn!(ws<StrIter, &str>,
@ -148,6 +156,8 @@ make_fn!(unit<StrIter, &str>,
text_token!("floz"), text_token!("floz"),
text_token!("ml"), text_token!("ml"),
text_token!("ltr"), text_token!("ltr"),
text_token!("lb"),
text_token!("oz"),
text_token!("cup"), text_token!("cup"),
text_token!("qrt"), text_token!("qrt"),
text_token!("pint"), text_token!("pint"),
@ -212,6 +222,9 @@ pub fn measure(i: StrIter) -> abortable_parser::Result<StrIter, Measure> {
Some("qrt") | Some("quart") => Volume(Qrt(qty)), Some("qrt") | Some("quart") => Volume(Qrt(qty)),
Some("pint") | Some("pnt") => Volume(Pint(qty)), Some("pint") | Some("pnt") => Volume(Pint(qty)),
Some("cnt") | Some("count") => Count(qty), Some("cnt") | Some("count") => Count(qty),
Some("lb") => Measure::lb(qty),
Some("oz") => Measure::oz(qty),
Some("kg") => Measure::kilogram(qty),
Some("g") => Gram(qty), Some("g") => Gram(qty),
Some("gram") => Gram(qty), Some("gram") => Gram(qty),
Some(u) => { Some(u) => {
@ -237,8 +250,10 @@ pub fn measure(i: StrIter) -> abortable_parser::Result<StrIter, Measure> {
make_fn!( make_fn!(
pub ingredient_name<StrIter, &str>, pub ingredient_name<StrIter, &str>,
do_each!( do_each!(
name => until!(ascii_ws), name => until!(either!(
_ => ws, discard!(text_token!("\n")),
eoi,
discard!(text_token!("(")))),
(name) (name)
) )
); );
@ -260,6 +275,7 @@ make_fn!(
measure => measure, measure => measure,
name => ingredient_name, name => ingredient_name,
modifier => optional!(ingredient_modifier), modifier => optional!(ingredient_modifier),
_ => optional!(ws),
(Ingredient::new(name, modifier.map(|s| s.to_owned()), measure, "")) (Ingredient::new(name, modifier.map(|s| s.to_owned()), measure, ""))
) )
); );

View File

@ -418,6 +418,7 @@ until thickened. Set aside to cool.
match parse::recipe(StrIter::new(recipe)) { match parse::recipe(StrIter::new(recipe)) {
ParseResult::Complete(_, recipe) => { ParseResult::Complete(_, recipe) => {
assert_eq!(recipe.steps.len(), 2); assert_eq!(recipe.steps.len(), 2);
assert_eq!(recipe.steps[0].ingredients.len(), 3);
} }
err => assert!(false, "{:?}", err), err => assert!(false, "{:?}", err),
} }

View File

@ -263,6 +263,21 @@ impl Measure {
Gram(qty) Gram(qty)
} }
pub fn kilogram(qty: Quantity) -> Self {
Gram(qty * Quantity::Whole(1000))
}
// TODO(jwall): Should these be separate units with conversions?
pub fn lb(qty: Quantity) -> Self {
// This is an approximation obviously
Gram(qty * (Quantity::Whole(453) + Quantity::Frac(Ratio::new(6, 10))))
}
pub fn oz(qty: Quantity) -> Self {
// This is an approximation obviously
Gram(qty * (Quantity::Whole(28) + Quantity::Frac(Ratio::new(4, 10))))
}
pub fn measure_type(&self) -> String { pub fn measure_type(&self) -> String {
match self { match self {
Volume(_) => "Volume", Volume(_) => "Volume",