Macro yer

Source
macro_rules! yer {
    (
        $struct_name:ident =>
        let! $var_name:ident = $expression:expr;
        $($tail:tt)*
    ) => { ... };
    (
        $struct_name:ident =>
        let! $var_name:ident: $var_type:ty = $expression:expr;
        $($tail:tt)*
    ) => { ... };
    (
        $struct_name:ident =>
        do! $expression:expr;
        $($tail:tt)*
    ) => { ... };
    (
        $struct_name:ident =>
        let $var_name:ident = $expression:expr;
        $($tail:tt)*
    ) => { ... };
    (
        $struct_name:ident =>
        let $var_name:ident: $var_type:ty = $expression:expr;
        $($tail:tt)*
    ) => { ... };
    (
        $struct_name:ident =>
        do $expression:expr;
        $($tail:tt)*
    ) => { ... };
    ( $struct_name:ident => ret <$($gtype:ty),+> $expression:expr ) => { ... };
    ( $struct_name:ident => ret $expression:expr ) => { ... };
    ( $struct_name:ident => ret! $expression:expr ) => { ... };
    ( $struct_name:ident => ret! <$($gtype:ty),+> $expression:expr ) => { ... };
    (
        $struct_name:ident =>
        yield! $expression:expr;
    ) => { ... };
    (
        $struct_name:ident =>
        yield! $expression:expr;
        $($tail:tt)*
    ) => { ... };
    (
        $struct_name:ident =>
        yield $expression:expr;
    ) => { ... };
    (
        $struct_name:ident =>
        yield $expression:expr;
        $($tail:tt)*
    ) => { ... };
    ( run $struct_name:ident => $($tail:tt)* ) => { ... };
    ( $struct_name:ident >> $($tail:tt)* ) => { ... };
    ( $previous_struct_name:ident => $struct_name:ident => $($tail:tt)* ) => { ... };
    ( $previous_struct_name:ident => $struct_name:ident! => $($tail:tt)* ) => { ... };
    (
        $struct_name:ident =>
        if ($if_expr:expr) {
            $($if_block:tt)*
        }
        $($tail:tt)*
    ) => { ... };
    ( $struct_name:ident => ) => { ... };
}
Expand description

yerevan.rs macros for fancy-shmancy syntax for computation expressions.

Example:

use yerevan::yer;

// Some simple user-defined structs for compuation expressions
struct SimpleBinder {}
impl SimpleBinder {
    pub fn bind<T, U>(val: Option<T>, f: &dyn Fn(T) -> Option<U>) -> Option<U> {
        match val {
            Some(v) => f(v),
            None => SimpleBinder::zero(),
        }
    }
    pub fn ret<T>(val: T) -> Option<T> {
        Some(val)
    }
    pub fn zero<T>() -> Option<T> {
        None
    }
}

struct Incrementer {}
impl Incrementer {
    pub fn bind(val: i32, f: &dyn Fn(i32) -> i32) -> i32 {
        f(val + 1)
    }
    pub fn ret(val: i32) -> i32 {
        val
    }
}

pub fn showcase(wrapped1: Option<i32>, wrapped2: Option<&str>) -> bool {
    let from_macro = yer!(
        SimpleBinder =>
        let! unwrapped1 = wrapped1;
        let! unwrapped2 = wrapped2;
        let one = 1;
        Incrementer =>
        let! res = one + unwrapped1 + (unwrapped2.len() as i32);
        ret res
    );
    let by_hand =
        SimpleBinder::bind(
        wrapped1, &|unwrapped1| {
        SimpleBinder::bind(
        wrapped2, &|unwrapped2| {
        let one = 1;
        SimpleBinder::ret(
        Incrementer::bind(
        one + unwrapped1 + (unwrapped2.len() as i32), &|res| {
        Incrementer::ret(res)
        })
        )
        })
        });
    from_macro == by_hand // true
}