1use std::fmt::Debug;
2use std::sync::Arc;
3
4pub trait Sink<T> {
5 fn send(&self, item: T);
6}
7
8impl<T, S: ?Sized> Sink<T> for &S
9where
10 S: Sink<T>,
11{
12 fn send(&self, item: T) {
13 Sink::send(*self, item)
14 }
15}
16
17pub trait SinkMut<T> {
18 fn send(&mut self, item: T);
19}
20
21impl<T, S: ?Sized> SinkMut<T> for &mut S
22where
23 S: SinkMut<T>,
24{
25 fn send(&mut self, item: T) {
26 SinkMut::send(*self, item)
27 }
28}
29
30impl<T, S: ?Sized> SinkMut<T> for &S
31where
32 S: Sink<T>,
33{
34 fn send(&mut self, item: T) {
35 Sink::send(*self, item)
36 }
37}
38
39pub trait SinkOnce<T> {
40 fn send(self, item: T);
41}
42
43impl<T, S: ?Sized> SinkOnce<T> for &S
44where
45 S: Sink<T>,
46{
47 fn send(self, item: T) {
48 Sink::send(&self, item)
49 }
50}
51
52impl<T, S: ?Sized> SinkOnce<T> for &mut S
53where
54 S: SinkMut<T>,
55{
56 fn send(mut self, item: T) {
57 SinkMut::send(&mut self, item)
58 }
59}
60
61#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
63pub struct LogTarget(&'static str);
64
65impl From<&'static str> for LogTarget {
66 fn from(target: &'static str) -> Self {
67 Self(target)
68 }
69}
70
71impl From<LogTarget> for &'static str {
72 fn from(target: LogTarget) -> Self {
73 target.0
74 }
75}
76
77pub trait Logger<T>: Send + Sync {
79 fn log(&self, ev: T);
80
81 fn filter<P>(self, predicate: P) -> Filter<P, Self>
82 where
83 Self: Sized,
84 P: Send + Sync + Fn(&T) -> bool,
85 {
86 Filter::new(self, predicate)
87 }
88
89 fn map<S, F>(self, f: F) -> Map<F, Self>
90 where
91 Self: Sized,
92 F: Send + Sync + Fn(S) -> T,
93 {
94 Map::new(self, f)
95 }
96
97 fn filter_map<S, F>(self, f: F) -> FilterMap<F, Self>
98 where
99 Self: Sized,
100 F: Send + Sync + Fn(S) -> Option<T>,
101 {
102 FilterMap::new(self, f)
103 }
104}
105
106pub struct Filter<P, L> {
108 logger: L,
109 predicate: P,
110}
111
112impl<P, L> Filter<P, L> {
113 fn new(logger: L, predicate: P) -> Self {
114 Self { logger, predicate }
115 }
116}
117
118impl<T, P, L> Logger<T> for Filter<P, L>
119where
120 P: Send + Sync + Fn(&T) -> bool,
121 L: Logger<T>,
122{
123 fn log(&self, ev: T) {
124 if (self.predicate)(&ev) {
125 self.logger.log(ev);
126 }
127 }
128}
129
130pub struct Map<F, L> {
132 logger: L,
133 f: F,
134}
135
136impl<F, L> Map<F, L> {
137 fn new(logger: L, f: F) -> Self {
138 Self { logger, f }
139 }
140}
141
142impl<T, U, F, L> Logger<T> for Map<F, L>
143where
144 F: Send + Sync + Fn(T) -> U,
145 L: Logger<U>,
146{
147 fn log(&self, ev: T) {
148 self.logger.log((self.f)(ev))
149 }
150}
151
152pub struct FilterMap<F, L> {
155 logger: L,
156 f: F,
157}
158
159impl<F, L> FilterMap<F, L> {
160 fn new(logger: L, f: F) -> Self {
161 Self { logger, f }
162 }
163}
164
165impl<T, U, F, L> Logger<T> for FilterMap<F, L>
166where
167 F: Send + Sync + Fn(T) -> Option<U>,
168 L: Logger<U>,
169{
170 fn log(&self, ev: T) {
171 if let Some(ev) = (self.f)(ev) {
172 self.logger.log(ev)
173 }
174 }
175}
176
177impl<L, Ev> Logger<Ev> for &L
178where
179 L: ?Sized + Logger<Ev>,
180{
181 fn log(&self, ev: Ev) {
182 Logger::log(*self, ev)
183 }
184}
185
186impl<L, Ev> Logger<Ev> for Arc<L>
187where
188 L: ?Sized + Logger<Ev>,
189{
190 fn log(&self, ev: Ev) {
191 Logger::log(self.as_ref(), ev)
192 }
193}
194
195#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
197pub struct NoopLogger;
198
199impl<Ev> Logger<Ev> for NoopLogger {
200 fn log(&self, _ev: Ev) {}
201}
202
203pub struct StderrLogger;
205
206impl<Ev> Logger<Ev> for StderrLogger
207where
208 Ev: Debug,
209{
210 fn log(&self, ev: Ev) {
211 eprintln!("{:?}", ev);
212 }
213}
214
215impl<T> SinkMut<T> for Vec<T> {
216 fn send(&mut self, item: T) {
217 self.push(item);
218 }
219}
220
221impl<T> SinkMut<T> for Option<T> {
222 fn send(&mut self, item: T) {
223 *self = Some(item);
224 }
225}