use crate::{span, Event, Metadata};
use crate::stdlib::any::{Any, TypeId};
pub trait Subscriber: 'static {
fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
if self.enabled(metadata) {
Interest::always()
} else {
Interest::never()
}
}
fn enabled(&self, metadata: &Metadata<'_>) -> bool;
fn new_span(&self, span: &span::Attributes<'_>) -> span::Id;
fn record(&self, span: &span::Id, values: &span::Record<'_>);
fn record_follows_from(&self, span: &span::Id, follows: &span::Id);
fn event(&self, event: &Event<'_>);
fn enter(&self, span: &span::Id);
fn exit(&self, span: &span::Id);
fn clone_span(&self, id: &span::Id) -> span::Id {
id.clone()
}
#[deprecated(since = "0.1.2", note = "use `Subscriber::try_close` instead")]
fn drop_span(&self, _id: span::Id) {}
fn try_close(&self, id: span::Id) -> bool {
#[allow(deprecated)]
let _ = self.drop_span(id);
false
}
fn current_span(&self) -> span::Current {
span::Current::unknown()
}
unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> {
if id == TypeId::of::<Self>() {
Some(self as *const Self as *const ())
} else {
None
}
}
}
impl dyn Subscriber {
pub fn is<T: Any>(&self) -> bool {
self.downcast_ref::<T>().is_some()
}
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
unsafe {
let raw = self.downcast_raw(TypeId::of::<T>())?;
if raw.is_null() {
None
} else {
Some(&*(raw as *const _))
}
}
}
}
#[derive(Clone, Debug)]
pub struct Interest(InterestKind);
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
enum InterestKind {
Never = 0,
Sometimes = 1,
Always = 2,
}
impl Interest {
#[inline]
pub fn never() -> Self {
Interest(InterestKind::Never)
}
#[inline]
pub fn sometimes() -> Self {
Interest(InterestKind::Sometimes)
}
#[inline]
pub fn always() -> Self {
Interest(InterestKind::Always)
}
#[inline]
pub fn is_never(&self) -> bool {
match self.0 {
InterestKind::Never => true,
_ => false,
}
}
#[inline]
pub fn is_sometimes(&self) -> bool {
match self.0 {
InterestKind::Sometimes => true,
_ => false,
}
}
#[inline]
pub fn is_always(&self) -> bool {
match self.0 {
InterestKind::Always => true,
_ => false,
}
}
pub(crate) fn and(self, rhs: Interest) -> Self {
match rhs.0 {
InterestKind::Never => self,
InterestKind::Sometimes if self.0 == InterestKind::Never => rhs,
InterestKind::Always => rhs,
_ => self,
}
}
}