1use std::sync::Arc;
2
3use super::{BodyEnd, Connect, Dns, Done, Head, Sent, Summary, Tls, Trace};
4
5#[derive(Clone, Default)]
6pub struct Fanout {
7 hooks: Vec<Arc<dyn Trace>>,
8}
9
10impl std::fmt::Debug for Fanout {
11 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12 f.debug_struct("Fanout")
13 .field("hooks", &self.hooks.len())
14 .finish()
15 }
16}
17
18impl Fanout {
19 pub fn new() -> Self {
20 Self::default()
21 }
22
23 pub fn with(mut self, hook: impl Trace) -> Self {
24 self.hooks.push(Arc::new(hook));
25 self
26 }
27
28 fn each(&self, emit: impl Fn(&dyn Trace)) {
29 for hook in &self.hooks {
30 emit(hook.as_ref());
31 }
32 }
33}
34
35impl Trace for Fanout {
36 fn dns(&self, ev: &Dns<'_>) {
37 self.each(|hook| hook.dns(ev));
38 }
39
40 fn connect(&self, ev: &Connect<'_>) {
41 self.each(|hook| hook.connect(ev));
42 }
43
44 fn tls(&self, ev: &Tls<'_>) {
45 self.each(|hook| hook.tls(ev));
46 }
47
48 fn sent(&self, ev: &Sent<'_>) {
49 self.each(|hook| hook.sent(ev));
50 }
51
52 fn head(&self, ev: &Head<'_>) {
53 self.each(|hook| hook.head(ev));
54 }
55
56 fn done(&self, ev: &Done<'_>) {
57 self.each(|hook| hook.done(ev));
58 }
59
60 fn summary(&self, ev: &Summary<'_>) {
61 self.each(|hook| hook.summary(ev));
62 }
63
64 fn body(&self, ev: &BodyEnd<'_>) {
65 self.each(|hook| hook.body(ev));
66 }
67}