#![deny(missing_docs)]
#![doc(html_root_url = "https://docs.rs/adhesion/0.4.0")]
mod parse_generics_shim_util;
#[macro_export]
macro_rules! contract {
(
@muncher,
[double_check $double_check: tt],
$(#[$attribute: meta])*
$(pub$(($access_modifier: ident))*)* fn $fn_name: ident $($tail: tt)*
) => {
contract_fn! {
[callback contract(@muncher, [double_check $double_check],), double_check $double_check],
$(#[$attribute])*
$(pub$(($access_modifier))*)* fn $fn_name $($tail)*
}
};
(
@muncher,
[double_check $_old_double_check: tt],
double_check $double_check: tt
$($tail: tt)+
) => {
contract! {
@muncher,
[double_check $double_check],
$($tail)+
}
};
(
@muncher,
[double_check $_old_double_check: tt],
) => {};
(
$($tail: tt)*
) => {
contract! {
@muncher,
[double_check {}],
$($tail)*
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! contract_fn {
(
[callback $($callback: ident ($($callback_args: tt)*))*, double_check $double_check: tt],
$(#[$attribute: meta])*
$(pub$(($access_modifier: ident))*)* fn $fn_name: ident $($tail: tt)*
) => {
parse_generics_shim! {
{ constr },
then contract_fn!(@after_bracket_generics, [callback $($callback($($callback_args)*))*, double_check $double_check], $(#[$attribute])* $(pub$(($access_modifier))*)* fn $fn_name,),
$($tail)*
}
};
(
@after_bracket_generics,
[callback $($callback: ident ($($callback_args: tt)*))*, double_check $double_check: tt],
$(#[$attribute: meta])*
$(pub$(($access_modifier: ident))*)* fn $fn_name: ident,
{
constr: [$($constr: tt)*],
},
$args: tt $( -> $return_type: ty)* where $($tail: tt)*
) => {
parse_where_shim! {
{ clause, preds },
then contract_fn!(
@after_where_generics,
[callback $($callback($($callback_args)*))*, double_check $double_check],
$(#[$attribute])* $(pub$(($access_modifier))*)* fn $fn_name,
{
constr: [$($constr)*],
},
$args $( -> $return_type)*,
),
where $($tail)*
}
};
(
@after_bracket_generics,
[callback $($callback: ident ($($callback_args: tt)*))*, double_check $double_check: tt],
$(#[$attribute: meta])*
$(pub$(($access_modifier: ident))*)* fn $fn_name: ident,
{
constr: [$($constr: tt)*],
},
$args: tt $( -> $return_type: ty)*
{
$($block: tt)*
}
$($tail: tt)*
) => {
contract_fn! {
@after_where_generics,
[callback $($callback($($callback_args)*))*, double_check $double_check],
$(#[$attribute])*
$(pub$(($access_modifier))*)* fn $fn_name,
{
constr: [$($constr)*],
},
$args $( -> $return_type)*,
{
clause: [],
preds: [],
},
{
$($block)*
}
$($tail)*
}
};
(
@after_where_generics,
[callback $($callback: ident ($($callback_args: tt)*))*, double_check $double_check: tt],
$(#[$attribute: meta])*
$(pub$(($access_modifier: ident))*)* fn $fn_name: ident,
{
constr: [$($constr: tt)*],
},
$args: tt $( -> $return_type: ty)*,
{
clause: [$($where_clause: tt)*],
preds: $preds: tt,
},
{
$($block: tt)*
}
$($tail: tt)*
) => {
$(#[$attribute])*
$(pub$(($access_modifier))*)* fn $fn_name <$($constr)*> $args $( -> $return_type )* $($where_clause)* {
contract_body! {
(pre {}, body {}, post (_def) {}, double_check {}, global_double_check $double_check)
$($block)*
}
}
contract_fn!{
@callback,
[$($callback($($callback_args)*))*],
$($tail)*
}
};
(
@callback,
[],
$($tail: tt)*
) => {};
(
@callback,
[$callback: ident ($($args: tt)*)],
$($tail: tt)*
) => {
$callback!{ $($args)* $($tail)* }
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! contract_body {
(
($($blocks: tt)*)
#![$inner_attribute: meta]
$($tail: tt)*
) => {
contract_body! {
@processing_blocks
($($blocks)*, #![$inner_attribute])
$($tail)*
}
};
(
($($blocks: tt)*)
$($tail: tt)*
) => {
contract_body! {
@processing_blocks
($($blocks)*)
$($tail)*
}
};
(
@processing_blocks
(pre {}, body $body: tt, post ($return_value: ident) $post: tt, double_check $double_check: tt, global_double_check $global_double_check: tt $(, #![$inner_attribute: meta])*)
pre $pre: tt
$($tail: tt)*
) => {
contract_body! {
@processing_blocks
(pre $pre, body $body, post ($return_value) $post, double_check $double_check, global_double_check $global_double_check $(, #![$inner_attribute])*)
$($tail)*
}
};
(
@processing_blocks
(pre $pre: tt, body {}, post ($return_value: ident) $post: tt, double_check $double_check: tt, global_double_check $global_double_check: tt $(, #![$inner_attribute: meta])*)
body $body: tt
$($tail: tt)*
) => {
contract_body! {
@processing_blocks
(pre $pre, body $body, post ($return_value) $post, double_check $double_check, global_double_check $global_double_check $(, #![$inner_attribute])*)
$($tail)*
}
};
(
@processing_blocks
(pre $pre: tt, body $body: tt, post ($old_return_value: ident) {}, double_check $double_check: tt, global_double_check $global_double_check: tt $(, #![$inner_attribute: meta])*)
post ($return_value: ident) $post: tt
$($tail: tt)*
) => {
contract_body! {
@processing_blocks
(pre $pre, body $body, post ($return_value) $post, double_check $double_check, global_double_check $global_double_check $(, #![$inner_attribute])*)
$($tail)*
}
};
(
@processing_blocks
(pre $pre: tt, body $body: tt, post ($return_value: ident) {}, double_check $double_check: tt, global_double_check $global_double_check: tt $(, #![$inner_attribute: meta])*)
post $post: tt
$($tail: tt)*
) => {
contract_body! {
@processing_blocks
(pre $pre, body $body, post ($return_value) $post, double_check $double_check, global_double_check $global_double_check $(, #![$inner_attribute])*)
$($tail)*
}
};
(
@processing_blocks
(pre $pre: tt, body $body: tt, post ($return_value: ident) $post: tt, double_check {}, global_double_check $global_double_check: tt $(, #![$inner_attribute: meta])*)
double_check $double_check: tt
$($tail: tt)*
) => {
contract_body! {
@processing_blocks
(pre $pre, body $body, post ($return_value) $post, double_check $double_check, global_double_check $global_double_check $(, #![$inner_attribute])*)
$($tail)*
}
};
(
@processing_blocks
(pre $pre: tt, body $body: tt, post ($return_value: ident) $post: tt, double_check $double_check: tt, global_double_check $global_double_check: tt $(, #![$inner_attribute: meta])*)
) => {
{
$(#![$inner_attribute])*
$pre
$global_double_check
$double_check
let $return_value = $body;
$global_double_check
$double_check
$post
$return_value
}
};
}