macro_rules! seedable_function {
(@attrs [$($unseeded:tt)*] [$($seeded:tt)*] [$($optional:tt)*] #[unseeded] #[$attr:meta] $($rest:tt)*) => {
$crate::macros::seeded::seedable_function!(
@attrs [$($unseeded)* #[$attr]] [$($seeded)*] [$($optional)*] $($rest)*
);
};
(@attrs [$($unseeded:tt)*] [$($seeded:tt)*] [$($optional:tt)*] #[seeded] #[$attr:meta] $($rest:tt)*) => {
$crate::macros::seeded::seedable_function!(
@attrs [$($unseeded)*] [$($seeded)* #[$attr]] [$($optional)*] $($rest)*
);
};
(@attrs [$($unseeded:tt)*] [$($seeded:tt)*] [$($optional:tt)*] #[optionally_seeded] #[$attr:meta] $($rest:tt)*) => {
$crate::macros::seeded::seedable_function!(
@attrs [$($unseeded)*] [$($seeded)*] [$($optional)* #[$attr]] $($rest)*
);
};
(@attrs [$($unseeded:tt)*] [$($seeded:tt)*] [$($optional:tt)*] #[$attr:meta] $($rest:tt)*) => {
$crate::macros::seeded::seedable_function!(
@attrs [$($unseeded)* #[$attr]] [$($seeded)* #[$attr]] [$($optional)* #[$attr]] $($rest)*
);
};
(
@attrs $unseeded:tt $seeded:tt $optional:tt
$vis:vis fn $name:ident (&$receiver:ident, $($params:tt)*) -> $ret:ty $body:block
) => {
$crate::macros::seeded::seedable_function!(
@params $unseeded $seeded $optional ($vis) $name $ret $body
[&$receiver,] [$receiver.] [] $($params)*
);
};
(
@attrs $unseeded:tt $seeded:tt $optional:tt
$vis:vis fn $name:ident ($($params:tt)*) -> $ret:ty $body:block
) => {
$crate::macros::seeded::seedable_function!(
@params $unseeded $seeded $optional ($vis) $name $ret $body
[] [Self::] [] $($params)*
);
};
(
@params [$($unseeded:tt)*] [$($seeded:tt)*] [$($optional:tt)*]
($vis:vis) $name:ident $ret:ty $body:block
[$($receiver:tt)*] [$($call:tt)*]
[$($arg:ident : $arg_type:ty,)*]
$seed:ident : Option<[u8; 32]> $(,)?
) => {
paste::paste! {
$($optional)*
$vis fn [<$name _optionally_seeded>](
$($receiver)*
$($arg: $arg_type,)*
$seed: Option<[u8; 32]>,
) -> $ret $body
$($unseeded)*
pub fn $name($($receiver)* $($arg: $arg_type),*) -> $ret {
$($call)*[<$name _optionally_seeded>]($($arg,)* None)
}
$($seeded)*
pub fn [<$name _seeded>]($($receiver)* $($arg: $arg_type,)* $seed: [u8; 32]) -> $ret {
$($call)*[<$name _optionally_seeded>]($($arg,)* Some($seed))
}
}
};
(
@params $unseeded:tt $seeded:tt $optional:tt $vis:tt $name:tt $ret:tt $body:tt
$receiver:tt $call:tt [$($collected:tt)*] $arg:ident : $arg_type:ty, $($rest:tt)*
) => {
$crate::macros::seeded::seedable_function!(
@params $unseeded $seeded $optional $vis $name $ret $body
$receiver $call [$($collected)* $arg: $arg_type,] $($rest)*
);
};
($($input:tt)*) => {
$crate::macros::seeded::seedable_function!(@attrs [] [] [] $($input)*);
};
}
pub(crate) use seedable_function;