diff --git a/tracing-core/src/collect.rs b/tracing-core/src/collect.rs index 869259ca90..a939ef1be2 100644 --- a/tracing-core/src/collect.rs +++ b/tracing-core/src/collect.rs @@ -471,6 +471,54 @@ impl dyn Collect { } } +impl dyn Collect + Send { + /// Returns `true` if this `Collector` is the same type as `T`. + pub fn is(&self) -> bool { + self.downcast_ref::().is_some() + } + + /// Returns some reference to this `Collector` 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::())?; + Some(&*(raw.cast().as_ptr())) + } + } +} + +impl dyn Collect + Sync { + /// Returns `true` if this `Collector` is the same type as `T`. + pub fn is(&self) -> bool { + self.downcast_ref::().is_some() + } + + /// Returns some reference to this `Collector` 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::())?; + Some(&*(raw.cast().as_ptr())) + } + } +} + +impl dyn Collect + Send + Sync { + /// Returns `true` if this `Collector` is the same type as `T`. + pub fn is(&self) -> bool { + self.downcast_ref::().is_some() + } + + /// Returns some reference to this `Collector` 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::())?; + Some(&*(raw.cast().as_ptr())) + } + } +} + /// Indicates a [`Collect`]'s interest in a particular callsite. /// /// Collectors return an `Interest` from their [`register_callsite`] methods diff --git a/tracing-subscriber/src/subscribe/layered.rs b/tracing-subscriber/src/subscribe/layered.rs index fe014c6fe6..4c6ac69c62 100644 --- a/tracing-subscriber/src/subscribe/layered.rs +++ b/tracing-subscriber/src/subscribe/layered.rs @@ -11,7 +11,7 @@ use crate::{ }; #[cfg(all(feature = "registry", feature = "std"))] use crate::{filter::FilterId, registry::Registry}; -use core::{any::TypeId, cmp, fmt, marker::PhantomData, ptr::NonNull}; +use core::{any::{Any, TypeId}, cmp, fmt, marker::PhantomData, ptr::NonNull}; /// A [collector] composed of a [collector] wrapped by one or more /// [subscriber]s. @@ -62,6 +62,26 @@ pub struct Layered { // === impl Layered === +impl Layered +where + S: Subscribe, + C: Collect, +{ + /// Returns `true` if this `Collector` is the same type as `T`. + pub fn is(&self) -> bool { + self.downcast_ref::().is_some() + } + + /// Returns some reference to this `Collector` 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::())?; + Some(&*(raw.cast().as_ptr())) + } + } +} + impl Collect for Layered where S: Subscribe,