diff --git a/Cargo.lock b/Cargo.lock index 8f905a9..4123ffd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,6 @@ dependencies = [ [[package]] name = "estring" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0069d8a2500e291e248b96dc353cf71e2693b278058fd2954b5ed90c836e77" +checksum = "a7cc7b476dae2894e7fb8d37102acc505c8981f754d1cf44aaf666f20cf21e74" diff --git a/Cargo.toml b/Cargo.toml index cf5cbc0..63c4254 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ all-features = true default = [] low-level = ["estring/low-level"] structs = ["estring/structs"] +aggs = ["estring/aggs"] # deprecated number = [] @@ -27,12 +28,12 @@ bool = [] vec = ["structs"] [dependencies] -estring = "0.2" +estring = "0.3" [badges] maintenance = { status = "actively-developed" } [[example]] name = "calc" -required-features = ["structs"] +required-features = ["structs", "aggs"] diff --git a/examples/README.md b/examples/README.md index e8dfe34..0e5a7b4 100644 --- a/examples/README.md +++ b/examples/README.md @@ -11,5 +11,3 @@ E=2*2-1-1+5*3-10 cargo run --example calc --all-features Limits (yet): - Supports `*`, `+`, `-` -- You cannot start from a negative number. `E=-10`. Solution: start from `0`. - `E=0-10`. diff --git a/examples/calc.rs b/examples/calc.rs index 94e3801..e4c23b4 100644 --- a/examples/calc.rs +++ b/examples/calc.rs @@ -1,16 +1,18 @@ -use enve::SepVec; +use enve::{ + estring::{self, Aggregatable, Aggregate}, + Product, SepVec, Sum, +}; -type MinusVec = SepVec; type PlusVec = SepVec; type MulVec = SepVec; const HELP_MESSAGE: &str = " USAGE: -E=10+10*2+4 cargo run --example calc --all-features +E=10+10*2-4 cargo run --example calc --all-features "; fn main() -> Result<(), enve::Error> { - let res: f32 = enve::get::>>>("E") + let res: f32 = enve::get::>>>>>("E") .map_err(|err| { match err { enve::Error::NotPresent => eprintln!("The expression was not found"), @@ -21,16 +23,46 @@ fn main() -> Result<(), enve::Error> { std::process::exit(0); }) .unwrap() - .iter() - .map(|p| { - p.iter() - .map(|m| m.iter().product::()) - .reduce(|acc, v| acc - v) - .unwrap_or_default() - }) - .sum::(); + .agg(); println!("result: {}", res); Ok(()) } + +struct MinusVec(Vec); + +impl estring::ParseFragment for MinusVec +where + T: estring::ParseFragment, +{ + fn parse_frag(es: estring::EString) -> estring::Result { + let mut prev: Option<&str> = None; + es.split('-') + .map(str::trim) + .map(|val| match prev.replace(val) { + None => String::from(val), + Some(_) => { + let mut s = val.to_owned(); + s.insert(0, '-'); + s + } + }) + .filter(|val| !val.is_empty()) + .map(estring::EString::from) + .map(T::parse_frag) + .collect::>>() + .map(Self) + } +} + +impl estring::Aggregatable for MinusVec +where + T: Aggregatable, +{ + type Item = T::Item; + + fn items(self) -> Vec { + self.0.into_iter().flat_map(T::items).collect() + } +} diff --git a/src/estr.rs b/src/estr.rs index 95ffb1d..d3ca26f 100644 --- a/src/estr.rs +++ b/src/estr.rs @@ -4,6 +4,9 @@ mod structs; pub use structs::{CommaVec, SemiVec}; pub use estring::core::EString; + +#[cfg(feature = "aggs")] +pub use estring::agg::*; #[cfg(feature = "low-level")] pub use estring::low::*; #[cfg(feature = "structs")]