metrics_prometheus/recorder/
layer.rs

1//! [`metrics::Layer`] implementations.
2//!
3//! [`metrics::Layer`]: Layer
4
5pub use metrics_util::layers::Layer;
6
7/// No-op [`metrics::Layer`] which returns the received [`metrics::Recorder`]
8/// "as is".
9///
10/// [`metrics::Layer`]: Layer
11#[derive(Clone, Copy, Debug)]
12pub struct Identity;
13
14impl<R> Layer<R> for Identity {
15    type Output = R;
16
17    #[expect(clippy::renamed_function_params, reason = "impl related")]
18    fn layer(&self, itself: R) -> R {
19        itself
20    }
21}
22
23/// [`metrics::Layer`] similar to [`metrics::layers::Stack`], but nests the
24/// [`metrics::Layer`]s themselves instead of [`metrics::Recorder`]s.
25///
26/// [`metrics::Layer`]: Layer
27/// [`metrics::layers::Stack`]: metrics_util::layers::Stack
28#[derive(Clone, Copy, Debug)]
29pub struct Stack<Head = Identity, Tail = Identity>(Head, Tail);
30
31impl Stack {
32    /// Returns a growable [`Stack`] of [`metrics::Layer`]s, being no-op by
33    /// default.
34    ///
35    /// [`metrics::Layer`]: Layer
36    #[must_use]
37    pub const fn identity() -> Self {
38        Self(Identity, Identity)
39    }
40}
41
42impl<H, T> Stack<H, T> {
43    /// Pushes the provided [`metrics::Layer`] on top of this [`Stack`],
44    /// wrapping it.
45    ///
46    /// [`metrics::Layer`]: Layer
47    #[must_use]
48    pub const fn push<R, L: Layer<R>>(self, layer: L) -> Stack<L, Self> {
49        Stack(layer, self)
50    }
51}
52
53#[warn(clippy::missing_trait_methods)]
54impl<R, H, T> Layer<R> for Stack<H, T>
55where
56    H: Layer<<T as Layer<R>>::Output>,
57    T: Layer<R>,
58{
59    type Output = H::Output;
60
61    fn layer(&self, inner: R) -> Self::Output {
62        self.0.layer(self.1.layer(inner))
63    }
64}