commonware_consensus/
reporter.rs

1//! Reporter implementations for various standard types.
2
3use crate::Reporter;
4use futures::join;
5use std::marker::PhantomData;
6
7/// An implementation of [Reporter] for an optional [Reporter].
8///
9/// This is useful for reporting activity to a [Reporter] that may not be present.
10/// Reporting is a no-op if the [Reporter] is `None`.
11impl<A: Send, R: Reporter<Activity = A>> Reporter for Option<R> {
12    type Activity = A;
13
14    async fn report(&mut self, activity: Self::Activity) {
15        let Some(reporter) = self else {
16            return;
17        };
18        reporter.report(activity).await;
19    }
20}
21
22/// A struct used to report activity to multiple [Reporter]s (which may or may not be present).
23#[derive(Clone)]
24pub struct Reporters<A, R1, R2> {
25    r1: Option<R1>,
26    r2: Option<R2>,
27
28    _phantom: PhantomData<A>,
29}
30
31impl<A, R1, R2> Reporter for Reporters<A, R1, R2>
32where
33    A: Clone + Send + 'static,
34    R1: Reporter<Activity = A>,
35    R2: Reporter<Activity = A>,
36{
37    type Activity = A;
38
39    async fn report(&mut self, activity: Self::Activity) {
40        // This approach avoids cloning activity, if possible.
41        match (&mut self.r1, &mut self.r2) {
42            (Some(r1), Some(r2)) => join!(r1.report(activity.clone()), r2.report(activity)),
43            (Some(r1), None) => (r1.report(activity).await, ()),
44            (None, Some(r2)) => ((), r2.report(activity).await),
45            (None, None) => ((), ()),
46        };
47    }
48}
49
50impl<A, R1, R2> From<(Option<R1>, Option<R2>)> for Reporters<A, R1, R2> {
51    fn from((r1, r2): (Option<R1>, Option<R2>)) -> Self {
52        Self {
53            r1,
54            r2,
55            _phantom: PhantomData,
56        }
57    }
58}
59
60impl<A, R1, R2> From<(Option<R1>, R2)> for Reporters<A, R1, R2> {
61    fn from((r1, r2): (Option<R1>, R2)) -> Self {
62        Self {
63            r1,
64            r2: Some(r2),
65            _phantom: PhantomData,
66        }
67    }
68}
69
70impl<A, R1, R2> From<(R1, Option<R2>)> for Reporters<A, R1, R2> {
71    fn from((r1, r2): (R1, Option<R2>)) -> Self {
72        Self {
73            r1: Some(r1),
74            r2,
75            _phantom: PhantomData,
76        }
77    }
78}
79
80impl<A, R1, R2> From<(R1, R2)> for Reporters<A, R1, R2> {
81    fn from((r1, r2): (R1, R2)) -> Self {
82        Self {
83            r1: Some(r1),
84            r2: Some(r2),
85            _phantom: PhantomData,
86        }
87    }
88}