diff --git a/tracing-core/src/subscriber.rs b/tracing-core/src/subscriber.rs index 501cce733d..3d6aaa3441 100644 --- a/tracing-core/src/subscriber.rs +++ b/tracing-core/src/subscriber.rs @@ -484,6 +484,66 @@ impl dyn Subscriber { } } +impl dyn Subscriber + Send { + /// Returns `true` if this [`Subscriber`] is the same type as `T`. + pub fn is(&self) -> bool { + self.downcast_ref::().is_some() + } + + /// Returns some reference to this [`Subscriber`] value if it is of type `T`, + /// or `None` if it isn't. + pub fn downcast_ref(&self) -> Option<&T> { + unsafe { + let raw = self.downcast_raw(TypeId::of::())?; + if raw.is_null() { + None + } else { + Some(&*(raw as *const _)) + } + } + } +} + +impl dyn Subscriber + Sync { + /// Returns `true` if this [`Subscriber`] is the same type as `T`. + pub fn is(&self) -> bool { + self.downcast_ref::().is_some() + } + + /// Returns some reference to this `[`Subscriber`] value if it is of type `T`, + /// or `None` if it isn't. + pub fn downcast_ref(&self) -> Option<&T> { + unsafe { + let raw = self.downcast_raw(TypeId::of::())?; + if raw.is_null() { + None + } else { + Some(&*(raw as *const _)) + } + } + } +} + +impl dyn Subscriber + Send + Sync { + /// Returns `true` if this [`Subscriber`] is the same type as `T`. + pub fn is(&self) -> bool { + self.downcast_ref::().is_some() + } + + /// Returns some reference to this [`Subscriber`] value if it is of type `T`, + /// or `None` if it isn't. + pub fn downcast_ref(&self) -> Option<&T> { + unsafe { + let raw = self.downcast_raw(TypeId::of::())?; + if raw.is_null() { + None + } else { + Some(&*(raw as *const _)) + } + } + } +} + /// Indicates a [`Subscriber`]'s interest in a particular callsite. /// /// `Subscriber`s return an `Interest` from their [`register_callsite`] methods diff --git a/tracing-subscriber/src/layer/layered.rs b/tracing-subscriber/src/layer/layered.rs index 0c6658cb06..5c9b934e35 100644 --- a/tracing-subscriber/src/layer/layered.rs +++ b/tracing-subscriber/src/layer/layered.rs @@ -12,7 +12,11 @@ use crate::{ }; #[cfg(all(feature = "registry", feature = "std"))] use crate::{filter::FilterId, registry::Registry}; -use core::{any::TypeId, cmp, fmt, marker::PhantomData}; +use core::{ + any::{Any, TypeId}, + cmp, fmt, + marker::PhantomData, +}; /// A [`Subscriber`] composed of a `Subscriber` wrapped by one or more /// [`Layer`]s. @@ -63,6 +67,30 @@ pub struct Layered { // === impl Layered === +impl Layered +where + L: Layer, + S: Subscriber, +{ + /// Returns `true` if this [`Subscriber`] is the same type as `T`. + pub fn is(&self) -> bool { + self.downcast_ref::().is_some() + } + + /// Returns some reference to this [`Subscriber`] value if it is of type `T`, + /// or `None` if it isn't. + pub fn downcast_ref(&self) -> Option<&T> { + unsafe { + let raw = self.downcast_raw(TypeId::of::())?; + if raw.is_null() { + None + } else { + Some(&*(raw as *const T)) + } + } + } +} + impl Subscriber for Layered where L: Layer,