Extension traits for Result and Option with tap, map, and error accumulation
cargo add philiprehberger-result-extExtension traits for Result and Option with tap, map, and error accumulation
[dependencies]
philiprehberger-result-ext = "0.3.0"
use philiprehberger_result_ext::{ResultExt, OptionExt, collect_results, ResultGroup};
// Tap for side effects (logging, metrics)
let value = Ok::<_, &str>(42)
.tap_ok(|v| println!("Got value: {}", v))
.tap_err(|e| println!("Error: {}", e));
// Map both variants
let result: Result<String, i32> = Ok("hello")
.map_both(|s| s.to_uppercase(), |e: &str| e.len() as i32);
// Try recovery on error
let result = Err("primary failed")
.or_try(|_| Ok("recovered"));
// Collect all errors, not just the first
let results = vec![Ok(1), Err("a"), Ok(3), Err("b")];
let outcome = collect_results(results);
assert_eq!(outcome, Err(vec!["a", "b"]));
// Accumulate results
let mut group = ResultGroup::new();
group.push(Ok(1));
group.push(Err("oops"));
group.push(Ok(3));
assert!(group.has_errors());
assert_eq!(group.success_count(), 2);
assert_eq!(group.values(), &[1, 3]);
assert_eq!(group.errors(), &["oops"]);
use philiprehberger_result_ext::partition;
let results = vec![Ok(1), Err("a"), Ok(3), Err("b")];
let (oks, errs) = partition(results);
assert_eq!(oks, vec![1, 3]);
assert_eq!(errs, vec!["a", "b"]);
| Function / Type | Description |
|---|---|
ResultExt::tap_ok(f) | Inspect Ok value without consuming |
ResultExt::tap_err(f) | Inspect Err value without consuming |
ResultExt::map_both(ok_fn, err_fn) | Map both Ok and Err variants |
ResultExt::or_try(f) | Try to recover from an error |
ResultExt::tap(f) | Inspect both variants uniformly without consuming |
OptionExt::tap_some(f) | Inspect Some value without consuming |
OptionExt::tap_none(f) | Execute function on None |
OptionExt::ok_or_default() | Unwrap or T::default() for None |
collect_results(iter) | Collect all Ok values or all Err values |
ResultGroup::new() | Create an error accumulator |
ResultGroup::with_capacity(n) | Pre-allocated accumulator |
ResultGroup::push(result) | Add a result to the group |
ResultGroup::extend(iter) | Push every result from an iterator |
ResultGroup::finish() | Get accumulated Ok values or all errors |
ResultGroup::is_empty() | True if no successes and no errors |
ResultGroup::success_count() | Number of successes |
ResultGroup::values() | Reference to accumulated values |
ResultGroup::errors() | Reference to accumulated errors |
ResultGroup::into_parts() | Consume into (oks, errs) tuple |
partition(iter) | Split Results into (Vec<T>, Vec<E>) |
cargo test
cargo clippy -- -D warnings
If you find this project useful: