#swift #guard


Provides a ward! macro which returns the contents of an Option and otherwise returns early, and a guard! macro, which does the same, but with a syntax more similar to Swift’s guard syntax

6 stable releases

2.1.0 Sep 16, 2019
2.0.0 Sep 16, 2019
1.1.0 Sep 9, 2019
1.0.2 Sep 9, 2019

#452 in Rust patterns

Download history 377/week @ 2022-06-03 299/week @ 2022-06-10 316/week @ 2022-06-17 256/week @ 2022-06-24 348/week @ 2022-07-01 367/week @ 2022-07-08 382/week @ 2022-07-15 268/week @ 2022-07-22 386/week @ 2022-07-29 403/week @ 2022-08-05 326/week @ 2022-08-12 291/week @ 2022-08-19 332/week @ 2022-08-26 410/week @ 2022-09-02 391/week @ 2022-09-09 346/week @ 2022-09-16

1,533 downloads per month

MIT license



Crates.io Crates.io Crates.io Docs.io

This crate exports two macros, which are intended to replicate the functionality of Swift's guard expression with Option<T>.

The guard! macro was created to emulate the guard let statement in Swift. This macro is only really useful for moving values out of Option<T>s into variables. The ward! macro, on the other hand, doesn't force the creation of a variable, it only returns the value that the guard! variable would place into a variable. As such, it's a more flexible version of the guard! macro; and probably also somewhat more Rustic.


let sut = Some("test");

// This creates the variable res, which from an Option<T> will return a T if it is Some(T), and will
// otherwise return early from the function.
guard!(let res = sut);
assert_eq!(res, "test");

The ward! macro, by comparison, just returns the value, without forcing you to make a variable from it (although we still do in this example):

let sut = Some("test");
let res = ward!(sut);
assert_eq!(res, "test");

Both macros also support an else branch, which will run if the Option<T> is None:

let sut = None;
guard!(let _res = sut, else {
    println!("This will be called!");

    // Because sut is None, the else branch will be run. When the else branch is invoked, guard!
    // no longer automatically returns early for you, so you must do so yourself if you want it.

Both macros also support an alternative "early return statement", which will let you e.g. break within loops:

// Not that you couldn't (and probably should) do this case with `while let Some(res) = sut`...
let mut sut = Some(0);
loop {
    let res = ward!(sut, break);
    sut = if res < 5 {
        Some(res + 1)
    } else {
assert_eq!(sut, None);

No runtime deps