From 331e9f09cf4a777287e6e4e98a0f0170cbac81ec Mon Sep 17 00:00:00 2001 From: Jack Wrenn Date: Fri, 10 Jun 2022 14:12:06 -0400 Subject: [PATCH] tracing-core,tracing-subscriber: more `downcast_ref` & `is` methods Adds inherent `downcast_ref` and `is` inherent methods to: - `dyn Subscriber + Send` - `dyn Subscriber + Sync` - `dyn Subscriber + Send + Sync` - `Layered` These additional implementations reduce the circumstances in which one must cast to `dyn Subscriber` (which, previously, was the only type for which `downcast_ref` and `is` were available). --- tracing-core/src/collect.rs | 48 +++++++++++++++++++++ tracing-subscriber/src/subscribe/layered.rs | 27 +++++++++++- 2 files changed, 74 insertions(+), 1 deletion(-) 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..813bafebba 100644 --- a/tracing-subscriber/src/subscribe/layered.rs +++ b/tracing-subscriber/src/subscribe/layered.rs @@ -11,7 +11,12 @@ 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 +67,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,