diff --git a/.clj-kondo/.cache/2021.10.20-SNAPSHOT/lock b/.clj-kondo/.cache/2021.10.20-SNAPSHOT/lock new file mode 100644 index 0000000..e69de29 diff --git a/.lsp/.cache/data.mdb b/.lsp/.cache/data.mdb new file mode 100644 index 0000000..87383ee Binary files /dev/null and b/.lsp/.cache/data.mdb differ diff --git a/.lsp/.cache/lock.mdb b/.lsp/.cache/lock.mdb new file mode 100644 index 0000000..144169f Binary files /dev/null and b/.lsp/.cache/lock.mdb differ diff --git a/Cargo.lock b/Cargo.lock index c39d110..8258db3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,11 +1,30 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + [[package]] name = "abortable_parser" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec7b38b411d838e24b7914898b2d3cf3e24adbd81b6edf778e80ea23fe5e9d1" +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + [[package]] name = "autocfg" version = "1.0.1" @@ -172,18 +191,36 @@ dependencies = [ name = "recipes" version = "0.1.0" dependencies = [ + "Inflector", "abortable_parser", "chrono", "num-rational", "uuid", ] +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + [[package]] name = "regex-automata" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + [[package]] name = "ryu" version = "1.0.5" diff --git a/examples/cornbread_dressing.txt b/examples/cornbread_dressing.txt index 2a33b12..f18f602 100644 --- a/examples/cornbread_dressing.txt +++ b/examples/cornbread_dressing.txt @@ -22,7 +22,7 @@ medium-high heat until evenly browned. step: -16 slices white bread +16 white bread slices 2 tsp dried sage 1 tsp dried thyme 1 tsp poultry seasoning diff --git a/recipes/Cargo.toml b/recipes/Cargo.toml index b190790..68d5a14 100644 --- a/recipes/Cargo.toml +++ b/recipes/Cargo.toml @@ -15,4 +15,7 @@ version = "~0.8.2" features = ["v4"] [dependencies.num-rational] -version = "~0.4.0" \ No newline at end of file +version = "~0.4.0" + +[dependencies.Inflector] +version = "0.11.4" diff --git a/recipes/src/parse.rs b/recipes/src/parse.rs index 9745427..f43908a 100644 --- a/recipes/src/parse.rs +++ b/recipes/src/parse.rs @@ -183,26 +183,39 @@ make_fn!( ) ); -make_fn!(unit, +make_fn!(unit, do_each!( u => either!( + text_token!("tsps"), text_token!("tsp"), + text_token!("tbsps"), text_token!("tbsp"), text_token!("floz"), text_token!("ml"), text_token!("ltr"), + text_token!("lbs"), text_token!("lb"), text_token!("oz"), + text_token!("cups"), text_token!("cup"), + text_token!("qrts"), text_token!("qrt"), + text_token!("quarts"), + text_token!("quart"), + text_token!("pints"), text_token!("pint"), text_token!("pnt"), - text_token!("gal"), + text_token!("gals"), text_token!("gal"), text_token!("cnt"), - text_token!("g"), - text_token!("gram")), - (u)) + text_token!("kilograms"), + text_token!("kilogram"), + text_token!("kg"), + text_token!("grams"), + text_token!("gram"), + text_token!("g")), + _ => ws, + (u.to_lowercase().to_singular())) ); make_fn!( @@ -229,7 +242,7 @@ make_fn!( ); make_fn!( - pub measure_parts)>, + pub measure_parts)>, do_each!( qty => quantity, unit => optional!(do_each!( @@ -245,31 +258,31 @@ make_fn!( pub fn measure(i: StrIter) -> abortable_parser::Result { match measure_parts(i) { Result::Complete(i, (qty, unit)) => { + let count = Count(qty.clone()); return Result::Complete( i.clone(), - match unit { - Some("tsp") => Volume(Tsp(qty)), - Some("tbsp") => Volume(Tbsp(qty)), - Some("floz") => Volume(Floz(qty)), - Some("ml") => Volume(ML(qty)), - Some("ltr") | Some("liter") => Volume(Ltr(qty)), - Some("cup") | Some("cp") => Volume(Cup(qty)), - Some("qrt") | Some("quart") => Volume(Qrt(qty)), - Some("pint") | Some("pnt") => Volume(Pint(qty)), - Some("cnt") | Some("count") => Count(qty), - Some("lb") => Weight(Pound(qty)), - Some("oz") => Weight(Oz(qty)), - Some("kg") => Weight(Kilogram(qty)), - Some("g") | Some("gram") => Weight(Gram(qty)), - Some(u) => { - return Result::Abort(abortable_parser::Error::new( - format!("Invalid Unit {}", u), - Box::new(i), - )) + unit.map(|s| match s.as_str() { + "tbsp" => Volume(Tbsp(qty)), + "tsp" => Volume(Tsp(qty)), + "floz" => Volume(Floz(qty)), + "ml" => Volume(ML(qty)), + "ltr" | "liter" => Volume(Ltr(qty)), + "cup" | "cp" => Volume(Cup(qty)), + "qrt" | "quart" => Volume(Qrt(qty)), + "pint" | "pnt" => Volume(Pint(qty)), + "gal" => Volume(Gal(qty)), + "cnt" | "count" => Count(qty), + "lb" => Weight(Pound(qty)), + "oz" => Weight(Oz(qty)), + "kg" | "kilogram" => Weight(Kilogram(qty)), + "g" | "gram" => Weight(Gram(qty)), + _u => { + eprintln!("Invalid unit: {}", _u); + unreachable!() } - None => Count(qty), - }, - ) + }) + .unwrap_or(count), + ); } Result::Fail(e) => { return Result::Fail(e); @@ -281,14 +294,16 @@ pub fn measure(i: StrIter) -> abortable_parser::Result { } } +use inflector::Inflector; + make_fn!( - pub ingredient_name, + pub ingredient_name, do_each!( name => until!(either!( discard!(text_token!("\n")), eoi, discard!(text_token!("(")))), - (name.trim()) + (name.trim().to_singular()) ) ); @@ -310,7 +325,7 @@ make_fn!( name => ingredient_name, 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, String::new())) ) );