1use tracing::Subscriber;
2use tracing_subscriber::filter::Targets;
3use tracing_subscriber::prelude::*;
4use tracing_subscriber::Layer;
5
6#[test]
7fn downcast_ref_to_inner_layer_and_filter() {
8 // Test that a filtered layer gives downcast_ref access to
9 // both the layer and the filter.
10
11 struct WrappedLayer;
12
13 impl<S> Layer<S> for WrappedLayer
14 where
15 S: Subscriber,
16 S: for<'lookup> tracing_subscriber::registry::LookupSpan<'lookup>,
17 {
18 }
19
20 let layer = WrappedLayer;
21 let filter = Targets::new().with_default(tracing::Level::INFO);
22 let registry = tracing_subscriber::registry().with(layer.with_filter(filter));
23 let dispatch = tracing::dispatcher::Dispatch::new(registry);
24
25 // The filter is available
26 assert!(dispatch.downcast_ref::<Targets>().is_some());
27 // The wrapped layer is available
28 assert!(dispatch.downcast_ref::<WrappedLayer>().is_some());
29}
30
31#[test]
32fn forward_downcast_raw_to_layer() {
33 // Test that a filtered layer still gives its wrapped layer a chance to
34 // return a custom struct from downcast_raw.
35 // https://github.com/tokio-rs/tracing/issues/1618
36
37 struct WrappedLayer {
38 with_context: WithContext,
39 }
40
41 struct WithContext;
42
43 impl<S> Layer<S> for WrappedLayer
44 where
45 S: Subscriber,
46 S: for<'lookup> tracing_subscriber::registry::LookupSpan<'lookup>,
47 {
48 unsafe fn downcast_raw(&self, id: std::any::TypeId) -> Option<*const ()> {
49 match id {
50 id if id == std::any::TypeId::of::<Self>() => Some(self as *const _ as *const ()),
51 id if id == std::any::TypeId::of::<WithContext>() => {
52 Some(&self.with_context as *const _ as *const ())
53 }
54 _ => None,
55 }
56 }
57 }
58
59 let layer = WrappedLayer {
60 with_context: WithContext,
61 };
62 let filter = Targets::new().with_default(tracing::Level::INFO);
63 let registry = tracing_subscriber::registry().with(layer.with_filter(filter));
64 let dispatch = tracing::dispatcher::Dispatch::new(registry);
65
66 // Types from a custom implementation of `downcast_raw` are available
67 assert!(dispatch.downcast_ref::<WithContext>().is_some());
68}
69