Skip to content

Commit

Permalink
core, subscriber: more downcast_ref & is methods (#2160)
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
jswrenn committed Jun 13, 2022
1 parent 0d23925 commit 758df19
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 1 deletion.
48 changes: 48 additions & 0 deletions tracing-core/src/collect.rs
Expand Up @@ -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<T: Any>(&self) -> bool {
self.downcast_ref::<T>().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<T: Any>(&self) -> Option<&T> {
unsafe {
let raw = self.downcast_raw(TypeId::of::<T>())?;
Some(&*(raw.cast().as_ptr()))
}
}
}

impl dyn Collect + Sync {
/// Returns `true` if this `Collector` is the same type as `T`.
pub fn is<T: Any>(&self) -> bool {
self.downcast_ref::<T>().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<T: Any>(&self) -> Option<&T> {
unsafe {
let raw = self.downcast_raw(TypeId::of::<T>())?;
Some(&*(raw.cast().as_ptr()))
}
}
}

impl dyn Collect + Send + Sync {
/// Returns `true` if this `Collector` is the same type as `T`.
pub fn is<T: Any>(&self) -> bool {
self.downcast_ref::<T>().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<T: Any>(&self) -> Option<&T> {
unsafe {
let raw = self.downcast_raw(TypeId::of::<T>())?;
Some(&*(raw.cast().as_ptr()))
}
}
}

/// Indicates a [`Collect`]'s interest in a particular callsite.
///
/// Collectors return an `Interest` from their [`register_callsite`] methods
Expand Down
27 changes: 26 additions & 1 deletion tracing-subscriber/src/subscribe/layered.rs
Expand Up @@ -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.
Expand Down Expand Up @@ -62,6 +67,26 @@ pub struct Layered<S, I, C = I> {

// === impl Layered ===

impl<S, C> Layered<S, C>
where
S: Subscribe<C>,
C: Collect,
{
/// Returns `true` if this `Collector` is the same type as `T`.
pub fn is<T: Any>(&self) -> bool {
self.downcast_ref::<T>().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<T: Any>(&self) -> Option<&T> {
unsafe {
let raw = self.downcast_raw(TypeId::of::<T>())?;
Some(&*(raw.cast().as_ptr()))
}
}
}

impl<S, C> Collect for Layered<S, C>
where
S: Subscribe<C>,
Expand Down

0 comments on commit 758df19

Please sign in to comment.