1use crate::{connection, endpoint};
5#[cfg(feature = "alloc")]
6use alloc::vec::Vec;
7use core::{fmt, ops::RangeInclusive, time::Duration};
8
9mod generated;
10pub mod metrics;
11pub use generated::*;
12
13#[cfg(any(test, feature = "testing"))]
14#[doc(hidden)]
15pub mod snapshot;
16
17pub trait Event: core::fmt::Debug {
19 const NAME: &'static str;
20}
21
22pub trait IntoEvent<Target> {
23 fn into_event(self) -> Target;
24}
25
26macro_rules! ident_into_event {
27 ($($name:ty),* $(,)?) => {
28 $(
29 impl IntoEvent<$name> for $name {
30 #[inline]
31 fn into_event(self) -> Self {
32 self
33 }
34 }
35 )*
36 };
37}
38
39macro_rules! borrowed_into_event {
40 ($($name:ty),* $(,)?) => {
41 $(
42 impl<'a> IntoEvent<&'a $name> for &'a $name {
43 #[inline]
44 fn into_event(self) -> Self {
45 self
46 }
47 }
48 )*
49 };
50}
51
52ident_into_event!(
53 u8,
54 i8,
55 u16,
56 i16,
57 u32,
58 i32,
59 u64,
60 i64,
61 usize,
62 isize,
63 f32,
64 Duration,
65 bool,
66 connection::Error,
67 endpoint::Location,
68);
69borrowed_into_event!(
70 [u8; 4],
71 [u8; 16],
72 [u8],
73 [u32],
74 [&'a [u8]],
75 (dyn core::error::Error + Send + Sync + 'static)
76);
77
78impl<T: IntoEvent<U>, U> IntoEvent<Option<U>> for Option<T> {
79 #[inline]
80 fn into_event(self) -> Option<U> {
81 self.map(IntoEvent::into_event)
82 }
83}
84
85impl<'a> IntoEvent<&'a str> for &'a str {
86 #[inline]
87 fn into_event(self) -> Self {
88 self
89 }
90}
91
92impl<'a> IntoEvent<&'a (dyn core::any::Any + Send + 'static)>
93 for &'a (dyn core::any::Any + Send + 'static)
94{
95 #[inline]
96 fn into_event(self) -> Self {
97 self
98 }
99}
100
101impl<T> IntoEvent<RangeInclusive<T>> for RangeInclusive<T> {
102 #[inline]
103 fn into_event(self) -> RangeInclusive<T> {
104 self
105 }
106}
107
108#[derive(Clone, Copy)]
109pub struct Timestamp(crate::time::Timestamp);
110
111impl fmt::Debug for Timestamp {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 self.0.fmt(f)
114 }
115}
116
117impl fmt::Display for Timestamp {
118 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119 self.0.fmt(f)
120 }
121}
122
123impl Timestamp {
124 pub fn duration_since_start(&self) -> Duration {
146 unsafe { self.0.as_duration() }
149 }
150
151 #[inline]
154 pub fn saturating_duration_since(self, earlier: Self) -> Duration {
155 self.0.saturating_duration_since(earlier.0)
156 }
157}
158
159impl IntoEvent<Timestamp> for crate::time::Timestamp {
160 #[inline]
161 fn into_event(self) -> Timestamp {
162 Timestamp(self)
163 }
164}
165
166impl IntoEvent<Timestamp> for Timestamp {
167 #[inline]
168 fn into_event(self) -> Timestamp {
169 self
170 }
171}
172
173#[derive(Clone)]
174pub struct TlsSession<'a> {
175 session: &'a dyn crate::crypto::tls::TlsSession,
176}
177
178impl<'a> TlsSession<'a> {
179 #[doc(hidden)]
180 pub fn new(session: &'a dyn crate::crypto::tls::TlsSession) -> TlsSession<'a> {
181 TlsSession { session }
182 }
183
184 pub fn tls_exporter(
185 &self,
186 label: &[u8],
187 context: &[u8],
188 output: &mut [u8],
189 ) -> Result<(), crate::crypto::tls::TlsExportError> {
190 self.session.tls_exporter(label, context, output)
191 }
192
193 #[doc(hidden)]
195 #[cfg(feature = "alloc")]
196 pub fn peer_cert_chain_der(&self) -> Result<Vec<Vec<u8>>, crate::crypto::tls::ChainError> {
197 self.session.peer_cert_chain_der()
198 }
199
200 pub fn cipher_suite(&self) -> crate::event::api::CipherSuite {
201 self.session.cipher_suite().into_event()
202 }
203}
204
205impl<'a> crate::event::IntoEvent<TlsSession<'a>> for TlsSession<'a> {
206 #[inline]
207 fn into_event(self) -> Self {
208 self
209 }
210}
211
212impl core::fmt::Debug for TlsSession<'_> {
213 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
214 f.debug_struct("TlsSession").finish_non_exhaustive()
215 }
216}
217
218#[cfg(feature = "std")]
219impl<'a> IntoEvent<&'a std::io::Error> for &'a std::io::Error {
220 #[inline]
221 fn into_event(self) -> &'a std::io::Error {
222 self
223 }
224}
225
226pub trait Meta: core::fmt::Debug {
228 fn endpoint_type(&self) -> &api::EndpointType;
230
231 fn subject(&self) -> api::Subject;
235
236 fn timestamp(&self) -> &Timestamp;
238}
239
240impl Meta for api::ConnectionMeta {
241 fn endpoint_type(&self) -> &api::EndpointType {
242 &self.endpoint_type
243 }
244
245 fn subject(&self) -> api::Subject {
246 api::Subject::Connection { id: self.id }
247 }
248
249 fn timestamp(&self) -> &Timestamp {
250 &self.timestamp
251 }
252}
253
254impl Meta for api::EndpointMeta {
255 fn endpoint_type(&self) -> &api::EndpointType {
256 &self.endpoint_type
257 }
258
259 fn subject(&self) -> api::Subject {
260 api::Subject::Endpoint {}
261 }
262
263 fn timestamp(&self) -> &Timestamp {
264 &self.timestamp
265 }
266}