|
264 | 264 | //! .init(); |
265 | 265 | //! ``` |
266 | 266 | //! |
267 | | -//! [prelude]: crate::prelude |
| 267 | +//! The [`Layer::boxed`] method is provided to make boxing a `Layer` |
| 268 | +//! more convenient, but [`Box::new`] may be used as well. |
| 269 | +//! |
268 | 270 | //! [option-impl]: Layer#impl-Layer<S>-for-Option<L> |
269 | 271 | //! [box-impl]: Layer#impl-Layer%3CS%3E-for-Box%3Cdyn%20Layer%3CS%3E%20+%20Send%20+%20Sync%3E |
270 | 272 | //! [prelude]: crate::prelude |
@@ -921,6 +923,131 @@ where |
921 | 923 | filter::Filtered::new(self, filter) |
922 | 924 | } |
923 | 925 |
|
| 926 | + /// Erases the type of this [`Layer`], returning a [`Box`]ed `dyn |
| 927 | + /// Layer` trait object. |
| 928 | + /// |
| 929 | + /// This can be used when a function returns a `Layer` which may be of |
| 930 | + /// one of several types, or when a `Layer` subscriber has a very long type |
| 931 | + /// signature. |
| 932 | + /// |
| 933 | + /// # Examples |
| 934 | + /// |
| 935 | + /// The following example will *not* compile, because the value assigned to |
| 936 | + /// `log_layer` may have one of several different types: |
| 937 | + /// |
| 938 | + /// ```compile_fail |
| 939 | + /// # fn main() -> Result<(), Box<dyn std::error::Error>> { |
| 940 | + /// use tracing_subscriber::{Layer, filter::LevelFilter, prelude::*}; |
| 941 | + /// use std::{path::PathBuf, fs::File, io}; |
| 942 | + /// |
| 943 | + /// /// Configures whether logs are emitted to a file, to stdout, or to stderr. |
| 944 | + /// pub enum LogConfig { |
| 945 | + /// File(PathBuf), |
| 946 | + /// Stdout, |
| 947 | + /// Stderr, |
| 948 | + /// } |
| 949 | + /// |
| 950 | + /// let config = // ... |
| 951 | + /// # LogConfig::Stdout; |
| 952 | + /// |
| 953 | + /// // Depending on the config, construct a layer of one of several types. |
| 954 | + /// let log_layer = match config { |
| 955 | + /// // If logging to a file, use a maximally-verbose configuration. |
| 956 | + /// LogConfig::File(path) => { |
| 957 | + /// let file = File::create(path)?; |
| 958 | + /// tracing_subscriber::fmt::layer() |
| 959 | + /// .with_thread_ids(true) |
| 960 | + /// .with_thread_names(true) |
| 961 | + /// // Selecting the JSON logging format changes the layer's |
| 962 | + /// // type. |
| 963 | + /// .json() |
| 964 | + /// .with_span_list(true) |
| 965 | + /// // Setting the writer to use our log file changes the |
| 966 | + /// // layer's type again. |
| 967 | + /// .with_writer(file) |
| 968 | + /// }, |
| 969 | + /// |
| 970 | + /// // If logging to stdout, use a pretty, human-readable configuration. |
| 971 | + /// LogConfig::Stdout => tracing_subscriber::fmt::layer() |
| 972 | + /// // Selecting the "pretty" logging format changes the |
| 973 | + /// // layer's type! |
| 974 | + /// .pretty() |
| 975 | + /// .with_writer(io::stdout) |
| 976 | + /// // Add a filter based on the RUST_LOG environment variable; |
| 977 | + /// // this changes the type too! |
| 978 | + /// .and_then(tracing_subscriber::EnvFilter::from_default_env()), |
| 979 | + /// |
| 980 | + /// // If logging to stdout, only log errors and warnings. |
| 981 | + /// LogConfig::Stderr => tracing_subscriber::fmt::layer() |
| 982 | + /// // Changing the writer changes the layer's type |
| 983 | + /// .with_writer(io::stderr) |
| 984 | + /// // Only log the `WARN` and `ERROR` levels. Adding a filter |
| 985 | + /// // changes the layer's type to `Filtered<LevelFilter, ...>`. |
| 986 | + /// .with_filter(LevelFilter::WARN), |
| 987 | + /// }; |
| 988 | + /// |
| 989 | + /// tracing_subscriber::registry() |
| 990 | + /// .with(log_layer) |
| 991 | + /// .init(); |
| 992 | + /// # Ok(()) } |
| 993 | + /// ``` |
| 994 | + /// |
| 995 | + /// However, adding a call to `.boxed()` after each match arm erases the |
| 996 | + /// layer's type, so this code *does* compile: |
| 997 | + /// |
| 998 | + /// ``` |
| 999 | + /// # fn main() -> Result<(), Box<dyn std::error::Error>> { |
| 1000 | + /// # use tracing_subscriber::{Layer, filter::LevelFilter, prelude::*}; |
| 1001 | + /// # use std::{path::PathBuf, fs::File, io}; |
| 1002 | + /// # pub enum LogConfig { |
| 1003 | + /// # File(PathBuf), |
| 1004 | + /// # Stdout, |
| 1005 | + /// # Stderr, |
| 1006 | + /// # } |
| 1007 | + /// # let config = LogConfig::Stdout; |
| 1008 | + /// let log_layer = match config { |
| 1009 | + /// LogConfig::File(path) => { |
| 1010 | + /// let file = File::create(path)?; |
| 1011 | + /// tracing_subscriber::fmt::layer() |
| 1012 | + /// .with_thread_ids(true) |
| 1013 | + /// .with_thread_names(true) |
| 1014 | + /// .json() |
| 1015 | + /// .with_span_list(true) |
| 1016 | + /// .with_writer(file) |
| 1017 | + /// // Erase the type by boxing the layer |
| 1018 | + /// .boxed() |
| 1019 | + /// }, |
| 1020 | + /// |
| 1021 | + /// LogConfig::Stdout => tracing_subscriber::fmt::layer() |
| 1022 | + /// .pretty() |
| 1023 | + /// .with_writer(io::stdout) |
| 1024 | + /// .and_then(tracing_subscriber::EnvFilter::from_default_env()) |
| 1025 | + /// // Erase the type by boxing the layer |
| 1026 | + /// .boxed(), |
| 1027 | + /// |
| 1028 | + /// LogConfig::Stderr => tracing_subscriber::fmt::layer() |
| 1029 | + /// .with_writer(io::stderr) |
| 1030 | + /// .with_filter(LevelFilter::WARN) |
| 1031 | + /// // Erase the type by boxing the layer |
| 1032 | + /// .boxed(), |
| 1033 | + /// }; |
| 1034 | + /// |
| 1035 | + /// tracing_subscriber::registry() |
| 1036 | + /// .with(log_layer) |
| 1037 | + /// .init(); |
| 1038 | + /// # Ok(()) } |
| 1039 | + /// ``` |
| 1040 | + #[cfg(any(feature = "alloc", feature = "std"))] |
| 1041 | + #[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))] |
| 1042 | + fn boxed(self) -> Box<dyn Layer<S> + Send + Sync + 'static> |
| 1043 | + where |
| 1044 | + Self: Sized, |
| 1045 | + Self: Layer<S> + Send + Sync + 'static, |
| 1046 | + S: Subscriber, |
| 1047 | + { |
| 1048 | + Box::new(self) |
| 1049 | + } |
| 1050 | + |
924 | 1051 | #[doc(hidden)] |
925 | 1052 | unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { |
926 | 1053 | if id == TypeId::of::<Self>() { |
|
0 commit comments