1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
// Copyright (c) 2018-2024 Brendan Molloy <brendan@bbqsrc.net>,
// Ilya Solovyiov <ilya.solovyiov@gmail.com>,
// Kai Ren <tyranron@gmail.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Passing events to one of two [`Writer`]s based on a predicate.
use crate::{cli, event, parser, writer, Event, World, Writer};
/// Wrapper for passing events to one of two [`Writer`]s based on a predicate.
#[derive(Clone, Copy, Debug)]
pub struct Or<L, R, F> {
/// Left [`Writer`].
left: L,
/// Right [`Writer`].
right: R,
/// Predicate indicating which [`Writer`] should be used.
/// `left` is used on [`true`] and `right` on [`false`].
predicate: F,
}
impl<L, R, F> Or<L, R, F> {
/// Creates a new [`Or`] [`Writer`] passing events to the `left` and `right`
/// [`Writer`]s based on the specified `predicate`.
///
/// In case `predicate` returns [`true`], the `left` [`Writer`] is used,
/// otherwise the `right` [`Writer`] is used on [`false`].
#[must_use]
pub const fn new(left: L, right: R, predicate: F) -> Self {
Self {
left,
right,
predicate,
}
}
/// Returns the left [`Writer`] of this [`Or`] one.
#[must_use]
pub const fn left_writer(&self) -> &L {
&self.left
}
/// Returns the right [`Writer`] of this [`Or`] one.
#[must_use]
pub const fn right_writer(&self) -> &R {
&self.right
}
}
#[warn(clippy::missing_trait_methods)]
impl<W, L, R, F> Writer<W> for Or<L, R, F>
where
W: World,
L: Writer<W>,
R: Writer<W>,
F: FnMut(
&parser::Result<Event<event::Cucumber<W>>>,
&cli::Compose<L::Cli, R::Cli>,
) -> bool,
{
type Cli = cli::Compose<L::Cli, R::Cli>;
async fn handle_event(
&mut self,
ev: parser::Result<Event<event::Cucumber<W>>>,
cli: &Self::Cli,
) {
if (self.predicate)(&ev, cli) {
self.left.handle_event(ev, &cli.left).await;
} else {
self.right.handle_event(ev, &cli.right).await;
}
}
}
impl<W, L, R, F> writer::Stats<W> for Or<L, R, F>
where
L: writer::Stats<W>,
R: writer::Stats<W>,
F: FnMut(
&parser::Result<Event<event::Cucumber<W>>>,
&cli::Compose<L::Cli, R::Cli>,
) -> bool,
Self: Writer<W>,
{
fn passed_steps(&self) -> usize {
self.left.passed_steps() + self.right.passed_steps()
}
fn skipped_steps(&self) -> usize {
self.left.skipped_steps() + self.right.skipped_steps()
}
fn failed_steps(&self) -> usize {
self.left.failed_steps() + self.right.failed_steps()
}
fn retried_steps(&self) -> usize {
self.left.retried_steps() + self.right.retried_steps()
}
fn parsing_errors(&self) -> usize {
self.left.parsing_errors() + self.right.parsing_errors()
}
fn hook_errors(&self) -> usize {
self.left.hook_errors() + self.right.hook_errors()
}
}
#[warn(clippy::missing_trait_methods)]
impl<L, R, F> writer::Normalized for Or<L, R, F>
where
L: writer::Normalized,
R: writer::Normalized,
{
}
#[warn(clippy::missing_trait_methods)]
impl<L, R, F> writer::NonTransforming for Or<L, R, F>
where
L: writer::NonTransforming,
R: writer::NonTransforming,
{
}