macro_rules! impl_box_consumer_methods {
(@and_then Consumer, $struct_name:ident, $first:expr, $after:expr, $t:ident) => {{
let first = $first;
let after = $after;
$struct_name::new(move |t: &$t| {
first.accept(t);
after.accept(t);
})
}};
(@and_then ConsumerOnce, $struct_name:ident, $first:expr, $after:expr, $t:ident) => {{
let first = $first;
let after = $after;
$struct_name::new(move |t: &$t| {
first.accept(t);
after.accept(t);
})
}};
(@and_then StatefulConsumer, $struct_name:ident, $first:expr, $after:expr, $t:ident) => {{
let mut first = $first;
let mut after = $after;
$struct_name::new(move |t: &$t| {
first.accept(t);
after.accept(t);
})
}};
(@and_then_bi BiConsumer, $struct_name:ident, $first:expr, $after:expr, $t:ident, $u:ident) => {{
let first = $first;
let after = $after;
$struct_name::new(move |t: &$t, u: &$u| {
first.accept(t, u);
after.accept(t, u);
})
}};
(@and_then_bi BiConsumerOnce, $struct_name:ident, $first:expr, $after:expr, $t:ident, $u:ident) => {{
let first = $first;
let after = $after;
$struct_name::new(move |t: &$t, u: &$u| {
first.accept(t, u);
after.accept(t, u);
})
}};
(@and_then_bi StatefulBiConsumer, $struct_name:ident, $first:expr, $after:expr, $t:ident, $u:ident) => {{
let mut first = $first;
let mut after = $after;
$struct_name::new(move |t: &$t, u: &$u| {
first.accept(t, u);
after.accept(t, u);
})
}};
(
$struct_name:ident < $t:ident >,
$conditional_type:ident,
$consumer_trait:ident
) => {
pub fn when<P>(self, predicate: P) -> $conditional_type<$t>
where
$t: 'static,
P: Predicate<$t> + 'static,
{
$conditional_type {
consumer: self,
predicate: $crate::BoxPredicate::new(predicate),
}
}
pub fn and_then<C>(self, after: C) -> $struct_name<$t>
where
Self: Sized + 'static,
$t: 'static,
C: $consumer_trait<$t> + 'static,
{
impl_box_consumer_methods!(@and_then $consumer_trait, $struct_name, self, after, $t)
}
};
(
$struct_name:ident < $t:ident, $u:ident >,
$conditional_type:ident,
$consumer_trait:ident
) => {
pub fn when<P>(self, predicate: P) -> $conditional_type<$t, $u>
where
$t: 'static,
$u: 'static,
P: BiPredicate<$t, $u> + 'static,
{
$conditional_type {
consumer: self,
predicate: $crate::BoxBiPredicate::new(predicate),
}
}
pub fn and_then<C>(self, after: C) -> $struct_name<$t, $u>
where
Self: Sized + 'static,
$t: 'static,
$u: 'static,
C: $consumer_trait<$t, $u> + 'static,
{
impl_box_consumer_methods!(@and_then_bi $consumer_trait, $struct_name, self, after, $t, $u)
}
};
}
pub(crate) use impl_box_consumer_methods;