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
}