tracing_capture/predicates/name.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
//! `name()` predicate factory.
use predicates::{
reflection::{Case, PredicateReflection},
Predicate,
};
use std::fmt;
use crate::CapturedSpan;
/// Creates a predicate for the name of a [`CapturedSpan`].
///
/// # Arguments
///
/// The argument of this function can be any `str`ing predicate, e.g. `eq("test")` for
/// exact comparison.
///
/// # Examples
///
/// ```
/// # use predicates::{ord::eq, str::starts_with};
/// # use tracing_subscriber::{layer::SubscriberExt, Registry};
/// # use tracing_capture::{predicates::{name, ScanExt}, CaptureLayer, SharedStorage};
/// let storage = SharedStorage::default();
/// let subscriber = Registry::default().with(CaptureLayer::new(&storage));
/// tracing::subscriber::with_default(subscriber, || {
/// tracing::info_span!("compute").in_scope(|| {
/// tracing::info!(answer = 42, "done");
/// });
/// });
///
/// let storage = storage.lock();
/// // All of these access the single captured span.
/// let spans = storage.scan_spans();
/// let _ = spans.single(&name(eq("compute")));
/// let _ = spans.single(&name(starts_with("co")));
/// ```
pub fn name<P: Predicate<str>>(matches: P) -> NamePredicate<P> {
NamePredicate { matches }
}
/// Predicate for the name of a [`CapturedSpan`] returned by the [`name()`] function.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct NamePredicate<P> {
matches: P,
}
impl_bool_ops!(NamePredicate<P>);
impl<P: Predicate<str>> fmt::Display for NamePredicate<P> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "name({})", self.matches)
}
}
impl<P: Predicate<str>> PredicateReflection for NamePredicate<P> {}
impl<P: Predicate<str>> Predicate<CapturedSpan<'_>> for NamePredicate<P> {
fn eval(&self, variable: &CapturedSpan<'_>) -> bool {
self.matches.eval(variable.metadata().name())
}
fn find_case(&self, expected: bool, variable: &CapturedSpan<'_>) -> Option<Case<'_>> {
let child = self
.matches
.find_case(expected, variable.metadata().name())?;
Some(Case::new(Some(self), expected).add_child(child))
}
}