diff --git a/Cargo.toml b/Cargo.toml index 40a9121..f372dd0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rematch" -version = "0.3.0" +version = "0.3.1" authors = ["Avril "] edition = "2024" diff --git a/src/main.rs b/src/main.rs index 3fccdf6..ec25428 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,52 @@ mod re; mod text; +/// Run an expression on an named value with a result type `Result`. +/// Where `T` and `U` have *the same API surface* for the duration of the provided expression. +/// +/// # Example +/// If there is a value `let mut value: Result`, where `T: Write` & `U: BufWrite`; +/// the expression `value.flush()` is valid for both `T` and `U`. +/// Therefore, it can be simplified to be called as so: `unwrap_either(mut value => value.flush())`. +/// +/// # Reference capture vs. `move` capture. +/// Note that by default, the identified value is **moved** *into* the expression. +/// The type of reference can be controlled by appending `ref`, `mut`, or `ref mut` to the ident. +/// +/// Identifier capture table: +/// - **none** ~default~ - Capture by move, value is immutable in expression. +/// - `mut` - Capture by move, value is mutable in expression. +/// - `ref` - Capture by ref, value is immutable (`&value`) in expression. +/// - `ref mut` - Capture by mutable ref, value is mutable (`&mut value`) in expression. (__NOTE__: `value` must be defined as mutable to take a mutable reference of it.) +/// +/// Essentially the same rules as any `match` branch pattern. +macro_rules! unwrap_either { + ($res:ident => $($rest:tt)+) => { + match $res { + Ok(ref mut $res) => $($rest)+, + Err(ref mut $res) => $($rest)+, + } + }; + (ref mut $res:ident => $($rest:tt)+) => { + match $res { + Ok(ref mut $res) => $($rest)+, + Err(ref mut $res) => $($rest)+, + } + }; + (ref $res:ident => $($rest:tt)+) => { + match $res { + Ok(ref $res) => $($rest)+, + Err(ref $res) => $($rest)+, + } + }; + (mut $res:ident => $($rest:tt)+) => { + match $res { + Ok(mut $res) => $($rest)+, + Err(mut $res) => $($rest)+, + } + }; +} + use color_eyre::{ eyre::{ self, @@ -99,9 +145,9 @@ fn main() -> eyre::Result<()> use std::io::Write; let mut stdout = std::io::stdout(); - if &text[..] == "-" { + let stdout = if &text[..] == "-" { + let mut stdout = std::io::BufWriter::new(stdout.lock()); text::stdin_lines(|text| -> eyre::Result { - let mut stdout = stdout.lock(); match re.exec(&text)? { Some(g) /*if g.len() > group*/ => // NOTE: This check branch has now been moved into `print_groups()` print_groups(&mut stdout, &g, &groups)?, //println!("{}", &g[group]), @@ -109,14 +155,18 @@ fn main() -> eyre::Result<()> } Ok(true) })?; + + Some(stdout) } else { match re.exec(&text)? { Some(g) /*if g.len() > group*/ => print_groups(&mut stdout, &g[..], &groups)?,//println!("{}", &g.nth(group).unwrap().map(|x| x.as_ref()).unwrap_or("")), _ => (), } - } - stdout.flush().unwrap(); + + None + }.ok_or_else(move || stdout); + unwrap_either!(mut stdout => stdout.flush()).unwrap(); } Ok(()) }