use crate::{span, Dispatch, Event, LevelFilter, Metadata};
use crate::stdlib::{
any::{Any, TypeId},
boxed::Box,
sync::Arc,
};
pub trait Subscriber: 'static {
fn on_register_dispatch(&self, subscriber: &Dispatch) {
let _ = subscriber;
}
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 max_level_hint(&self) -> Option<LevelFilter> {
None
}
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_enabled(&self, event: &Event<'_>) -> bool {
let _ = event;
true
}
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)]
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 _))
}
}
}
}
impl dyn Subscriber + Send {
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 _))
}
}
}
}
impl dyn Subscriber + Sync {
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 _))
}
}
}
}
impl dyn Subscriber + Send + Sync {
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 {
matches!(self.0, InterestKind::Never)
}
#[inline]
pub fn is_sometimes(&self) -> bool {
matches!(self.0, InterestKind::Sometimes)
}
#[inline]
pub fn is_always(&self) -> bool {
matches!(self.0, InterestKind::Always)
}
pub(crate) fn and(self, rhs: Interest) -> Self {
if self.0 == rhs.0 {
self
} else {
Interest::sometimes()
}
}
}
#[derive(Copy, Clone, Debug, Default)]
pub struct NoSubscriber(());
impl Subscriber for NoSubscriber {
#[inline]
fn register_callsite(&self, _: &'static Metadata<'static>) -> Interest {
Interest::never()
}
fn new_span(&self, _: &span::Attributes<'_>) -> span::Id {
span::Id::from_u64(0xDEAD)
}
fn event(&self, _event: &Event<'_>) {}
fn record(&self, _span: &span::Id, _values: &span::Record<'_>) {}
fn record_follows_from(&self, _span: &span::Id, _follows: &span::Id) {}
#[inline]
fn enabled(&self, _metadata: &Metadata<'_>) -> bool {
false
}
fn enter(&self, _span: &span::Id) {}
fn exit(&self, _span: &span::Id) {}
}
impl NoSubscriber {
#[must_use]
pub const fn new() -> Self {
Self(())
}
}
impl<S> Subscriber for Box<S>
where
S: Subscriber + ?Sized,
{
#[inline]
fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
self.as_ref().register_callsite(metadata)
}
#[inline]
fn enabled(&self, metadata: &Metadata<'_>) -> bool {
self.as_ref().enabled(metadata)
}
#[inline]
fn max_level_hint(&self) -> Option<LevelFilter> {
self.as_ref().max_level_hint()
}
#[inline]
fn new_span(&self, span: &span::Attributes<'_>) -> span::Id {
self.as_ref().new_span(span)
}
#[inline]
fn record(&self, span: &span::Id, values: &span::Record<'_>) {
self.as_ref().record(span, values)
}
#[inline]
fn record_follows_from(&self, span: &span::Id, follows: &span::Id) {
self.as_ref().record_follows_from(span, follows)
}
#[inline]
fn event_enabled(&self, event: &Event<'_>) -> bool {
self.as_ref().event_enabled(event)
}
#[inline]
fn event(&self, event: &Event<'_>) {
self.as_ref().event(event)
}
#[inline]
fn enter(&self, span: &span::Id) {
self.as_ref().enter(span)
}
#[inline]
fn exit(&self, span: &span::Id) {
self.as_ref().exit(span)
}
#[inline]
fn clone_span(&self, id: &span::Id) -> span::Id {
self.as_ref().clone_span(id)
}
#[inline]
fn try_close(&self, id: span::Id) -> bool {
self.as_ref().try_close(id)
}
#[inline]
#[allow(deprecated)]
fn drop_span(&self, id: span::Id) {
self.as_ref().try_close(id);
}
#[inline]
fn current_span(&self) -> span::Current {
self.as_ref().current_span()
}
#[inline]
unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> {
if id == TypeId::of::<Self>() {
return Some(self as *const Self as *const _);
}
self.as_ref().downcast_raw(id)
}
}
impl<S> Subscriber for Arc<S>
where
S: Subscriber + ?Sized,
{
#[inline]
fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
self.as_ref().register_callsite(metadata)
}
#[inline]
fn enabled(&self, metadata: &Metadata<'_>) -> bool {
self.as_ref().enabled(metadata)
}
#[inline]
fn max_level_hint(&self) -> Option<LevelFilter> {
self.as_ref().max_level_hint()
}
#[inline]
fn new_span(&self, span: &span::Attributes<'_>) -> span::Id {
self.as_ref().new_span(span)
}
#[inline]
fn record(&self, span: &span::Id, values: &span::Record<'_>) {
self.as_ref().record(span, values)
}
#[inline]
fn record_follows_from(&self, span: &span::Id, follows: &span::Id) {
self.as_ref().record_follows_from(span, follows)
}
#[inline]
fn event_enabled(&self, event: &Event<'_>) -> bool {
self.as_ref().event_enabled(event)
}
#[inline]
fn event(&self, event: &Event<'_>) {
self.as_ref().event(event)
}
#[inline]
fn enter(&self, span: &span::Id) {
self.as_ref().enter(span)
}
#[inline]
fn exit(&self, span: &span::Id) {
self.as_ref().exit(span)
}
#[inline]
fn clone_span(&self, id: &span::Id) -> span::Id {
self.as_ref().clone_span(id)
}
#[inline]
fn try_close(&self, id: span::Id) -> bool {
self.as_ref().try_close(id)
}
#[inline]
#[allow(deprecated)]
fn drop_span(&self, id: span::Id) {
self.as_ref().try_close(id);
}
#[inline]
fn current_span(&self) -> span::Current {
self.as_ref().current_span()
}
#[inline]
unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> {
if id == TypeId::of::<Self>() {
return Some(self as *const Self as *const _);
}
self.as_ref().downcast_raw(id)
}
}