Skip to content

Commit

Permalink
Impl Success for bool
Browse files Browse the repository at this point in the history
  • Loading branch information
benfrankel committed Aug 1, 2024
1 parent b1b9f41 commit 441cc34
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 36 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ fn increment_last(list: &mut [usize]) {
}
```

The macros support `Option` and `Result` types out-of-the-box. This can be extended by implementing the
[`Success`](https://docs.rs/tiny_bail/latest/tiny_bail/trait.Success.html) trait for other types.
The macros support `bool`, `Option`, and `Result` types out-of-the-box. This can be extended by implementing
the [`Success`](https://docs.rs/tiny_bail/latest/tiny_bail/trait.Success.html) trait for other types.

You can specify the return value as an optional first argument to the macro, or omit it to default to
`Default::default()`—which even works in functions with no return value.
Expand Down
147 changes: 113 additions & 34 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
//! Tiny failure-skipping macros.
// TODO: Expand module-level docs.

/// TODO
/// Re-exported macros.
///
/// The recommended way to use this crate is to glob import the prelude:
///
/// ```rust
/// use tiny_bail::prelude::*;
/// ```
pub mod prelude {
pub use super::{c, cq, or_continue, or_continue_quiet, or_return, or_return_quiet, r, rq};
}

// TODO: Impl `Success<()> for bool`
/// An extension trait for extracting success from failure types.
pub trait Success<T> {
/// Return the success value, or `None` on failure.
fn success(self) -> Option<T>;
}

impl Success<()> for bool {
fn success(self) -> Option<()> {
self.then_some(())
}
}

impl<T> Success<T> for Option<T> {
fn success(self) -> Option<T> {
self
Expand Down Expand Up @@ -152,129 +163,197 @@ macro_rules! or_continue_quiet {
mod tests {
#[test]
fn r() {
fn unwrap_some() -> usize {
fn bail_true() -> usize {
let x = r!(true);
assert_eq!(x, ());
5
}

fn bail_false() -> usize {
r!(false);
5
}

fn bail_some() -> usize {
r!(Some(5))
}

fn unwrap_none() -> usize {
fn bail_none() -> usize {
r!(None)
}

fn unwrap_ok() -> usize {
fn bail_ok() -> usize {
r!(Ok::<_, ()>(5))
}

fn unwrap_err() -> usize {
fn bail_err() -> usize {
r!(Err(()))
}

assert_eq!(unwrap_some(), 5);
assert_eq!(unwrap_none(), 0);
assert_eq!(unwrap_ok(), 5);
assert_eq!(unwrap_err(), 0);
assert_eq!(bail_true(), 5);
assert_eq!(bail_false(), 0);
assert_eq!(bail_some(), 5);
assert_eq!(bail_none(), 0);
assert_eq!(bail_ok(), 5);
assert_eq!(bail_err(), 0);
}

#[test]
fn rq() {
fn unwrap_some() -> usize {
fn bail_true() -> usize {
let x = rq!(true);
assert_eq!(x, ());
5
}

fn bail_false() -> usize {
rq!(false);
5
}

fn bail_some() -> usize {
rq!(Some(5))
}

fn unwrap_none() -> usize {
fn bail_none() -> usize {
rq!(None)
}

fn unwrap_ok() -> usize {
fn bail_ok() -> usize {
rq!(Ok::<_, ()>(5))
}

fn unwrap_err() -> usize {
fn bail_err() -> usize {
rq!(Err(()))
}

assert_eq!(unwrap_some(), 5);
assert_eq!(unwrap_none(), 0);
assert_eq!(unwrap_ok(), 5);
assert_eq!(unwrap_err(), 0);
assert_eq!(bail_true(), 5);
assert_eq!(bail_false(), 0);
assert_eq!(bail_some(), 5);
assert_eq!(bail_none(), 0);
assert_eq!(bail_ok(), 5);
assert_eq!(bail_err(), 0);
}

#[test]
fn c() {
fn unwrap_some() -> usize {
fn bail_true() -> usize {
let mut val = 3;
for _ in 0..1 {
let x = c!(true);
assert_eq!(x, ());
val = 5;
}
val
}

fn bail_false() -> usize {
let mut val = 3;
for _ in 0..1 {
c!(false);
val = 5;
}
val
}

fn bail_some() -> usize {
let mut val = 3;
for _ in 0..1 {
val = c!(Some(5));
}
val
}

fn unwrap_none() -> usize {
fn bail_none() -> usize {
let mut val = 3;
for _ in 0..1 {
val = c!(None);
}
val
}

fn unwrap_ok() -> usize {
fn bail_ok() -> usize {
let mut val = 3;
for _ in 0..1 {
val = c!(Ok::<_, ()>(5));
}
val
}

fn unwrap_err() -> usize {
fn bail_err() -> usize {
let mut val = 3;
for _ in 0..1 {
val = c!(Err(()));
}
val
}

assert_eq!(unwrap_some(), 5);
assert_eq!(unwrap_none(), 3);
assert_eq!(unwrap_ok(), 5);
assert_eq!(unwrap_err(), 3);
assert_eq!(bail_true(), 5);
assert_eq!(bail_false(), 3);
assert_eq!(bail_some(), 5);
assert_eq!(bail_none(), 3);
assert_eq!(bail_ok(), 5);
assert_eq!(bail_err(), 3);
}

#[test]
fn cq() {
fn unwrap_some() -> usize {
fn bail_true() -> usize {
let mut val = 3;
for _ in 0..1 {
let x = cq!(true);
assert_eq!(x, ());
val = 5;
}
val
}

fn bail_false() -> usize {
let mut val = 3;
for _ in 0..1 {
cq!(false);
val = 5;
}
val
}

fn bail_some() -> usize {
let mut val = 3;
for _ in 0..1 {
val = cq!(Some(5));
}
val
}

fn unwrap_none() -> usize {
fn bail_none() -> usize {
let mut val = 3;
for _ in 0..1 {
val = cq!(None);
}
val
}

fn unwrap_ok() -> usize {
fn bail_ok() -> usize {
let mut val = 3;
for _ in 0..1 {
val = cq!(Ok::<_, ()>(5));
}
val
}

fn unwrap_err() -> usize {
fn bail_err() -> usize {
let mut val = 3;
for _ in 0..1 {
val = cq!(Err(()));
}
val
}

assert_eq!(unwrap_some(), 5);
assert_eq!(unwrap_none(), 3);
assert_eq!(unwrap_ok(), 5);
assert_eq!(unwrap_err(), 3);
assert_eq!(bail_true(), 5);
assert_eq!(bail_false(), 3);
assert_eq!(bail_some(), 5);
assert_eq!(bail_none(), 3);
assert_eq!(bail_ok(), 5);
assert_eq!(bail_err(), 3);
}
}

0 comments on commit 441cc34

Please sign in to comment.