#guard #macro #try

try-guard

A guard! macro inspired by the guard Alternative function from Haskell

3 unstable releases

0.2.0 Jun 7, 2019
0.1.1 May 7, 2019
0.1.0 May 7, 2019

#641 in Rust patterns

Download history 43/week @ 2022-06-02 13/week @ 2022-06-09 15/week @ 2022-06-16 16/week @ 2022-06-23 15/week @ 2022-06-30 13/week @ 2022-07-07 9/week @ 2022-07-14 18/week @ 2022-07-21 9/week @ 2022-07-28 24/week @ 2022-08-04 23/week @ 2022-08-11 11/week @ 2022-08-18 16/week @ 2022-08-25 15/week @ 2022-09-01 25/week @ 2022-09-08 12/week @ 2022-09-15

68 downloads per month
Used in 2 crates

BSD-3-Clause

8KB

The guard Haskell Alternative function brought to Rust

The guard! macro.

The guard! macro implements a control-flow sugar that occurs very often in common Rust code:

fn foo(cond: bool) -> Option<i32> {
  if !cond {
    return None;
  }

  // do something useful

  Some(42)
}

This pattern of testing arguments and early-returning with an error is very typical. Unfortunately, the ? operator doesn’t help us here because we want to early-return on a boolean value, not an error value.

A not very idiomatic and weird way to rewrite that:

fn foo(cond: bool) -> Option<i32> {
  if cond { Some(()) } else { None }?;
  Some(42)
}

This crate provides the guard! macro — analoguous to the guard Haskell Alternative function — that helps early-return from a function if a predicate is false:


use try_guard::guard;

fn foo(cond: bool) -> Option<i32> {
  guard!(cond);
  Some(42)
}

Custom guard types

This crate also allows you to guard to any thing that implements Try<Error = NoneError>. For instance, the following works:


use std::ops::Try;
use std::option::NoneError;
use try_guard::guard;

enum MyGuard<T> {
  Just(T),
  Nothing
}

impl<T> MyGuard<T> {
  fn new(x: T) -> Self {
    MyGuard::Just(x)
  }

  fn none() -> Self {
    MyGuard::Nothing
  }
}

impl<T> Try for MyGuard<T> {
  type Ok = T;

  type Error = NoneError;

  fn from_error(_: Self::Error) -> Self {
    MyGuard::none()
  }

  fn from_ok(x: Self::Ok) -> Self {
    MyGuard::new(x)
  }

  fn into_result(self) -> Result<Self::Ok, Self::Error> {
    match self {
      MyGuard::Just(x) => Ok(x),
      MyGuard::Nothing => Err(NoneError)
    }
  }
}

fn foo(cond: bool) -> MyGuard<i32> {
  guard!(cond);
  MyGuard::new(42)
}

Feature flags

  • The test-nightly feature flag can be used to test nightly-related features that come freely and don’t require a nightly build of rustc to compile this crate but require one at use site.

No runtime deps

Features

  • test-nightly