macro_rules! impl_shared_conditional_consumer {
(@let_consumer Consumer, $name:ident, $value:expr) => {
let $name = $value;
};
(@let_consumer StatefulConsumer, $name:ident, $value:expr) => {
let mut $name = $value;
};
(@let_consumer BiConsumer, $name:ident, $value:expr) => {
let $name = $value;
};
(@let_consumer StatefulBiConsumer, $name:ident, $value:expr) => {
let mut $name = $value;
};
(
$struct_name:ident < $t:ident >,
$consumer_type:ident,
$consumer_trait:ident,
callback_bounds = ($($callback_bounds:tt)+)
) => {
impl<$t> $struct_name<$t> {
pub fn and_then<C>(&self, next: C) -> $consumer_type<$t>
where
$t: 'static,
C: $consumer_trait<$t> + $($callback_bounds)+,
{
let first_predicate = self.predicate.clone();
impl_shared_conditional_consumer!(@let_consumer $consumer_trait, first_consumer, self.consumer.clone());
impl_shared_conditional_consumer!(@let_consumer $consumer_trait, next, next);
$consumer_type::new(move |t: &$t| {
if first_predicate.test(t) {
first_consumer.accept(t);
}
next.accept(t);
})
}
pub fn or_else<C>(&self, else_consumer: C) -> $consumer_type<$t>
where
$t: 'static,
C: $consumer_trait<$t> + $($callback_bounds)+,
{
let predicate = self.predicate.clone();
impl_shared_conditional_consumer!(@let_consumer $consumer_trait, then_consumer, self.consumer.clone());
impl_shared_conditional_consumer!(@let_consumer $consumer_trait, else_consumer, else_consumer);
$consumer_type::new(move |t: &$t| {
if predicate.test(t) {
then_consumer.accept(t);
} else {
else_consumer.accept(t);
}
})
}
}
};
(
$struct_name:ident < $t:ident, $u:ident >,
$consumer_type:ident,
$consumer_trait:ident,
callback_bounds = ($($callback_bounds:tt)+)
) => {
impl<$t, $u> $struct_name<$t, $u> {
pub fn and_then<C>(&self, next: C) -> $consumer_type<$t, $u>
where
$t: 'static,
$u: 'static,
C: $consumer_trait<$t, $u> + $($callback_bounds)+,
{
let first_predicate = self.predicate.clone();
impl_shared_conditional_consumer!(@let_consumer $consumer_trait, first_consumer, self.consumer.clone());
impl_shared_conditional_consumer!(@let_consumer $consumer_trait, next, next);
$consumer_type::new(move |t: &$t, u: &$u| {
if first_predicate.test(t, u) {
first_consumer.accept(t, u);
}
next.accept(t, u);
})
}
pub fn or_else<C>(&self, else_consumer: C) -> $consumer_type<$t, $u>
where
$t: 'static,
$u: 'static,
C: $consumer_trait<$t, $u> + $($callback_bounds)+,
{
let predicate = self.predicate.clone();
impl_shared_conditional_consumer!(@let_consumer $consumer_trait, then_consumer, self.consumer.clone());
impl_shared_conditional_consumer!(@let_consumer $consumer_trait, else_consumer, else_consumer);
$consumer_type::new(move |t: &$t, u: &$u| {
if predicate.test(t, u) {
then_consumer.accept(t, u);
} else {
else_consumer.accept(t, u);
}
})
}
}
};
}
pub(crate) use impl_shared_conditional_consumer;