Skip to content

Commit cad7f96

Browse files
committed
Support ensure_with macro
1 parent 4d2ef08 commit cad7f96

3 files changed

Lines changed: 106 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
This project roughly adheres to [Semantic Versioning](http://semver.org/). For 0.x.y releases, `x` is the major version in semver, while `y` is the minor version.
44

5+
## Unreleased
6+
7+
* Add convenience macro `ensure_with` for boolean condition checks
8+
59
## 0.3.1 - 2024-06-19
610

711
* Derive Hash, Ord, PartialOrd for SimpleError

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,12 @@ fn main() {
8383
}
8484
// This prints out "cannot watch tv, tv remote not found, failed to open remote file, Text file busy" if the error is text file busy.
8585
```
86+
87+
You can also ensure a condition holds and early-return a `SimpleError` if it does not:
88+
89+
```rust
90+
fn check_config(is_valid: bool) -> Result<(), SimpleError> {
91+
ensure_with!(is_valid, "invalid config");
92+
Ok(())
93+
}
94+
```

src/lib.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,64 @@ macro_rules! require_with {
247247
});
248248
}
249249

250+
/// Helper macro for ensuring a boolean condition while returning early with a
251+
/// newly constructed `SimpleError` if the condition is `false`.
252+
/// Can only be used in functions that return `Result<_, SimpleError>`.
253+
///
254+
/// # Examples
255+
///
256+
/// ```
257+
/// # #[macro_use] extern crate simple_error;
258+
/// # fn main() {
259+
/// use self::simple_error::SimpleError;
260+
/// use std::error::Error;
261+
///
262+
/// fn ensure_block(cond: bool, s: &str) -> Result<(), SimpleError> {
263+
/// ensure_with!(cond, s);
264+
/// Ok(())
265+
/// }
266+
///
267+
/// // Above is equivalent to below.
268+
///
269+
/// fn ensure_block_equivalent(cond: bool, s: &str) -> Result<(), SimpleError> {
270+
/// if !cond {
271+
/// return Err(SimpleError::new(s));
272+
/// }
273+
/// Ok(())
274+
/// }
275+
///
276+
/// // Use a format string
277+
/// fn ensure_block_format(cond: bool, s: &str) -> Result<(), SimpleError> {
278+
/// ensure_with!(cond, "with {}", s);
279+
/// Ok(())
280+
/// }
281+
///
282+
/// // Use a format string to a boxed error
283+
/// fn ensure_block_format_to_box_error(cond: bool, s: &str) -> Result<(), Box<dyn Error>> {
284+
/// ensure_with!(cond, "with {}", s);
285+
/// Ok(())
286+
/// }
287+
/// # }
288+
/// ```
289+
#[macro_export]
290+
macro_rules! ensure_with {
291+
($cond: expr, $fmt:literal) => ({
292+
if !$cond {
293+
return Err(::std::convert::From::from($crate::SimpleError::new(format!($fmt))));
294+
}
295+
});
296+
($cond: expr, $str: expr) => ({
297+
if !$cond {
298+
return Err(::std::convert::From::from($crate::SimpleError::new(::std::convert::AsRef::<str>::as_ref($str))));
299+
}
300+
});
301+
($cond: expr, $fmt:literal, $($arg:tt)+) => ({
302+
if !$cond {
303+
return Err(::std::convert::From::from($crate::SimpleError::new(format!($fmt, $($arg)+))));
304+
}
305+
});
306+
}
307+
250308
/// Helper macro for returning a `SimpleError` constructed from either a `Into<SimpleError>`, a
251309
/// string slice, or a formatted string.
252310
///
@@ -468,6 +526,41 @@ mod tests {
468526
assert_eq!(Err(SimpleError::new("with require block error")), require_block_format_with_capture(None, "require block error"));
469527
}
470528

529+
fn ensure_block(cond: bool, s: &str) -> Result<(), SimpleError> {
530+
ensure_with!(cond, s);
531+
Ok(())
532+
}
533+
534+
fn ensure_block_str_as_ref(cond: bool, s: &String) -> Result<(), SimpleError> {
535+
ensure_with!(cond, s);
536+
Ok(())
537+
}
538+
539+
fn ensure_block_format(cond: bool, s: &str) -> Result<(), SimpleError> {
540+
ensure_with!(cond, "with {}", s);
541+
Ok(())
542+
}
543+
544+
fn ensure_block_format_with_capture(cond: bool, s: &str) -> Result<(), SimpleError> {
545+
ensure_with!(cond, "with {s}");
546+
Ok(())
547+
}
548+
549+
fn ensure_block_format_to_box_error(cond: bool, s: &str) -> Result<(), Box<dyn Error>> {
550+
ensure_with!(cond, "with {}", s);
551+
Ok(())
552+
}
553+
554+
#[test]
555+
fn macro_ensure_with() {
556+
assert_eq!(Ok(()), ensure_block(true, ""));
557+
assert_eq!(Err(SimpleError::new("ensure block error")), ensure_block(false, "ensure block error"));
558+
assert_eq!(Err(SimpleError::new("ensure block error")), ensure_block_str_as_ref(false, &"ensure block error".to_owned()));
559+
assert_eq!(Err(SimpleError::new("with ensure block error")), ensure_block_format(false, "ensure block error"));
560+
assert_eq!(Err(SimpleError::new("with ensure block error")), ensure_block_format_with_capture(false, "ensure block error"));
561+
assert!(ensure_block_format_to_box_error(false, "ensure block error").is_err());
562+
}
563+
471564
fn bail_block_into(es: ErrorSeed) -> Result<(), SimpleError> {
472565
bail!(es);
473566
}

0 commit comments

Comments
 (0)