Skip to main content

micromegas_tracing/spans/
span_name.rs

1//! Static and runtime span names behind one interface, so that guards and futures are written once.
2use crate::dispatch::{
3    on_begin_async_named_scope, on_begin_async_named_scope_dyn, on_begin_named_scope,
4    on_begin_named_scope_dyn, on_end_async_named_scope, on_end_async_named_scope_dyn,
5    on_end_named_scope, on_end_named_scope_dyn,
6};
7use crate::spans::SpanLocation;
8
9mod sealed {
10    pub trait Sealed {}
11    impl Sealed for super::StaticSpanName {}
12    impl<N: AsRef<str>> Sealed for super::DynSpanName<N> {}
13}
14
15pub trait SpanName: sealed::Sealed {
16    fn begin_thread(&self, loc: &'static SpanLocation);
17    fn end_thread(&self, loc: &'static SpanLocation);
18    fn begin_async(&self, loc: &'static SpanLocation, parent: u64, depth: u32) -> u64;
19    fn end_async(&self, span_id: u64, parent: u64, loc: &'static SpanLocation, depth: u32);
20}
21
22/// A `&'static str` name. It is a lifetime-free wrapper because a trait implemented only for
23/// `&'static str` makes rustc reject `Send` futures that await an instrumented future
24/// ("implementation is not general enough").
25#[derive(Clone, Copy)]
26pub struct StaticSpanName(pub &'static str);
27
28impl SpanName for StaticSpanName {
29    #[inline(always)]
30    fn begin_thread(&self, loc: &'static SpanLocation) {
31        on_begin_named_scope(loc, self.0);
32    }
33
34    #[inline(always)]
35    fn end_thread(&self, loc: &'static SpanLocation) {
36        on_end_named_scope(loc, self.0);
37    }
38
39    #[inline(always)]
40    fn begin_async(&self, loc: &'static SpanLocation, parent: u64, depth: u32) -> u64 {
41        on_begin_async_named_scope(loc, self.0, parent, depth)
42    }
43
44    #[inline(always)]
45    fn end_async(&self, span_id: u64, parent: u64, loc: &'static SpanLocation, depth: u32) {
46        on_end_async_named_scope(span_id, parent, loc, self.0, depth);
47    }
48}
49
50/// A span name built at runtime. It is copied into the block that records each event.
51pub struct DynSpanName<N>(pub N);
52
53impl<N: AsRef<str>> SpanName for DynSpanName<N> {
54    #[inline(always)]
55    fn begin_thread(&self, loc: &'static SpanLocation) {
56        on_begin_named_scope_dyn(loc, self.0.as_ref());
57    }
58
59    #[inline(always)]
60    fn end_thread(&self, loc: &'static SpanLocation) {
61        on_end_named_scope_dyn(loc, self.0.as_ref());
62    }
63
64    #[inline(always)]
65    fn begin_async(&self, loc: &'static SpanLocation, parent: u64, depth: u32) -> u64 {
66        on_begin_async_named_scope_dyn(loc, self.0.as_ref(), parent, depth)
67    }
68
69    #[inline(always)]
70    fn end_async(&self, span_id: u64, parent: u64, loc: &'static SpanLocation, depth: u32) {
71        on_end_async_named_scope_dyn(span_id, parent, loc, self.0.as_ref(), depth);
72    }
73}