Skip to content

Commit aa520ab

Browse files
jswrennkaffarell
authored andcommitted
core, subscriber: more downcast_ref & is methods (tokio-rs#2160)
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).
1 parent 5035f85 commit aa520ab

File tree

2 files changed

+89
-1
lines changed

2 files changed

+89
-1
lines changed

tracing-core/src/subscriber.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,66 @@ impl dyn Subscriber {
484484
}
485485
}
486486

487+
impl dyn Subscriber + Send {
488+
/// Returns `true` if this [`Subscriber`] is the same type as `T`.
489+
pub fn is<T: Any>(&self) -> bool {
490+
self.downcast_ref::<T>().is_some()
491+
}
492+
493+
/// Returns some reference to this [`Subscriber`] value if it is of type `T`,
494+
/// or `None` if it isn't.
495+
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
496+
unsafe {
497+
let raw = self.downcast_raw(TypeId::of::<T>())?;
498+
if raw.is_null() {
499+
None
500+
} else {
501+
Some(&*(raw as *const _))
502+
}
503+
}
504+
}
505+
}
506+
507+
impl dyn Subscriber + Sync {
508+
/// Returns `true` if this [`Subscriber`] is the same type as `T`.
509+
pub fn is<T: Any>(&self) -> bool {
510+
self.downcast_ref::<T>().is_some()
511+
}
512+
513+
/// Returns some reference to this `[`Subscriber`] value if it is of type `T`,
514+
/// or `None` if it isn't.
515+
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
516+
unsafe {
517+
let raw = self.downcast_raw(TypeId::of::<T>())?;
518+
if raw.is_null() {
519+
None
520+
} else {
521+
Some(&*(raw as *const _))
522+
}
523+
}
524+
}
525+
}
526+
527+
impl dyn Subscriber + Send + Sync {
528+
/// Returns `true` if this [`Subscriber`] is the same type as `T`.
529+
pub fn is<T: Any>(&self) -> bool {
530+
self.downcast_ref::<T>().is_some()
531+
}
532+
533+
/// Returns some reference to this [`Subscriber`] value if it is of type `T`,
534+
/// or `None` if it isn't.
535+
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
536+
unsafe {
537+
let raw = self.downcast_raw(TypeId::of::<T>())?;
538+
if raw.is_null() {
539+
None
540+
} else {
541+
Some(&*(raw as *const _))
542+
}
543+
}
544+
}
545+
}
546+
487547
/// Indicates a [`Subscriber`]'s interest in a particular callsite.
488548
///
489549
/// `Subscriber`s return an `Interest` from their [`register_callsite`] methods

tracing-subscriber/src/layer/layered.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ use crate::{
1212
};
1313
#[cfg(all(feature = "registry", feature = "std"))]
1414
use crate::{filter::FilterId, registry::Registry};
15-
use core::{any::TypeId, cmp, fmt, marker::PhantomData};
15+
use core::{
16+
any::{Any, TypeId},
17+
cmp, fmt,
18+
marker::PhantomData,
19+
};
1620

1721
/// A [`Subscriber`] composed of a `Subscriber` wrapped by one or more
1822
/// [`Layer`]s.
@@ -63,6 +67,30 @@ pub struct Layered<L, I, S = I> {
6367

6468
// === impl Layered ===
6569

70+
impl<L, S> Layered<L, S>
71+
where
72+
L: Layer<S>,
73+
S: Subscriber,
74+
{
75+
/// Returns `true` if this [`Subscriber`] is the same type as `T`.
76+
pub fn is<T: Any>(&self) -> bool {
77+
self.downcast_ref::<T>().is_some()
78+
}
79+
80+
/// Returns some reference to this [`Subscriber`] value if it is of type `T`,
81+
/// or `None` if it isn't.
82+
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
83+
unsafe {
84+
let raw = self.downcast_raw(TypeId::of::<T>())?;
85+
if raw.is_null() {
86+
None
87+
} else {
88+
Some(&*(raw as *const T))
89+
}
90+
}
91+
}
92+
}
93+
6694
impl<L, S> Subscriber for Layered<L, S>
6795
where
6896
L: Layer<S>,

0 commit comments

Comments
 (0)