mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2025-03-12 16:11:43 +01:00
65 lines
1.7 KiB
Rust
65 lines
1.7 KiB
Rust
use tracing_core::span::Id;
|
|
|
|
// This has been copied from tracing-subscriber. Once the library adds
|
|
// the ability to iterate over entered spans, this code will
|
|
// no longer be needed here
|
|
//
|
|
// https://github.com/tokio-rs/tracing/blob/master/tracing-subscriber/src/registry/stack.rs
|
|
#[derive(Debug, Clone)]
|
|
pub(crate) struct ContextId {
|
|
id: Id,
|
|
duplicate: bool,
|
|
}
|
|
|
|
impl ContextId {
|
|
pub fn id(&self) -> &Id {
|
|
&self.id
|
|
}
|
|
}
|
|
|
|
/// `SpanStack` tracks what spans are currently executing on a thread-local basis.
|
|
///
|
|
/// A "separate current span" for each thread is a semantic choice, as each span
|
|
/// can be executing in a different thread.
|
|
#[derive(Debug, Default)]
|
|
pub(crate) struct SpanStack {
|
|
stack: Vec<ContextId>,
|
|
}
|
|
|
|
impl SpanStack {
|
|
#[inline]
|
|
pub(crate) fn push(&mut self, id: Id) -> bool {
|
|
let duplicate = self.stack.iter().any(|i| i.id == id);
|
|
self.stack.push(ContextId { id, duplicate });
|
|
!duplicate
|
|
}
|
|
|
|
/// Pop a currently entered span.
|
|
///
|
|
/// Returns `true` if the span was actually exited.
|
|
#[inline]
|
|
pub(crate) fn pop(&mut self, expected_id: &Id) -> bool {
|
|
if let Some((idx, _)) = self
|
|
.stack
|
|
.iter()
|
|
.enumerate()
|
|
.rev()
|
|
.find(|(_, ctx_id)| ctx_id.id == *expected_id)
|
|
{
|
|
let ContextId { id: _, duplicate } = self.stack.remove(idx);
|
|
return !duplicate;
|
|
}
|
|
false
|
|
}
|
|
|
|
pub(crate) fn iter(&self) -> impl Iterator<Item = &Id> {
|
|
self.stack
|
|
.iter()
|
|
.filter_map(|ContextId { id, duplicate }| if *duplicate { None } else { Some(id) })
|
|
}
|
|
|
|
pub(crate) fn stack(&self) -> &Vec<ContextId> {
|
|
&self.stack
|
|
}
|
|
}
|