From 30b800ce09afa180ed1b1cb4c50380ff19701b57 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Sun, 21 Nov 2021 15:09:13 -0500 Subject: [PATCH] Handle Step Durations --- recipes/src/parse.rs | 43 +++++++++++++++++++++++++++++++++++++++---- recipes/src/test.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/recipes/src/parse.rs b/recipes/src/parse.rs index 0dae279..9745427 100644 --- a/recipes/src/parse.rs +++ b/recipes/src/parse.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. use std::str::FromStr; +use std::time::Duration; use abortable_parser::{ ascii_digit, consume_all, discard, do_each, either, eoi, make_fn, must, not, optional, peek, @@ -78,24 +79,58 @@ make_fn!( ); make_fn!( - pub step_prefix, + pub step_time, + do_each!( + cnt => num, + _ => optional!(ws), + u => either!( + text_token!("ms"), + text_token!("sec"), + text_token!("s"), + text_token!("min"), + text_token!("m"), + text_token!("hrs"), + text_token!("hr"), + text_token!("h") + ), + ( + Duration::from_secs( + match u { + "ms" => (cnt / 1000), + "s" | "sec" => cnt.into(), + "m" | "min" => (dbg!(cnt) * 60), + "h" | "hr" | "hrs" => (cnt * 60 * 60), + _ => unreachable!(), + }.into() + ) + ) + ) +); + +make_fn!( + pub step_prefix>, do_each!( _ => text_token!("step:"), + dur => optional!(do_each!( + _ => ws, + dur => step_time, + (dbg!(dur)) + )), _ => optional!(ws), _ => para_separator, - ("") + (dur) ) ); make_fn!( pub step, do_each!( - _ => step_prefix, + dur => step_prefix, ingredients => must!(ingredient_list), _ => para_separator, desc => description, _ => either!(discard!(para_separator), eoi), - (Step::new(None, desc).with_ingredients(ingredients)) + (Step::new(dur, desc).with_ingredients(ingredients)) ) ); diff --git a/recipes/src/test.rs b/recipes/src/test.rs index d65c788..e178367 100644 --- a/recipes/src/test.rs +++ b/recipes/src/test.rs @@ -361,6 +361,34 @@ until thickens. Set aside to cool." } } +#[test] +fn test_single_step_with_duration() { + let step = "step: 30 min + +1 tbsp flour +2 tbsp butter +1 cup apple (chopped) + +Saute apples in butter until golden brown. Add flour slowly +until thickens. Set aside to cool."; + + match parse::step(StrIter::new(step)) { + ParseResult::Complete(_, step) => { + assert_eq!(step.ingredients.len(), 3); + assert_eq!( + step.instructions, + "Saute apples in butter until golden brown. Add flour slowly +until thickens. Set aside to cool." + ); + assert_eq!( + step.prep_time.unwrap(), + std::time::Duration::new(30 * 60, 0) + ) + } + err => assert!(false, "{:?}", err), + } +} + #[test] fn test_multiple_steps() { let steps = "step: