#[cfg(not(feature = "async"))]
#[macro_export]
macro_rules! check {
(@check ($($tokens:tt)*) ($session:expr)) => {
$crate::check!(@case $session, ($($tokens)*), (), ())
};
(@check ($session:expr, $($tokens:tt)*) ()) => {
$crate::check!(@check ($($tokens)*) ($session))
};
(@check ($session:expr, $($tokens:tt)*) ($session2:expr)) => {
compile_error!("Wrong number of session arguments")
};
(@check ($($tokens:tt)*) ()) => {
compile_error!("Please provide a session as a first argument")
};
(@check () ($session:expr)) => {
compile_error!("There's no reason in running check with no arguments. Please supply a check branches")
};
(@case $session:expr, ($var:tt = $exp:expr => $body:tt, $($tail:tt)*), ($($head:tt)*), ($($default:tt)*)) => {
$crate::check!(@case $session, ($($tail)*), ($($head)* $var = $exp => $body, ), ($($default)*))
};
(@case $session:expr, ($var:tt = $exp:expr => $body:tt $($tail:tt)*), ($($head:tt)*), ($($default:tt)*)) => {
$crate::check!(@case $session, ($($tail)*), ($($head)* $var = $exp => $body, ), ($($default)*))
};
(@case $session:expr, (default => $($tail:tt)*), ($($head:tt)*), ($($default:tt)+)) => {
compile_error!("Only 1 default case is allowed")
};
(@case $session:expr, (default => $body:tt, $($tail:tt)*), ($($head:tt)*), ()) => {
$crate::check!(@case $session, ($($tail)*), ($($head)*), ( { $body; #[allow(unreachable_code)] Ok(()) } ))
};
(@case $session:expr, (default => $body:tt $($tail:tt)*), ($($head:tt)*), ()) => {
$crate::check!(@case $session, ($($tail)*), ($($head)*), ( { $body; Ok(()) } ))
};
(@case $session:expr, (), ($($head:tt)*), ()) => {
$crate::check!(@case $session, (), ($($head)*), ( { Ok(()) } ))
};
(@case $session:expr, (), ($($tail:tt)*), ($($default:tt)*)) => {
$crate::check!(@branch $session, ($($tail)*), ($($default)*))
};
(@branch $session:expr, ($var:tt = $exp:expr => $body:tt, $($tail:tt)*), ($($default:tt)*)) => {
match $crate::session::Session::check($session, $exp) {
result if result.as_ref().map(|found| !found.is_empty()).unwrap_or(false) => {
let $var = result.unwrap();
$body;
#[allow(unreachable_code)]
Ok(())
}
Ok(_) => {
$crate::check!(@branch $session, ($($tail)*), ($($default)*))
}
Err(err) => Err(err),
}
};
(@branch $session:expr, (), ($default:tt)) => {
$default
};
(@branch $session:expr, ($($tail:tt)*), ($($default:tt)*)) => {
compile_error!(
concat!(
"No supported syntax tail=(",
stringify!($($tail,)*),
") ",
"default=(",
stringify!($($default,)*),
") ",
))
};
($($tokens:tt)*) => {
{
let result: Result::<(), $crate::Error> = $crate::check!(@check ($($tokens)*) ());
result
}
};
}
#[cfg(feature = "async")]
#[macro_export]
macro_rules! check {
(@check ($($tokens:tt)*) ($session:expr)) => {
$crate::check!(@case $session, ($($tokens)*), (), ())
};
(@check ($session:expr, $($tokens:tt)*) ()) => {
$crate::check!(@check ($($tokens)*) ($session))
};
(@check ($session:expr, $($tokens:tt)*) ($session2:expr)) => {
compile_error!("Wrong number of session arguments")
};
(@check ($($tokens:tt)*) ()) => {
compile_error!("Please provide a session as a first argument")
};
(@check () ($session:expr)) => {
compile_error!("There's no reason in running check with no arguments. Please supply a check branches")
};
(@case $session:expr, ($var:tt = $exp:expr => $body:tt, $($tail:tt)*), ($($head:tt)*), ($($default:tt)*)) => {
$crate::check!(@case $session, ($($tail)*), ($($head)* $var = $exp => $body, ), ($($default)*))
};
(@case $session:expr, ($var:tt = $exp:expr => $body:tt $($tail:tt)*), ($($head:tt)*), ($($default:tt)*)) => {
$crate::check!(@case $session, ($($tail)*), ($($head)* $var = $exp => $body, ), ($($default)*))
};
(@case $session:expr, (default => $($tail:tt)*), ($($head:tt)*), ($($default:tt)+)) => {
compile_error!("Only 1 default case is allowed")
};
(@case $session:expr, (default => $body:tt, $($tail:tt)*), ($($head:tt)*), ()) => {
$crate::check!(@case $session, ($($tail)*), ($($head)*), ( { $body; #[allow(unreachable_code)] Ok(()) } ))
};
(@case $session:expr, (default => $body:tt $($tail:tt)*), ($($head:tt)*), ()) => {
$crate::check!(@case $session, ($($tail)*), ($($head)*), ( { $body; Ok(()) } ))
};
(@case $session:expr, (), ($($head:tt)*), ()) => {
$crate::check!(@case $session, (), ($($head)*), ( { Ok(()) } ))
};
(@case $session:expr, (), ($($tail:tt)*), ($($default:tt)*)) => {
$crate::check!(@branch $session, ($($tail)*), ($($default)*))
};
(@branch $session:expr, ($var:tt = $exp:expr => $body:tt, $($tail:tt)*), ($($default:tt)*)) => {
match $crate::session::Session::check(&mut $session, $exp).await {
Ok(found) => {
if !found.is_empty() {
let $var = found;
$body;
#[allow(unreachable_code)]
return Ok(())
}
$crate::check!(@branch $session, ($($tail)*), ($($default)*))
}
Err(err) => Err(err),
}
};
(@branch $session:expr, (), ($default:tt)) => {
$default
};
(@branch $session:expr, ($($tail:tt)*), ($($default:tt)*)) => {
compile_error!(
concat!(
"No supported syntax tail=(",
stringify!($($tail,)*),
") ",
"default=(",
stringify!($($default,)*),
") ",
))
};
($($tokens:tt)*) => {
async {
let value: Result::<(), $crate::Error> = $crate::check!(@check ($($tokens)*) ());
value
}
};
}
#[cfg(test)]
mod tests {
#[allow(unused_variables)]
#[allow(unused_must_use)]
#[test]
#[ignore = "Testing in compile time"]
fn test_check() {
let mut session = crate::spawn("").unwrap();
crate::check! {
&mut session,
as11d = "zxc" => {},
};
crate::check! {
&mut session,
as11d = "zxc" => {},
asbb = "zxc123" => {},
};
crate::check! { session, };
crate::check! {
&mut session,
as11d = "zxc" => {}
asbb = "zxc123" => {}
};
crate::check! {
&mut session,
as11d = "zxc" => {}
default => {}
};
#[cfg(not(feature = "async"))]
{
crate::check! {
&mut session,
as11d = "zxc" => {},
}
.unwrap();
(crate::check! {
&mut session,
as11d = "zxc" => {},
})
.unwrap();
(crate::check! {
&mut session,
as11d = "zxc" => {},
})
.unwrap();
(crate::check! {
&mut session,
as11d = "zxc" => {
println!("asd")
},
})
.unwrap();
}
#[cfg(feature = "async")]
async {
crate::check! {
session,
as11d = "zxc" => {},
}
.await
.unwrap();
(crate::check! {
session,
as11d = "zxc" => {},
})
.await
.unwrap();
(crate::check! {
session,
as11d = "zxc" => {},
})
.await
.unwrap();
(crate::check! {
session,
as11d = "zxc" => {
println!("asd")
},
})
.await
.unwrap();
};
}
}