macro_rules! try2 {
($expr:expr $(,)?) => { ... };
}
Expand description
Works like the ?
operator on StashedResult
should.
The try2!
macro works well with or_stash
and ErrorStash::ok
:
#[cfg(any(feature = "rust-v1.81", feature = "std"))]
use lazy_errors::{prelude::*, Result};
#[cfg(not(any(feature = "rust-v1.81", feature = "std")))]
use lazy_errors::surrogate_error_trait::{prelude::*, Result};
fn parse_version(s: &str) -> Result<(u32, u32)> {
let mut errs = ErrorStash::new(|| "Invalid version");
// If `parts` does not contain exactly two elements, return right now.
let [major, minor]: [_; 2] = try2!(s
.split('.')
.collect::<Vec<_>>()
.try_into()
.map_err(|_| Error::from_message("Must have two parts"))
.or_stash(&mut errs));
// If we got exactly two parts, try to parse both of them,
// even if the first part already contains an error.
let major = u32::from_str(major)
.or_stash(&mut errs)
.ok();
let minor = u32::from_str(minor)
.or_stash(&mut errs)
.ok();
// Return _all_ errors if major, minor, or both were invalid.
try2!(errs.ok());
// If the result above was `Ok`, all `ok()` calls returned `Some`.
Ok((major.unwrap(), minor.unwrap()))
}
assert_eq!(parse_version("42.1337").unwrap(), (42, 1337));
let err = parse_version("-1.-2.-3").unwrap_err();
assert_eq!(err.to_string(), "Invalid version: Must have two parts");
let err = parse_version("-1.-2").unwrap_err();
assert_eq!(err.to_string(), "Invalid version (2 errors)");
When the Try
trait is stabilized, this method will probably be replaced
by the ?
operator.
Before Rust had the ?
operator, that behavior was implemented in
the try!
macro. Currently, the ?
operator is being made more
generic: When the Try
trait gets stabilized, we can implement
that trait on any of our types and the ?
operator “should just work”.
Meanwhile, this macro takes the place of the ?
operator
(for StashedResult
only).