aingle_observability/open/
context_wrap.rs

1use super::*;
2
3/// Wrap a channel message in a span context.
4/// The context is automatically propagated to
5/// the current span by calling `msg_wrap.inner()`.
6/// The context is automatically propagated from
7/// the current span by calling `t.into()`.
8/// If you wish to avoid either of these propagations
9/// you can use `msg_wrap.without_context()` and
10/// `MsgWrap::from_no_context(t)` respectively.
11pub struct MsgWrap<T> {
12    t: T,
13    context: Option<Context>,
14}
15
16impl<T> MsgWrap<T> {
17    /// Create a T wrapped in a Context.
18    /// If you just need the current context use
19    /// `t.into()`.
20    pub fn new(t: T, context: Context) -> Self {
21        Self {
22            t,
23            context: Some(context),
24        }
25    }
26    /// Get the inner type and propagate the context to
27    /// the current span.
28    pub fn inner(self) -> T {
29        if let Some(context) = self.context {
30            tracing::Span::set_current_context(context);
31        }
32        self.t
33    }
34    /// Get the inner type without propagating the context.
35    pub fn without_context(self) -> T {
36        self.t
37    }
38
39    /// Create a wrapped T with no Context.
40    pub fn from_no_context(t: T) -> Self {
41        Self { t, context: None }
42    }
43
44    /// Unwrap the wrapped T into a T and Context.
45    /// If you just need to propagate the context to
46    /// the current span use `msg_wrap.inner()`
47    pub fn into_parts(self) -> (T, Context) {
48        (self.t, self.context.unwrap_or_default())
49    }
50}
51
52impl<T> From<T> for MsgWrap<T> {
53    /// Create a wrapped T with the context from
54    /// the current span.
55    fn from(t: T) -> Self {
56        let span = tracing::Span::current();
57        let context = if span.is_disabled() {
58            None
59        } else {
60            Some(span.get_context())
61        };
62
63        Self { t, context }
64    }
65}
66
67impl<T> std::fmt::Debug for MsgWrap<T>
68where
69    T: std::fmt::Debug,
70{
71    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72        f.write_fmt(format_args!("{:?}", self.t))
73    }
74}