slog/
lib.rs

1//! # Slog -  Structured, extensible, composable logging for Rust
2//!
3//! `slog-rs` is an ecosystem of reusable components for structured, extensible,
4//! composable logging for Rust.
5//!
6//! `slog` is `slog-rs`'s main crate providing core components shared between
7//! all other parts of `slog-rs` ecosystem.
8//!
9//! This is auto-generated technical documentation of `slog`. For information
10//! about project organization, development, help, etc. please see
11//! [slog github page](https://github.com/slog-rs/slog)
12//!
13//! ## Core advantages over `log` crate
14//!
15//! * **extensible** - `slog` crate provides core functionality: a very basic
16//!   and portable standard feature-set based on open `trait`s. This allows
17//!   implementing new features that can be independently published.
18//! * **composable** - `trait`s that `slog` exposes to provide extensibility
19//!   are designed to be easy to efficiently reuse and combine. By combining
20//!   different functionalities, each application can specify precisely when,
21//!   where, and how to process logging data from an application and its
22//!   dependencies.
23//! * **flexible** - `slog` does not constrain logging to just one globally
24//!   registered backend. Parts of your application can handle logging
25//!   in a customized way, or completely independently.
26//! * **structured** and both **human and machine readable** - By using the
27//!   key-value data format and retaining its type information, the meaning of logging
28//!   data is preserved.  Data can be serialized to machine readable formats like
29//!   JSON and sent to data-mining systems for further analysis, etc. On the
30//!   other hand, when presenting on screen, logging information can be presented
31//!   in aesthetically pleasing and easy to understand ways.
32//! * **contextual** - `slog`'s `Logger` objects carry set of key-value data
33//!   pairs that contain the context of logging - information that otherwise
34//!   would have to be repeated in every logging statement.
35//!
36//! ## `slog` features
37//!
38//! * performance oriented; read [what makes slog
39//!   fast](https://github.com/slog-rs/slog/wiki/What-makes-slog-fast) and see:
40//!   [slog bench log](https://github.com/dpc/slog-rs/wiki/Bench-log)
41//!   * lazily evaluation through closure values
42//!   * async IO support included: see [`slog-async`
43//!     crate](https://docs.rs/slog-async)
44//! * `#![no_std]` support (with opt-out `std` cargo feature flag)
45//! * support for named format arguments (e.g. `info!(logger, "printed {line_count} lines", line_count = 2);`)
46//!   for easy bridging between the human readable and machine-readable outputs
47//! * tree-structured loggers
48//! * modular, lightweight and very extensible
49//!   * tiny core crate that does not pull any dependencies
50//!   * feature-crates for specific functionality
51//!   * using `slog` in library does not force users of the library to use slog
52//!     (but provides additional functionality); see [example how to use
53//!     `slog` in library](https://github.com/slog-rs/example-lib)
54//! * backwards and forwards compatibility with `log` crate:
55//!   see [`slog-stdlog` crate](https://docs.rs/slog-stdlog)
56//! * convenience crates:
57//!   * logging-scopes for implicit `Logger` passing: see
58//!     [slog-scope crate](https://docs.rs/slog-scope)
59//! * many existing core & community provided features:
60//!   * multiple outputs
61//!   * filtering control
62//!       * compile-time log level filter using cargo features (same as in `log`
63//!         crate)
64//!       * by level, msg, and any other meta-data
65//!       * [`slog-envlogger`](https://github.com/slog-rs/envlogger) - port of
66//!         `env_logger`
67//!       * terminal output, with color support: see [`slog-term`
68//!         crate](https://docs.rs/slog-term)
69//!  * [json](https://docs.rs/slog-json)
70//!      * [bunyan](https://docs.rs/slog-bunyan)
71//!  * [syslog](https://docs.rs/slog-syslog)
72//!    and [journald](https://docs.rs/slog-journald) support
73//!  * run-time configuration:
74//!      * run-time behavior change;
75//!        see [slog-atomic](https://docs.rs/slog-atomic)
76//!      * run-time configuration; see
77//!        [slog-config crate](https://docs.rs/slog-config)
78//!
79//!
80//! [env_logger]: https://crates.io/crates/env_logger
81//!
82//! ## Notable details
83//!
84//! **Note:** At compile time `slog` by default removes trace and debug level
85//! statements in release builds, and trace level records in debug builds. This
86//! makes `trace` and `debug` level logging records practically free, which
87//! should encourage using them freely. If you want to enable trace/debug
88//! messages or raise the compile time logging level limit, use the following in
89//! your `Cargo.toml`:
90//!
91//! ```norust
92//! slog = { version = ... ,
93//!          features = ["max_level_trace", "release_max_level_warn"] }
94//! ```
95//!
96//! Root drain (passed to `Logger::root`) must be one that does not ever return
97//! errors. This forces user to pick error handing strategy.
98//! `Drain::fuse()` or `Drain::ignore_res()`.
99//!
100//! [env_logger]: https://crates.io/crates/env_logger
101//! [fn-overv]: https://github.com/dpc/slog-rs/wiki/Functional-overview
102//! [atomic-switch]: https://docs.rs/slog-atomic/
103//!
104//! ## Where to start
105//!
106//! [`Drain`](trait.Drain.html), [`Logger`](struct.Logger.html) and
107//! [`log` macro](macro.log.html) are the most important elements of
108//! slog. Make sure to read their respective documentation
109//!
110//! Typically the biggest problem is creating a `Drain`
111//!
112//!
113//! ### Logging to the terminal
114//!
115//! ```ignore
116//! use slog::{o, Drain};
117//!
118//! fn main() {
119//!     let decorator = slog_term::TermDecorator::new().build();
120//!     let drain = slog_term::FullFormat::new(decorator).build().fuse();
121//!     let drain = slog_async::Async::new(drain).build().fuse();
122//!
123//!     let _log = slog::Logger::root(drain, o!());
124//! }
125//! ```
126//!
127//! ### Logging to a file
128//!
129//! ```ignore
130//! use std::fs::OpenOptions;
131//! use slog::{o, Drain};
132//!
133//! fn main() {
134//!    let log_path = "target/your_log_file_path.log";
135//!    let file = OpenOptions::new()
136//!       .create(true)
137//!       .write(true)
138//!       .truncate(true)
139//!       .open(log_path)
140//!       .unwrap();
141//!
142//!     let decorator = slog_term::PlainDecorator::new(file);
143//!     let drain = slog_term::FullFormat::new(decorator).build().fuse();
144//!     let drain = slog_async::Async::new(drain).build().fuse();
145//!
146//!     let _log = slog::Logger::root(drain, o!());
147//! }
148//! ```
149//!
150//! You can consider using `slog-json` instead of `slog-term`.
151//! `slog-term` only coincidently fits the role of a file output format. A
152//! proper `slog-file` crate with suitable format, log file rotation and other
153//! file-logging related features would be awesome. Contributions are welcome!
154//!
155//! ### Change logging level at runtime
156//!
157//! ```ignore
158//! use slog::{o, Drain};
159//!
160//! use std::sync::{Arc, atomic};
161//! use std::sync::atomic::Ordering;
162//! use std::result;
163//!
164//! /// Custom Drain logic
165//! struct RuntimeLevelFilter<D>{
166//!    drain: D,
167//!    on: Arc<atomic::AtomicBool>,
168//! }
169//!
170//! impl<D> Drain for RuntimeLevelFilter<D>
171//!     where D : Drain {
172//!     type Ok = Option<D::Ok>;
173//!     type Err = Option<D::Err>;
174//!
175//!     fn log(&self,
176//!           record: &slog::Record,
177//!           values: &slog::OwnedKVList)
178//!           -> result::Result<Self::Ok, Self::Err> {
179//!           let current_level = if self.on.load(Ordering::Relaxed) {
180//!               slog::Level::Trace
181//!           } else {
182//!               slog::Level::Info
183//!           };
184//!
185//!           if record.level().is_at_least(current_level) {
186//!               self.drain.log(
187//!                   record,
188//!                   values
189//!               )
190//!               .map(Some)
191//!               .map_err(Some)
192//!           } else {
193//!               Ok(None)
194//!           }
195//!       }
196//!   }
197//!
198//! fn main() {
199//!     // atomic variable controlling logging level
200//!     let on = Arc::new(atomic::AtomicBool::new(false));
201//!
202//!     let decorator = slog_term::TermDecorator::new().build();
203//!     let drain = slog_term::FullFormat::new(decorator).build();
204//!     let drain = RuntimeLevelFilter {
205//!         drain: drain,
206//!         on: on.clone(),
207//!     }.fuse();
208//!     let drain = slog_async::Async::new(drain).build().fuse();
209//!
210//!     let _log = slog::Logger::root(drain, o!());
211//!
212//!     // switch level in your code
213//!     on.store(true, Ordering::Relaxed);
214//! }
215//! ```
216//!
217//! Why is this not an existing crate? Because there are multiple ways to
218//! achieve the same result, and each application might come with its own
219//! variation. Supporting a more general solution is a maintenance effort.
220//! There is also nothing stopping anyone from publishing their own crate
221//! implementing it.
222//!
223//! Alternative to the above approach is `slog-atomic` crate. It implements
224//! swapping whole parts of `Drain` logging hierarchy.
225//!
226//! ## Examples & help
227//!
228//! Basic examples that are kept up-to-date are typically stored in
229//! respective git repository, under `examples/` subdirectory. Eg.
230//! [slog-term examples](https://github.com/slog-rs/term/tree/master/examples).
231//!
232//! [slog-rs wiki pages](https://github.com/slog-rs/slog/wiki) contain
233//! some pages about `slog-rs` technical details.
234//!
235//! Source code of other [software using
236//! slog-rs](https://crates.io/crates/slog/reverse_dependencies) can
237//! be an useful reference.
238//!
239//! Visit [slog-rs gitter channel](https://gitter.im/slog-rs/slog) for immediate
240//! help.
241//!
242//! ## Migrating from slog v1 to slog v2
243//!
244//! ### Key-value pairs come now after format string
245//!
246//! ```
247//! use slog::{info, o};
248//!
249//! let drain = slog::Discard;
250//! let root = slog::Logger::root(drain, o!());
251//! info!(root, "formatted: {}", 1; "log-key" => true);
252//! ```
253//!
254//! See more information about format at [`log`](macro.log.html).
255//!
256//! ### `slog-streamer` is gone
257//!
258//! Create simple terminal logger like this:
259//!
260//! ```ignore
261//! use slog::{o, Drain};
262//!
263//! fn main() {
264//!     let decorator = slog_term::TermDecorator::new().build();
265//!     let drain = slog_term::FullFormat::new(decorator).build().fuse();
266//!     let drain = slog_async::Async::new(drain).build().fuse();
267//!
268//!     let _log = slog::Logger::root(drain, o!());
269//! }
270//! ```
271//!
272//!
273//! ### Logging macros now takes ownership of values.
274//!
275//! Pass them by reference: `&x`.
276//!
277// }}}
278
279// {{{ Imports & meta
280#![warn(missing_docs)]
281#![warn(
282    rust_2018_compatibility,
283    rust_2018_idioms,
284    rust_2021_compatibility,
285    future_incompatible
286)]
287#![warn(
288    // Use `core` and `alloc` instead of `std` wherever possible
289    clippy::alloc_instead_of_core,
290    clippy::std_instead_of_core,
291    clippy::std_instead_of_alloc,
292)]
293#![allow(
294    // Thiw lint was triggered by bumping the MSRV to 1.61
295    // TODO: Apply suggestions rather than suppressing
296    clippy::uninlined_format_args,
297)]
298#![cfg_attr(not(feature = "std"), no_std)]
299
300extern crate alloc;
301
302// Allows referencing `slog` in docs
303#[cfg(doc)]
304extern crate self as slog;
305
306mod key;
307pub use self::key::Key;
308
309use alloc::borrow::{Cow, ToOwned};
310use alloc::boxed::Box;
311use alloc::rc::Rc;
312use alloc::string::String;
313use alloc::{sync::Arc, vec::Vec};
314
315use core::str::FromStr;
316use core::{convert, fmt, result};
317
318#[cfg(all(not(feature = "std"), has_std_error))]
319// re-export as StdError is intended usage
320use core::error::Error as StdError;
321#[cfg(feature = "std")]
322use std::error::Error as StdError;
323
324pub mod prelude;
325
326// }}}
327
328// {{{ Macros
329/// Macro for building group of key-value pairs:
330/// [`OwnedKV`](struct.OwnedKV.html)
331///
332/// ```
333/// let drain = slog::Discard;
334/// let _root = slog::Logger::root(
335///     drain,
336///     slog::o!("key1" => "value1", "key2" => "value2")
337/// );
338/// ```
339#[macro_export(local_inner_macros)]
340macro_rules! o(
341    ($($args:tt)*) => {
342        $crate::OwnedKV(kv!($($args)*))
343    };
344);
345
346/// Macro for building group of key-value pairs (alias)
347///
348/// Use in case of macro name collisions
349#[macro_export(local_inner_macros)]
350#[deprecated(
351    since = "2.8.0",
352    note = "Use fully qualified macro slog::o!(...) instead"
353)]
354macro_rules! slog_o(
355    ($($args:tt)*) => ($crate::o!($($args)*));
356);
357
358/// Macro for building group of key-value pairs in
359/// [`BorrowedKV`](struct.BorrowedKV.html)
360///
361/// In most circumstances using this macro directly is unnecessary and `info!`
362/// and other wrappers over `log!` should be used instead.
363#[macro_export(local_inner_macros)]
364macro_rules! b(
365    ($($args:tt)*) => {
366        $crate::BorrowedKV(&kv!($($args)*))
367    };
368);
369
370/// Alias of `b`
371#[macro_export]
372#[deprecated(
373    since = "2.8.0",
374    note = "Use fully qualified macro slog::b!(...) instead"
375)]
376macro_rules! slog_b(
377    ($($args:tt)*) => ($crate::b!($($args)*));
378);
379
380/// Macro for build `KV` implementing type
381///
382/// You probably want to use `o!` or `b!` instead.
383// Note: make sure to keep in sync with `slog_kv`
384#[macro_export(local_inner_macros)]
385macro_rules! kv(
386    (@ $args_ready:expr; $k:expr => %$v:expr) => {
387        kv!(@ ($crate::SingleKV::from(($k, $crate::__builtin!(@format_args "{}", $v))), $args_ready); )
388    };
389    (@ $args_ready:expr; $k:expr => %$v:expr, $($args:tt)* ) => {
390        kv!(@ ($crate::SingleKV::from(($k, $crate::__builtin!(@format_args "{}", $v))), $args_ready); $($args)* )
391    };
392    (@ $args_ready:expr; $k:expr => #%$v:expr) => {
393        kv!(@ ($crate::SingleKV::from(($k, $crate::__builtin!(@format_args "{:#}", $v))), $args_ready); )
394    };
395    (@ $args_ready:expr; $k:expr => #%$v:expr, $($args:tt)* ) => {
396        kv!(@ ($crate::SingleKV::from(($k, $crate::__builtin!(@format_args "{:#}", $v))), $args_ready); $($args)* )
397    };
398    (@ $args_ready:expr; $k:expr => ?$v:expr) => {
399        kv!(@ ($crate::SingleKV::from(($k, $crate::__builtin!(@format_args "{:?}", $v))), $args_ready); )
400    };
401    (@ $args_ready:expr; $k:expr => ?$v:expr, $($args:tt)* ) => {
402        kv!(@ ($crate::SingleKV::from(($k, $crate::__builtin!(@format_args "{:?}", $v))), $args_ready); $($args)* )
403    };
404    (@ $args_ready:expr; $k:expr => #?$v:expr) => {
405        kv!(@ ($crate::SingleKV::from(($k, $crate::__builtin!(@format_args "{:#?}", $v))), $args_ready); )
406    };
407    (@ $args_ready:expr; $k:expr => #?$v:expr, $($args:tt)* ) => {
408        kv!(@ ($crate::SingleKV::from(($k, $crate::__builtin!(@format_args "{:#?}", $v))), $args_ready); $($args)* )
409    };
410    (@ $args_ready:expr; $k:expr => #$v:expr) => {
411        kv!(@ ($crate::SingleKV::from(($k, $crate::__builtin!(@wrap_error $v) )), $args_ready); )
412    };
413    (@ $args_ready:expr; $k:expr => #$v:expr, $($args:tt)* ) => {
414        kv!(@ ($crate::SingleKV::from(($k, $crate::__builtin!(@wrap_error $v))), $args_ready); $($args)* )
415    };
416    (@ $args_ready:expr; $k:expr => $v:expr) => {
417        kv!(@ ($crate::SingleKV::from(($k, $v)), $args_ready); )
418    };
419    (@ $args_ready:expr; $k:expr => $v:expr, $($args:tt)* ) => {
420        kv!(@ ($crate::SingleKV::from(($k, $v)), $args_ready); $($args)* )
421    };
422    (@ $args_ready:expr; $kv:expr) => {
423        kv!(@ ($kv, $args_ready); )
424    };
425    (@ $args_ready:expr; $kv:expr, $($args:tt)* ) => {
426        kv!(@ ($kv, $args_ready); $($args)* )
427    };
428    (@ $args_ready:expr; ) => {
429        $args_ready
430    };
431    (@ $args_ready:expr;, ) => {
432        $args_ready
433    };
434    ($($args:tt)*) => {
435        kv!(@ (); $($args)*)
436    };
437);
438
439/// Alias of `kv`
440// Note: make sure to keep in sync with `kv`
441#[macro_export]
442#[deprecated(
443    since = "2.8.0",
444    note = "Use fully qualified macro slog::kv!(...) instead"
445)]
446macro_rules! slog_kv(
447    ($($args:tt)*) => ($crate::kv!(@ (); $($args)*));
448);
449
450#[macro_export(local_inner_macros)]
451/// Create `RecordStatic` at the given code location
452macro_rules! record_static(
453    ($lvl:expr, $tag:expr,) => { record_static!($lvl, $tag) };
454    ($lvl:expr, $tag:expr) => {{
455        static LOC : $crate::RecordLocation = $crate::RecordLocation {
456            file: $crate::__builtin!(@file),
457            line: $crate::__builtin!(@line),
458            column: $crate::__builtin!(@column),
459            function: "",
460            module: $crate::__builtin!(@module_path),
461        };
462        $crate::RecordStatic {
463            location : &LOC,
464            level: $lvl,
465            tag : $tag,
466        }
467    }};
468);
469
470/// Create `RecordStatic` at the given code location (alias)
471#[macro_export]
472#[deprecated(
473    since = "2.8.0",
474    note = "Use fully qualified macro slog::record_static!(...) instead"
475)]
476macro_rules! slog_record_static(
477    ($($arg:tt)*) => ($crate::record_static!($($arg)*));
478);
479
480#[macro_export(local_inner_macros)]
481/// Create `Record` at the given code location
482///
483/// Note that this requires that `lvl` and `tag` are compile-time constants. If
484/// you need them to *not* be compile-time, such as when recreating a `Record`
485/// from a serialized version, use `Record::new` instead.
486macro_rules! record(
487    ($lvl:expr, $tag:expr, $args:expr, $b:expr,) => {
488        record!($lvl, $tag, $args, $b)
489    };
490    ($lvl:expr, $tag:expr, $args:expr, $b:expr) => {{
491        #[allow(dead_code)]
492        static RS : $crate::RecordStatic<'static> = record_static!($lvl, $tag);
493        $crate::Record::new(&RS, $args, $b)
494    }};
495);
496
497#[macro_export]
498#[deprecated(
499    since = "2.8.0",
500    note = "Use fully qualified macro slog::record!(...) instead"
501)]
502/// Create `Record` at the given code location (alias)
503macro_rules! slog_record(
504    ($($arg:tt)*) => ($crate::record_static!($($arg)*));
505);
506
507/// Log message a logging record
508///
509/// Use wrappers `error!`, `warn!` etc. instead
510///
511/// The `max_level_*` and `release_max_level*` cargo features can be used to
512/// statically disable logging at various levels. See [slog notable
513/// details](index.html#notable-details)
514///
515/// Use [version with longer name](macro.slog_log.html) if you want to prevent
516/// clash with legacy `log` crate macro names.
517///
518/// ## Supported invocations
519///
520/// ### Simple
521///
522/// ```
523/// let drain = slog::Discard;
524/// let root = slog::Logger::root(
525///     drain,
526///     slog::o!("key1" => "value1", "key2" => "value2"),
527/// );
528/// slog::info!(root, "test info log"; "log-key" => true);
529/// ```
530///
531/// Note that `"key" => value` part is optional:
532///
533/// ```
534/// let drain = slog::Discard;
535/// let root = slog::Logger::root(
536///     drain,
537///     slog::o!("key1" => "value1", "key2" => "value2"),
538/// );
539/// slog::info!(root, "test info log");
540/// ```
541///
542/// ### Formatting support:
543///
544/// ```
545/// let drain = slog::Discard;
546/// let root = slog::Logger::root(drain,
547///     slog::o!("key1" => "value1", "key2" => "value2")
548/// );
549/// slog::info!(root, "formatted {num_entries} entries of {}", "something", num_entries = 2; "log-key" => true);
550/// ```
551///
552/// Note:
553///
554/// * `;` is used to separate message arguments and key value pairs.
555/// * message behaves like `format!`/`format_args!`
556/// * Named arguments to messages will be added to key-value pairs as well!
557///
558/// `"key" => value` part is optional:
559///
560/// ```
561/// let drain = slog::Discard;
562/// let root = slog::Logger::root(
563///     drain,
564///     slog::o!("key1" => "value1", "key2" => "value2"),
565/// );
566/// slog::info!(root, "formatted: {}", 1);
567/// ```
568///
569/// Use formatting support wisely. Prefer named arguments, so the associated
570/// data is not "lost" by becoming an untyped string in the message.
571///
572/// ### Tags
573///
574/// All above versions can be supplemented with a tag - string literal prefixed
575/// with `#`.
576///
577/// ```
578/// let drain = slog::Discard;
579/// let root = slog::Logger::root(drain,
580///     slog::o!("key1" => "value1", "key2" => "value2")
581/// );
582/// let ops = 3;
583/// slog::info!(
584///     root,
585///     #"performance-metric", "thread speed"; "ops_per_sec" => ops
586/// );
587/// ```
588///
589/// See `Record::tag()` for more information about tags.
590///
591/// ### Own implementations of `KV` and `Value`
592///
593/// List of key value pairs is a comma separated list of key-values. Typically,
594/// a designed syntax is used in form of `k => v` where `k` can be any type
595/// that implements `Value` type.
596///
597/// It's possible to directly specify type that implements `KV` trait without
598/// `=>` syntax.
599///
600/// ```
601/// use slog::{KV, Value, Record, Serializer, Key, o, info};
602/// struct MyKV;
603/// struct MyV;
604///
605/// impl KV for MyKV {
606///     fn serialize(&self, _record: &Record, serializer: &mut dyn Serializer) -> slog::Result {
607///         serializer.emit_u32("MyK".into(), 16)
608///     }
609/// }
610///
611/// impl Value for MyV {
612///     fn serialize(&self, _record: &Record, key: Key, serializer: &mut dyn Serializer) -> slog::Result {
613///         serializer.emit_u32("MyKV".into(), 16)
614///     }
615/// }
616///
617/// let drain = slog::Discard;
618///
619/// let root = slog::Logger::root(drain, o!(MyKV));
620///
621/// info!(
622///     root,
623///     "testing MyV"; "MyV" => MyV
624/// );
625/// ```
626///
627/// ### `fmt::Display` and `fmt::Debug` values
628///
629/// Slog macros support couple of formatting modifiers for convenience.
630///
631/// Value of any type that implements `std::fmt::Display` can be prefixed with
632/// `%` in `k => v` expression to use its text representation returned by
633/// `format_args!("{}", v)`. This is especially useful for errors. Not that
634/// this does not allocate any `String` since it operates on `fmt::Arguments`.
635/// You can also use the `#%` prefix to use the "alternate" form of formatting,
636/// represented by the `{:#}` formatting specifier.
637///
638/// Similarly to use `std::fmt::Debug` value can be prefixed with `?`,
639/// or pretty-printed with `#?`.
640///
641/// Errors can be prefixed with `#` as a shorthand. Error values will be wrapped
642/// with [`ErrorValue`]. Error references will be wrapped in [`ErrorRef`].
643///
644/// Full list of supported formats can always be inspected by looking at
645/// [`kv` macro](macro.log.html)
646///
647/// ```
648/// # use std::fmt::Write;
649/// let drain = slog::Discard;
650/// let log  = slog::Logger::root(drain, slog::o!());
651///
652/// let mut output = String::new();
653///
654/// if let Err(e) = write!(&mut output, "write to string") {
655///     slog::error!(log, "write failed"; "err" => %e);
656/// }
657/// ```
658#[macro_export(local_inner_macros)]
659macro_rules! log(
660    // `2` means that `;` was already found
661   (2 @ { $($fmt:tt)* }, { $($kv:tt)* },  $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr) => {
662      $crate::Logger::log(&$l, &record!($lvl, $tag, &$crate::__builtin!(@format_args $msg_fmt, $($fmt)*), b!($($kv)*)))
663   };
664   (2 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr,) => {
665       log!(2 @ { $($fmt)* }, { $($kv)* }, $l, $lvl, $tag, $msg_fmt)
666   };
667   (2 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr;) => {
668       log!(2 @ { $($fmt)* }, { $($kv)* }, $l, $lvl, $tag, $msg_fmt)
669   };
670   (2 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr, $($args:tt)*) => {
671       log!(2 @ { $($fmt)* }, { $($kv)* $($args)*}, $l, $lvl, $tag, $msg_fmt)
672   };
673    // `1` means that we are still looking for `;`
674    // -- handle named arguments to format string
675   (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr, $k:ident = $v:expr) => {
676       log!(2 @ { $($fmt)* $k = $v }, { $($kv)* $crate::__builtin!(@stringify $k) => $v, }, $l, $lvl, $tag, $msg_fmt)
677   };
678   (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr, $k:ident = $v:expr;) => {
679       log!(2 @ { $($fmt)* $k = $v }, { $($kv)* $crate::__builtin!(@stringify $k) => $v, }, $l, $lvl, $tag, $msg_fmt)
680   };
681   (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr, $k:ident = $v:expr,) => {
682       log!(2 @ { $($fmt)* $k = $v }, { $($kv)* $crate::__builtin!(@stringify $k) => $v, }, $l, $lvl, $tag, $msg_fmt)
683   };
684   (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr, $k:ident = $v:expr; $($args:tt)*) => {
685       log!(2 @ { $($fmt)* $k = $v }, { $($kv)* $crate::__builtin!(@stringify $k) => $v, }, $l, $lvl, $tag, $msg_fmt, $($args)*)
686   };
687   (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr, $k:ident = $v:expr, $($args:tt)*) => {
688       log!(1 @ { $($fmt)* $k = $v, }, { $($kv)* $crate::__builtin!(@stringify $k) => $v, }, $l, $lvl, $tag, $msg_fmt, $($args)*)
689   };
690    // -- look for `;` termination
691   (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr,) => {
692       log!(2 @ { $($fmt)* }, { $($kv)* }, $l, $lvl, $tag, $msg_fmt)
693   };
694   (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr) => {
695       log!(2 @ { $($fmt)* }, { $($kv)* }, $l, $lvl, $tag, $msg_fmt)
696   };
697   (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr, ; $($args:tt)*) => {
698       log!(1 @ { $($fmt)* }, { $($kv)* }, $l, $lvl, $tag, $msg_fmt; $($args)*)
699   };
700   (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr; $($args:tt)*) => {
701       log!(2 @ { $($fmt)* }, { $($kv)* }, $l, $lvl, $tag, $msg_fmt, $($args)*)
702   };
703    // -- must be normal argument to format string
704   (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr, $f:tt $($args:tt)*) => {
705       log!(1 @ { $($fmt)* $f }, { $($kv)* }, $l, $lvl, $tag, $msg_fmt, $($args)*)
706   };
707   ($l:expr, $lvl:expr, $tag:expr, $($args:tt)*) => {
708       if $lvl.as_usize() <= $crate::__slog_static_max_level().as_usize() {
709           log!(1 @ { }, { }, $l, $lvl, $tag, $($args)*)
710       }
711   };
712);
713
714/// Log message a logging record (alias)
715///
716/// Before Rust 2018, this alternate name was necessary in case of conflicts with the `log` crate.
717/// Now it is possible to simply use the prefixed path `slog::log!`.
718///
719/// See [`log`](macro.log.html) for documentation.
720///
721/// ```
722/// extern crate slog;
723///
724/// fn main() {
725///     let log = slog::Logger::root(slog::Discard, slog::o!());
726///
727///     slog::info!(log, "some interesting info"; "where" => "right here");
728/// }
729/// ```
730#[macro_export]
731#[deprecated(
732    since = "2.8.0",
733    note = "Use fully qualified macro slog::log!(...) instead"
734)]
735macro_rules! slog_log(
736    ($($args:tt)*) => ($crate::log!($($args)*));
737);
738
739/// Log critical level record
740///
741/// See `log` for documentation.
742#[macro_export]
743macro_rules! crit(
744    ($l:expr, #$tag:expr, $($args:tt)+) => {
745        $crate::log!($l, $crate::Level::Critical, $tag, $($args)+)
746    };
747    ($l:expr, $($args:tt)+) => {
748        $crate::log!($l, $crate::Level::Critical, "", $($args)+)
749    };
750);
751
752/// Log critical level record (alias)
753///
754/// Before Rust 2018, this alternate name was necessary in case of conflicts with the `log` crate.
755/// Now it is possible to simply use the prefixed path `slog::crit!`.
756///
757/// See `slog_log` for documentation.
758#[macro_export(local_inner_macros)]
759#[deprecated(
760    since = "2.8.0",
761    note = "Use fully qualified macro slog::crit!(...) instead"
762)]
763macro_rules! slog_crit(
764    ($($args:tt)*) => ($crate::crit!($($args)*));
765);
766
767/// Log error level record
768///
769/// See `log` for documentation.
770#[macro_export(local_inner_macros)]
771macro_rules! error(
772    ($l:expr, #$tag:expr, $($args:tt)+) => {
773        log!($l, $crate::Level::Error, $tag, $($args)+)
774    };
775    ($l:expr, $($args:tt)+) => {
776        log!($l, $crate::Level::Error, "", $($args)+)
777    };
778);
779
780/// Log error level record
781///
782/// Before Rust 2018, this alternate name was necessary in case of conflicts with the `log` crate.
783///
784/// See `slog_log` for documentation.
785#[macro_export]
786#[deprecated(
787    since = "2.8.0",
788    note = "Use fully qualified macro slog::crit!(...) instead"
789)]
790macro_rules! slog_error(
791    ($($args:tt)*) => ($crate::error!($($args)*));
792);
793
794/// Log warning level record
795///
796/// See `log` for documentation.
797#[macro_export]
798macro_rules! warn(
799    ($l:expr, #$tag:expr, $($args:tt)+) => {
800        $crate::log!($l, $crate::Level::Warning, $tag, $($args)+)
801    };
802    ($l:expr, $($args:tt)+) => {
803        $crate::log!($l, $crate::Level::Warning, "", $($args)+)
804    };
805);
806
807/// Log warning level record (alias)
808///
809/// Before Rust 2018, this alternate name was necessary in case of conflicts with the `log` crate.
810///
811/// See `slog_log` for documentation.
812#[macro_export]
813#[deprecated(
814    since = "2.8.0",
815    note = "Use fully qualified macro slog::warn!(...) instead"
816)]
817macro_rules! slog_warn(
818    ($($args:tt)*) => ($crate::warn!($($args)*));
819);
820
821/// Log info level record
822///
823/// See `slog_log` for documentation.
824#[macro_export]
825macro_rules! info(
826    ($l:expr, #$tag:expr, $($args:tt)*) => {
827        $crate::log!($l, $crate::Level::Info, $tag, $($args)*)
828    };
829    ($l:expr, $($args:tt)*) => {
830        $crate::log!($l, $crate::Level::Info, "", $($args)*)
831    };
832);
833
834/// Log info level record (alias)
835///
836/// Before Rust 2018, this alternate name was necessary in case of conflicts with the `log` crate.
837///
838/// See `slog_log` for documentation.
839#[macro_export]
840#[deprecated(
841    since = "2.8.0",
842    note = "Use fully qualified macro slog::info!(...) instead"
843)]
844macro_rules! slog_info(
845    ($($args:tt)*) => ($crate::info!($($args)*));
846);
847
848/// Log debug level record
849///
850/// See `log` for documentation.
851#[macro_export]
852macro_rules! debug(
853    ($l:expr, #$tag:expr, $($args:tt)+) => {
854        $crate::log!($l, $crate::Level::Debug, $tag, $($args)+)
855    };
856    ($l:expr, $($args:tt)+) => {
857        $crate::log!($l, $crate::Level::Debug, "", $($args)+)
858    };
859);
860
861/// Log debug level record (alias)
862///
863/// Before Rust 2018, this alternate name was necessary in case of conflicts with the `log` crate.
864///
865/// See `slog_log` for documentation.
866#[macro_export]
867#[deprecated(
868    since = "2.8.0",
869    note = "Use fully qualified macro slog::warn!(...) instead"
870)]
871macro_rules! slog_debug(
872    ($($args:tt)*) => ($crate::debug!($($args)*));
873);
874
875/// Log trace level record
876///
877/// See `log` for documentation.
878#[macro_export]
879macro_rules! trace(
880    ($l:expr, #$tag:expr, $($args:tt)+) => {
881        $crate::log!($l, $crate::Level::Trace, $tag, $($args)+)
882    };
883    ($l:expr, $($args:tt)+) => {
884        $crate::log!($l, $crate::Level::Trace, "", $($args)+)
885    };
886);
887
888/// Log trace level record (alias)
889///
890/// Before Rust 2018, this alternate name was necessary in case of conflicts with the `log` crate.
891///
892/// See `slog_log` for documentation.
893#[macro_export]
894#[deprecated(
895    since = "2.8.0",
896    note = "Use fully qualified macro slog::trace!(...) instead"
897)]
898macro_rules! slog_trace(
899    ($($args:tt)*) => ($crate::trace!($($args)*));
900);
901
902/// Helper macro for using the built-in macros inside of
903/// exposed macros with `local_inner_macros` attribute.
904#[doc(hidden)]
905#[macro_export] // TODO: Always use explicit paths
906macro_rules! __builtin {
907    (@format_args $($t:tt)*) => ( format_args!($($t)*) );
908    (@stringify $($t:tt)*) => ( stringify!($($t)*) );
909    (@file) => ( file!() );
910    (@line) => ( line!() );
911    (@column) => ( column!() );
912    (@module_path) => ( module_path!() );
913    (@wrap_error $v:expr) => ({
914        // this magical sequence of code is used to wrap either with
915        // slog::ErrorValue or slog::ErrorRef as appropriate
916        // See PR #328 for details
917        #[allow(unused_imports)]
918        use $crate::{ErrorRefKind, ErrorValueKind};
919        let v = $v;
920        let w = $crate::ErrorTagWrapper(v);
921        (&&w).slog_error_kind().wrap(w.0)
922    });
923}
924
925// }}}
926
927// {{{ Logger
928/// Logging handle used to execute logging statements
929///
930/// In an essence `Logger` instance holds two pieces of information:
931///
932/// * drain - destination where to forward logging `Record`s for
933///   processing.
934/// * context - list of key-value pairs associated with it.
935///
936/// The root `Logger` is created with a `Drain` that will be cloned to every
937/// member of its hierarchy.
938///
939/// Child `Logger`s are built from existing ones, and inherit their key-value
940/// pairs, which can be supplemented with additional pairs.
941///
942/// Cloning existing loggers and creating new ones is cheap. Loggers can be
943/// freely passed around the code and between threads.
944///
945/// `Logger`s are `Sync+Send` - there's no need to synchronize accesses to them,
946/// as they can accept logging records from multiple threads at once. They can
947/// be sent to any thread. Because of that they require the `Drain` to be
948/// `Sync+Send` as well. Not all `Drain`s are `Sync` or `Send` but they can
949/// often be made so by wrapping in a `Mutex` and/or `Arc`.
950///
951/// `Logger` implements `Drain` trait. Any logging `Record` delivered to
952/// a `Logger` functioning as a `Drain` will be delivered to its `Drain`
953/// with existing key-value pairs appended to the `Logger`'s key-value pairs.
954/// By itself, it is effectively very similar to `Logger` being an ancestor
955/// of `Logger` that originated the logging `Record`. Combined with other
956/// `Drain`s, this allows custom processing logic for a sub-tree of a whole logging
957/// tree.
958///
959/// Logger is parametrized over type of a `Drain` associated with it (`D`). It
960/// default to type-erased version so `Logger` without any type annotation
961/// means `Logger<Arc<SendSyncRefUnwindSafeDrain<Ok = (), Err = Never>>>`. See
962/// `Logger::root_typed` and `Logger::to_erased` for more information.
963#[derive(Clone)]
964#[must_use = "does nothing unless used"]
965pub struct Logger<D = Arc<dyn SendSyncRefUnwindSafeDrain<Ok = (), Err = Never>>>
966where
967    D: SendSyncUnwindSafeDrain<Ok = (), Err = Never>,
968{
969    drain: D,
970    list: OwnedKVList,
971}
972
973impl<D> Logger<D>
974where
975    D: SendSyncUnwindSafeDrain<Ok = (), Err = Never>,
976{
977    /// Build a root `Logger`
978    ///
979    /// Root logger starts a new tree associated with a given `Drain`. Root
980    /// logger drain must return no errors. See `Drain::ignore_res()` and
981    /// `Drain::fuse()`.
982    ///
983    /// All children and their children (and so on), form one logging tree
984    /// sharing a common drain. See `Logger::new`.
985    ///
986    /// This version (as opposed to `Logger:root_typed`) will take `drain` and
987    /// made it into `Arc<SendSyncRefUnwindSafeDrain<Ok = (), Err = Never>>`.
988    /// This is typically the most convenient way to work with `Logger`s.
989    ///
990    /// Use `o!` macro to build `OwnedKV` object.
991    ///
992    /// ```
993    /// let _root = slog::Logger::root(
994    ///     slog::Discard,
995    ///     slog::o!("key1" => "value1", "key2" => "value2"),
996    /// );
997    /// ```
998    pub fn root<T>(drain: D, values: OwnedKV<T>) -> Logger
999    where
1000        D: 'static + SendSyncRefUnwindSafeDrain<Err = Never, Ok = ()>,
1001        T: SendSyncRefUnwindSafeKV + 'static,
1002    {
1003        Logger {
1004            drain: Arc::new(drain)
1005                as Arc<dyn SendSyncRefUnwindSafeDrain<Ok = (), Err = Never>>,
1006            list: OwnedKVList::root(values),
1007        }
1008    }
1009
1010    /// Build a root `Logger` that retains `drain` type
1011    ///
1012    /// Unlike `Logger::root`, this constructor retains the type of a `drain`,
1013    /// which allows highest performance possible by eliminating indirect call
1014    /// on `Drain::log`, and allowing monomorphization of `Logger` and `Drain`
1015    /// objects.
1016    ///
1017    /// If you don't understand the implications, you should probably just
1018    /// ignore it.
1019    ///
1020    /// See `Logger:into_erased` and `Logger::to_erased` for conversion from
1021    /// type returned by this function to version that would be returned by
1022    /// `Logger::root`.
1023    pub fn root_typed<T>(drain: D, values: OwnedKV<T>) -> Logger<D>
1024    where
1025        D: 'static + SendSyncUnwindSafeDrain<Err = Never, Ok = ()> + Sized,
1026        T: SendSyncRefUnwindSafeKV + 'static,
1027    {
1028        Logger {
1029            drain,
1030            list: OwnedKVList::root(values),
1031        }
1032    }
1033
1034    /// Build a child logger
1035    ///
1036    /// Child logger inherits all existing key-value pairs from its parent and
1037    /// supplements them with additional ones.
1038    ///
1039    /// Use `o!` macro to build `OwnedKV` object.
1040    ///
1041    /// ### Drain cloning (`D : Clone` requirement)
1042    ///
1043    /// All children, their children and so on, form one tree sharing a
1044    /// common drain. This drain, will be `Clone`d when this method is called.
1045    /// That is why `Clone` must be implemented for `D` in `Logger<D>::new`.
1046    ///
1047    /// For some `Drain` types `Clone` is cheap or even free (a no-op). This is
1048    /// the case for any `Logger` returned by `Logger::root` and its children.
1049    ///
1050    /// When using `Logger::root_typed`, it's possible that cloning might be
1051    /// expensive, or even impossible.
1052    ///
1053    /// The reason why wrapping in an `Arc` is not done internally, and exposed
1054    /// to the user is performance. Calling `Drain::log` through an `Arc` is
1055    /// tiny bit slower than doing it directly.
1056    ///
1057    /// ```
1058    /// use slog::o;
1059    /// let root = slog::Logger::root(
1060    ///     slog::Discard,
1061    ///     o!("key1" => "value1", "key2" => "value2"),
1062    /// );
1063    /// let _log = root.new(slog::o!("key" => "value"));
1064    /// ```
1065    #[allow(clippy::wrong_self_convention)]
1066    pub fn new<T>(&self, values: OwnedKV<T>) -> Logger<D>
1067    where
1068        T: SendSyncRefUnwindSafeKV + 'static,
1069        D: Clone,
1070    {
1071        Logger {
1072            drain: self.drain.clone(),
1073            list: OwnedKVList::new(values, self.list.node.clone()),
1074        }
1075    }
1076
1077    /// Log one logging `Record`
1078    ///
1079    /// Use specific logging functions instead. See `log!` macro
1080    /// documentation.
1081    #[inline]
1082    pub fn log(&self, record: &Record<'_>) {
1083        let _ = self.drain.log(record, &self.list);
1084    }
1085
1086    /// Flush all pending log records, blocking until completion.
1087    ///
1088    /// In many cases this is equivalent to calling [`std::io::Write::flush`] on the underlying stream.
1089    /// See docs on [`Drain::flush`] for more details.
1090    ///
1091    /// Returns [`FlushError::NotSupported`] if the underlying drain does not support [`Drain::flush`].
1092    #[inline]
1093    pub fn flush(&self) -> result::Result<(), FlushError> {
1094        self.drain.flush()
1095    }
1096
1097    /// Get list of key-value pairs assigned to this `Logger`
1098    pub fn list(&self) -> &OwnedKVList {
1099        &self.list
1100    }
1101
1102    /// Convert to default, "erased" type:
1103    /// `Logger<Arc<SendSyncUnwindSafeDrain>>`
1104    ///
1105    /// Useful to adapt `Logger<D : Clone>` to an interface expecting
1106    /// `Logger<Arc<...>>`.
1107    ///
1108    /// Note that calling on a `Logger<Arc<...>>` will convert it to
1109    /// `Logger<Arc<Arc<...>>>` which is not optimal. This might be fixed when
1110    /// Rust gains trait implementation specialization.
1111    pub fn into_erased(
1112        self,
1113    ) -> Logger<Arc<dyn SendSyncRefUnwindSafeDrain<Ok = (), Err = Never>>>
1114    where
1115        D: SendRefUnwindSafeDrain + 'static,
1116    {
1117        Logger {
1118            drain: Arc::new(self.drain)
1119                as Arc<dyn SendSyncRefUnwindSafeDrain<Ok = (), Err = Never>>,
1120            list: self.list,
1121        }
1122    }
1123
1124    /// Create a copy with "erased" type
1125    ///
1126    /// See `into_erased`
1127    pub fn to_erased(
1128        &self,
1129    ) -> Logger<Arc<dyn SendSyncRefUnwindSafeDrain<Ok = (), Err = Never>>>
1130    where
1131        D: SendRefUnwindSafeDrain + 'static + Clone,
1132    {
1133        self.clone().into_erased()
1134    }
1135}
1136
1137impl<D> fmt::Debug for Logger<D>
1138where
1139    D: SendSyncUnwindSafeDrain<Ok = (), Err = Never>,
1140{
1141    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1142        write!(f, "Logger{:?}", self.list)?;
1143        Ok(())
1144    }
1145}
1146
1147impl<D> Drain for Logger<D>
1148where
1149    D: SendSyncUnwindSafeDrain<Ok = (), Err = Never>,
1150{
1151    type Ok = ();
1152    type Err = Never;
1153
1154    fn log(
1155        &self,
1156        record: &Record<'_>,
1157        values: &OwnedKVList,
1158    ) -> result::Result<Self::Ok, Self::Err> {
1159        // Arc is required by API, but logically redundant
1160        #[cfg_attr(
1161            feature = "nothreads",
1162            allow(clippy::arc_with_non_send_sync)
1163        )]
1164        let chained = OwnedKVList {
1165            node: Arc::new(MultiListNode {
1166                next_node: values.node.clone(),
1167                node: self.list.node.clone(),
1168            }),
1169        };
1170        self.drain.log(record, &chained)
1171    }
1172
1173    #[inline]
1174    fn is_enabled(&self, level: Level) -> bool {
1175        self.drain.is_enabled(level)
1176    }
1177
1178    #[inline]
1179    fn flush(&self) -> result::Result<(), FlushError> {
1180        self.drain.flush()
1181    }
1182}
1183
1184/// An error that occurs when calling [`Drain::flush`].
1185#[non_exhaustive]
1186#[derive(Debug)]
1187pub enum FlushError {
1188    /// An error that occurs doing IO.
1189    ///
1190    /// Often triggered by [`std::io::Write::flush`]
1191    #[cfg(feature = "std")]
1192    Io(std::io::Error),
1193    /// Indicates this drain does not support flushing.
1194    NotSupported,
1195    /// A custom error, which is not directly caused by IO or [`FlushError::NotSupported`].
1196    #[cfg(has_std_error)]
1197    Custom(Box<dyn StdError + Send + Sync + 'static>),
1198    /// An error caused by calling [`slog::Duplicate::flush`].
1199    Duplicate(Box<DuplicateDrainFlushError>),
1200}
1201#[cfg(feature = "std")]
1202impl From<std::io::Error> for FlushError {
1203    fn from(value: std::io::Error) -> Self {
1204        FlushError::Io(value)
1205    }
1206}
1207#[cfg(has_std_error)]
1208impl StdError for FlushError {
1209    fn source(&self) -> Option<&(dyn StdError + 'static)> {
1210        match self {
1211            #[cfg(feature = "std")]
1212            FlushError::Io(cause) => Some(cause),
1213            FlushError::NotSupported => None,
1214            #[cfg(has_std_error)]
1215            FlushError::Custom(cause) => Some(&**cause),
1216            FlushError::Duplicate(cause) => Some(cause),
1217        }
1218    }
1219}
1220impl fmt::Display for FlushError {
1221    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1222        match self {
1223            #[cfg(feature = "std")]
1224            FlushError::Io(_) => {
1225                f.write_str("Encountered IO error during flushing")
1226            }
1227            FlushError::NotSupported => {
1228                f.write_str("Drain does not support flushing")
1229            }
1230            #[cfg(has_std_error)]
1231            FlushError::Custom(cause) => {
1232                write!(f, "Encountered error during flushing: {cause}")
1233            }
1234            FlushError::Duplicate(cause) => write!(f, "{cause}"),
1235        }
1236    }
1237}
1238
1239/// An error from calling [`Duplicate::flush`].
1240///
1241/// This means that at least one of the drains has failed to flush.
1242#[derive(Debug)]
1243pub enum DuplicateDrainFlushError {
1244    /// Occurs when calling [`Drain::flush`] the left (first) drain of [`Duplicate`] fails,
1245    /// but flushing the right drain succeeds.
1246    Left(FlushError),
1247    /// Occurs when calling [`Drain::flush`] the right (second) drain of [`Duplicate`] fails,
1248    /// but flushing the left drain succeeds.
1249    Right(FlushError),
1250    /// Occurs when calling [`Drain::flush`] fails for both the left and right
1251    /// (first and second) drains of [`Duplicate`].
1252    Both(FlushError, FlushError),
1253}
1254impl DuplicateDrainFlushError {
1255    /// If flushing the left drain triggered an error, then return it.
1256    ///
1257    /// Returns `None` if flushing the left drain did not cause an error.
1258    pub fn left(&self) -> Option<&'_ FlushError> {
1259        match self {
1260            DuplicateDrainFlushError::Left(left)
1261            | DuplicateDrainFlushError::Both(left, _) => Some(left),
1262            DuplicateDrainFlushError::Right(_) => None,
1263        }
1264    }
1265
1266    /// If flushing the right drain triggered an error, then return it.
1267    ///
1268    /// Returns `None` if flushing the right drain did not cause an error.
1269    pub fn right(&self) -> Option<&'_ FlushError> {
1270        match self {
1271            DuplicateDrainFlushError::Right(_) => None,
1272            DuplicateDrainFlushError::Both(left, _) => Some(left),
1273            DuplicateDrainFlushError::Left(_) => None,
1274        }
1275    }
1276}
1277#[cfg(has_std_error)]
1278impl StdError for DuplicateDrainFlushError {}
1279impl fmt::Display for DuplicateDrainFlushError {
1280    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1281        let (single, name) = match self {
1282            DuplicateDrainFlushError::Left(single) => (single, "left"),
1283            DuplicateDrainFlushError::Right(single) => (single, "right"),
1284            DuplicateDrainFlushError::Both(left, right) => {
1285                return write!(
1286                    f,
1287                    "Failed to flush both drains: ({left}) and ({right})"
1288                );
1289            }
1290        };
1291        write!(f, "Failed to flush {name} drain: ({single})")
1292    }
1293}
1294
1295// {{{ Drain
1296/// Logging drain
1297///
1298/// `Drain`s typically mean destination for logs, but `slog` generalizes the
1299/// term.
1300///
1301/// `Drain`s are responsible for handling logging statements (`Record`s) from
1302/// `Logger`s associated with them: filtering, modifying, formatting
1303/// and writing the log records into given destination(s).
1304///
1305/// It's a typical pattern to parametrize `Drain`s over `Drain` traits to allow
1306/// composing `Drain`s.
1307///
1308/// Implementing this trait allows writing custom `Drain`s. Slog users should
1309/// not be afraid of implementing their own `Drain`s. Any custom log handling
1310/// logic should be implemented as a `Drain`.
1311pub trait Drain {
1312    /// Type returned by this drain
1313    ///
1314    /// It can be useful in some circumstances, but rarely. It will probably
1315    /// default to `()` once <https://github.com/rust-lang/rust/issues/29661> is
1316    /// stable.
1317    type Ok;
1318    /// Type of potential errors that can be returned by this `Drain`
1319    type Err;
1320    /// Handle one logging statement (`Record`)
1321    ///
1322    /// Every logging `Record` built from a logging statement (eg.
1323    /// `info!(...)`), and key-value lists of a `Logger` it was executed on
1324    /// will be passed to the root drain registered during `Logger::root`.
1325    ///
1326    /// Typically `Drain`s:
1327    ///
1328    /// * pass this information (or not) to the sub-logger(s) (filters)
1329    /// * format and write the information to a destination (writers)
1330    /// * deal with the errors returned from the sub-logger(s)
1331    fn log(
1332        &self,
1333        record: &Record<'_>,
1334        values: &OwnedKVList,
1335    ) -> result::Result<Self::Ok, Self::Err>;
1336
1337    /// Flush all pending log records, blocking until completion.
1338    ///
1339    /// This method is logically idempotent.
1340    /// In theory, two successive flush calls are the same as one:
1341    /// They will both flush all message up to the point of the final.
1342    /// In practice, this is not actually the case as IO is complicated and
1343    /// flush calls can return errors.
1344    ///
1345    /// Should call [`std::io::Write::flush`] if applicable.
1346    /// If this drain wraps another drain,
1347    /// it should delegate to the flush call of the wrapped drain.
1348    ///
1349    /// An implementation of flush should try to avoid blocking log operations while the flush is in progress.
1350    /// Unfortunately, there are some cases like `impl Drain for Mutex` where this is not possible.
1351    ///
1352    /// A flush call is only required to flush records that are queued before the start of the call.
1353    /// In particular, consider the following interleaving of events
1354    /// ```text
1355    /// thread1 drain.log(record1)
1356    /// thread1: drain.flush() begin
1357    /// thread2: drain.log(record2)
1358    /// thread2: drain.flush() finish
1359    /// ```
1360    /// In this case, the drain is only required to flush `record1`.
1361    /// It may or may not flush `record2`.
1362    /// This is mainly relevant for the implementation of [`slog_async::Async`],
1363    /// as we have no control over the implementation of [`std::io::Write::flush`].
1364    /// This behavior is chosen to prevent a flush call from blocking indefinitely
1365    /// in the case of concurrent logging by other threads.
1366    ///
1367    /// Returns [`FlushError::NotSupported`] if the drain has not implemented this method.
1368    ///
1369    /// [`slog_async::Async`]: https://docs.rs/slog-async/latest/slog_async/struct.Async.html
1370    fn flush(&self) -> result::Result<(), FlushError> {
1371        Err(FlushError::NotSupported)
1372    }
1373
1374    /// **Avoid**: Check if messages at the specified log level are **maybe**
1375    /// enabled for this logger.
1376    ///
1377    /// The purpose of it so to allow **imprecise** detection if a given logging
1378    /// level has any chance of actually being logged. This might be used
1379    /// to explicitly skip needless computation.
1380    ///
1381    /// **It is best effort, can return false positives, but not false negatives.**
1382    ///
1383    /// The logger is still free to ignore records even if the level is enabled,
1384    /// so an enabled level doesn't necessarily guarantee that the record will
1385    /// actually be logged.
1386    ///
1387    /// This function is somewhat needless, and is better expressed by using
1388    /// lazy values (see `FnValue`).  A `FnValue` is more precise and does not
1389    /// require additional (potentially recursive) calls to do something that
1390    /// `log` will already do anyways (making decision if something should be
1391    /// logged or not).
1392    ///
1393    /// ```
1394    /// # use slog::*;
1395    /// # fn main() {
1396    /// let logger = Logger::root(Discard, o!());
1397    /// if logger.is_enabled(Level::Debug) {
1398    ///     let num = 5.0f64;
1399    ///     let sqrt = num.sqrt();
1400    ///     debug!(logger, "Sqrt"; "num" => num, "sqrt" => sqrt);
1401    /// }
1402    /// # }
1403    /// ```
1404    #[inline]
1405    fn is_enabled(&self, level: Level) -> bool {
1406        level.as_usize() <= crate::__slog_static_max_level().as_usize()
1407    }
1408
1409    /// **Avoid**: See `is_enabled`
1410    #[inline]
1411    fn is_critical_enabled(&self) -> bool {
1412        self.is_enabled(Level::Critical)
1413    }
1414
1415    /// **Avoid**: See `is_enabled`
1416    #[inline]
1417    fn is_error_enabled(&self) -> bool {
1418        self.is_enabled(Level::Error)
1419    }
1420
1421    /// **Avoid**: See `is_enabled`
1422    #[inline]
1423    fn is_warning_enabled(&self) -> bool {
1424        self.is_enabled(Level::Warning)
1425    }
1426
1427    /// **Avoid**: See `is_enabled`
1428    #[inline]
1429    fn is_info_enabled(&self) -> bool {
1430        self.is_enabled(Level::Info)
1431    }
1432
1433    /// **Avoid**: See `is_enabled`
1434    #[inline]
1435    fn is_debug_enabled(&self) -> bool {
1436        self.is_enabled(Level::Debug)
1437    }
1438
1439    /// **Avoid**: See `is_enabled`
1440    #[inline]
1441    fn is_trace_enabled(&self) -> bool {
1442        self.is_enabled(Level::Trace)
1443    }
1444
1445    /// Pass `Drain` through a closure, eg. to wrap
1446    /// into another `Drain`.
1447    ///
1448    /// ```
1449    /// use slog::{Discard, Fuse, Drain, o};
1450    /// let _drain = Discard.map(Fuse);
1451    /// ```
1452    fn map<F, R>(self, f: F) -> R
1453    where
1454        Self: Sized,
1455        F: FnOnce(Self) -> R,
1456    {
1457        f(self)
1458    }
1459
1460    /// Filter logging records passed to `Drain`
1461    ///
1462    /// Wrap `Self` in `Filter`
1463    ///
1464    /// This will convert `self` to a `Drain` that ignores `Record`s
1465    /// for which `f` returns false.
1466    fn filter<F>(self, f: F) -> Filter<Self, F>
1467    where
1468        Self: Sized,
1469        F: FilterFn,
1470    {
1471        Filter::new(self, f)
1472    }
1473
1474    /// Filter logging records passed to `Drain` (by level)
1475    ///
1476    /// Wrap `Self` in `LevelFilter`
1477    ///
1478    /// This will convert `self` to a `Drain` that ignores `Record`s of
1479    /// logging lever smaller than `level`.
1480    fn filter_level(self, level: Level) -> LevelFilter<Self>
1481    where
1482        Self: Sized,
1483    {
1484        LevelFilter(self, level)
1485    }
1486
1487    /// Map logging errors returned by this drain
1488    ///
1489    /// `f` is a closure that takes `Drain::Err` returned by a given
1490    /// drain, and returns new error of potentially different type
1491    fn map_err<F, E>(self, f: F) -> MapError<Self, E>
1492    where
1493        Self: Sized,
1494        F: MapErrFn<Self::Err, E>,
1495    {
1496        MapError::new(self, f)
1497    }
1498
1499    /// Ignore results returned by this drain
1500    ///
1501    /// Wrap `Self` in `IgnoreResult`
1502    fn ignore_res(self) -> IgnoreResult<Self>
1503    where
1504        Self: Sized,
1505    {
1506        IgnoreResult::new(self)
1507    }
1508
1509    /// Make `Self` panic when returning any errors
1510    ///
1511    /// Wrap `Self` in `Map`
1512    fn fuse(self) -> Fuse<Self>
1513    where
1514        Self::Err: fmt::Debug,
1515        Self: Sized,
1516    {
1517        self.map(Fuse)
1518    }
1519}
1520
1521impl<'a, D: Drain + 'a> Drain for &'a D {
1522    type Ok = D::Ok;
1523    type Err = D::Err;
1524    #[inline]
1525    fn log(
1526        &self,
1527        record: &Record<'_>,
1528        values: &OwnedKVList,
1529    ) -> result::Result<Self::Ok, Self::Err> {
1530        (**self).log(record, values)
1531    }
1532    #[inline]
1533    fn is_enabled(&self, level: Level) -> bool {
1534        (**self).is_enabled(level)
1535    }
1536    #[inline]
1537    fn flush(&self) -> result::Result<(), FlushError> {
1538        (**self).flush()
1539    }
1540}
1541
1542impl<'a, D: Drain + 'a> Drain for &'a mut D {
1543    type Ok = D::Ok;
1544    type Err = D::Err;
1545    #[inline]
1546    fn log(
1547        &self,
1548        record: &Record<'_>,
1549        values: &OwnedKVList,
1550    ) -> result::Result<Self::Ok, Self::Err> {
1551        (**self).log(record, values)
1552    }
1553    #[inline]
1554    fn is_enabled(&self, level: Level) -> bool {
1555        (**self).is_enabled(level)
1556    }
1557    #[inline]
1558    fn flush(&self) -> result::Result<(), FlushError> {
1559        (**self).flush()
1560    }
1561}
1562
1563/// Internal utility module used to "maybe" bound traits
1564/// based on cfg flags.
1565///
1566/// For example, on #[cfg(feature = "std")] we require `UnwindSafe`.
1567/// On no_std we disable that bound.
1568///
1569/// This is the same issue we had with `feature="nothread"`.
1570/// In that case we had to drop all our `Send + Sync` bounds.
1571///
1572/// Before this (tiny) module, this means we had to write separate versions of all our traits
1573/// for every possible combination of std/no_std and threads/nothreads.
1574///
1575/// This means there were 4 times as many trait definitions to make.
1576///
1577/// As you can imagine, this led to some mistakes ;)
1578///
1579/// In particular, feature="nothreads" was almost completely
1580/// broken before this module.
1581///
1582/// ## Usage
1583/// Replace all usages of `Send`, `Sync`, and `UnwindSafe` with `maybe::Send` and `maybe::Sync`, etc
1584///
1585/// These bounds will automatically be enabled/disabled based on the appropriate feature flags.
1586///
1587/// This avoids quadrupling trait definitions for every possible feature combination.
1588mod maybe {
1589    #[cfg(not(feature = "nothreads"))]
1590    use core::marker;
1591    #[cfg(feature = "std")]
1592    use std::panic;
1593    macro_rules! maybe_bound_trait_def {
1594        ($name:ident where $bound:path; if cfg($flag:meta)) => {
1595            #[cfg($flag)]
1596            pub trait $name: $bound {}
1597            #[cfg($flag)]
1598            impl<T: $bound + ?Sized> $name for T {}
1599            #[cfg(not($flag))]
1600            pub trait $name {}
1601            #[cfg(not($flag))]
1602            impl<T: ?Sized> $name for T {}
1603        };
1604    }
1605    maybe_bound_trait_def!(UnwindSafe where panic::UnwindSafe; if cfg(feature="std"));
1606    maybe_bound_trait_def!(RefUnwindSafe where panic::RefUnwindSafe; if cfg(feature="std"));
1607    maybe_bound_trait_def!(Sync where marker::Sync; if cfg(not(feature = "nothreads")));
1608    maybe_bound_trait_def!(Send where marker::Send; if cfg(not(feature = "nothreads")));
1609}
1610
1611/// `Send + Sync + UnwindSafe` bound
1612///
1613/// This type is used to enforce `Drain`s associated with `Logger`s
1614/// are thread-safe.
1615pub trait SendSyncUnwindSafe:
1616    maybe::Send + maybe::Sync + maybe::UnwindSafe
1617{
1618}
1619
1620impl<T> SendSyncUnwindSafe for T where
1621    T: maybe::Send + maybe::Sync + maybe::UnwindSafe + ?Sized
1622{
1623}
1624
1625/// `Drain + Send + Sync + UnwindSafe` bound
1626///
1627/// This type is used to enforce `Drain`s associated with `Logger`s
1628/// are thread-safe.
1629pub trait SendSyncUnwindSafeDrain:
1630    Drain + maybe::Send + maybe::Sync + maybe::UnwindSafe
1631{
1632}
1633
1634impl<T> SendSyncUnwindSafeDrain for T where
1635    T: Drain + maybe::Send + maybe::Sync + maybe::UnwindSafe + ?Sized
1636{
1637}
1638
1639/// `Drain + Send + Sync + RefUnwindSafe` bound
1640///
1641/// This type is used to enforce `Drain`s associated with `Logger`s
1642/// are thread-safe.
1643pub trait SendSyncRefUnwindSafeDrain:
1644    Drain + maybe::Send + maybe::Sync + maybe::RefUnwindSafe
1645{
1646}
1647
1648impl<T> SendSyncRefUnwindSafeDrain for T where
1649    T: Drain + maybe::Send + maybe::Sync + maybe::RefUnwindSafe + ?Sized
1650{
1651}
1652
1653/// Function that can be used in `MapErr` drain
1654pub trait MapErrFn<EI, EO>:
1655    'static
1656    + maybe::Sync
1657    + maybe::Send
1658    + maybe::UnwindSafe
1659    + maybe::RefUnwindSafe
1660    + Fn(EI) -> EO
1661{
1662}
1663
1664impl<T, EI, EO> MapErrFn<EI, EO> for T where
1665    T: 'static
1666        + maybe::Sync
1667        + maybe::Send
1668        + ?Sized
1669        + maybe::UnwindSafe
1670        + maybe::RefUnwindSafe
1671        + Fn(EI) -> EO
1672{
1673}
1674
1675/// Function that can be used in `Filter` drain
1676pub trait FilterFn:
1677    'static
1678    + maybe::Sync
1679    + maybe::Send
1680    + maybe::UnwindSafe
1681    + maybe::RefUnwindSafe
1682    + Fn(&Record<'_>) -> bool
1683{
1684}
1685
1686impl<T> FilterFn for T where
1687    T: 'static
1688        + maybe::Sync
1689        + maybe::Send
1690        + ?Sized
1691        + maybe::UnwindSafe
1692        + maybe::RefUnwindSafe
1693        + Fn(&Record<'_>) -> bool
1694{
1695}
1696
1697/// `Drain + Send + RefUnwindSafe` bound
1698pub trait SendRefUnwindSafeDrain:
1699    Drain + maybe::Send + maybe::RefUnwindSafe
1700{
1701}
1702
1703impl<T> SendRefUnwindSafeDrain for T where
1704    T: Drain + maybe::Send + maybe::RefUnwindSafe + ?Sized
1705{
1706}
1707
1708impl<D: Drain + ?Sized> Drain for Box<D> {
1709    type Ok = D::Ok;
1710    type Err = D::Err;
1711    fn log(
1712        &self,
1713        record: &Record<'_>,
1714        o: &OwnedKVList,
1715    ) -> result::Result<Self::Ok, D::Err> {
1716        (**self).log(record, o)
1717    }
1718    #[inline]
1719    fn is_enabled(&self, level: Level) -> bool {
1720        (**self).is_enabled(level)
1721    }
1722    #[inline]
1723    fn flush(&self) -> result::Result<(), FlushError> {
1724        (**self).flush()
1725    }
1726}
1727
1728impl<D: Drain + ?Sized> Drain for Arc<D> {
1729    type Ok = D::Ok;
1730    type Err = D::Err;
1731    fn log(
1732        &self,
1733        record: &Record<'_>,
1734        o: &OwnedKVList,
1735    ) -> result::Result<Self::Ok, D::Err> {
1736        (**self).log(record, o)
1737    }
1738    #[inline]
1739    fn is_enabled(&self, level: Level) -> bool {
1740        (**self).is_enabled(level)
1741    }
1742    #[inline]
1743    fn flush(&self) -> result::Result<(), FlushError> {
1744        (**self).flush()
1745    }
1746}
1747
1748/// `Drain` discarding everything
1749///
1750/// `/dev/null` of `Drain`s
1751#[derive(Debug, Copy, Clone)]
1752#[must_use = "does nothing by itself; needs to be attached to Logger"]
1753pub struct Discard;
1754
1755impl Drain for Discard {
1756    type Ok = ();
1757    type Err = Never;
1758    fn log(
1759        &self,
1760        _: &Record<'_>,
1761        _: &OwnedKVList,
1762    ) -> result::Result<(), Never> {
1763        Ok(())
1764    }
1765    #[inline]
1766    fn is_enabled(&self, _level: Level) -> bool {
1767        false
1768    }
1769    #[inline]
1770    fn flush(&self) -> result::Result<(), FlushError> {
1771        Ok(())
1772    }
1773}
1774
1775/// `Drain` filtering records
1776///
1777/// Wraps another `Drain` and passes `Record`s to it, only if they satisfy a
1778/// given condition.
1779#[derive(Debug, Clone)]
1780#[must_use = "does nothing by itself; needs to be attached to Logger"]
1781pub struct Filter<D: Drain, F>(pub D, pub F)
1782where
1783    F: Fn(&Record<'_>) -> bool + 'static + maybe::Send + maybe::Sync;
1784
1785impl<D: Drain, F> Filter<D, F>
1786where
1787    F: FilterFn,
1788{
1789    /// Create `Filter` wrapping given `drain`
1790    pub fn new(drain: D, cond: F) -> Self {
1791        Filter(drain, cond)
1792    }
1793}
1794
1795impl<D: Drain, F> Drain for Filter<D, F>
1796where
1797    F: FilterFn,
1798{
1799    type Ok = Option<D::Ok>;
1800    type Err = D::Err;
1801    fn log(
1802        &self,
1803        record: &Record<'_>,
1804        logger_values: &OwnedKVList,
1805    ) -> result::Result<Self::Ok, Self::Err> {
1806        if (self.1)(record) {
1807            Ok(Some(self.0.log(record, logger_values)?))
1808        } else {
1809            Ok(None)
1810        }
1811    }
1812    #[inline]
1813    fn is_enabled(&self, level: Level) -> bool {
1814        /*
1815         * This is one of the reasons we can't guarantee the value is actually logged.
1816         * The filter function is given dynamic control over whether or not the record is logged
1817         * and could filter stuff out even if the log level is supposed to be enabled
1818         */
1819        self.0.is_enabled(level)
1820    }
1821    #[inline]
1822    fn flush(&self) -> result::Result<(), FlushError> {
1823        self.0.flush()
1824    }
1825}
1826
1827/// `Drain` filtering records by `Record` logging level
1828///
1829/// Wraps a drain and passes records to it, only
1830/// if their level is at least given level.
1831///
1832/// TODO: Remove this type. This drain is a special case of `Filter`, but
1833/// because `Filter` can not use static dispatch ATM due to Rust limitations
1834/// that will be lifted in the future, it is a standalone type.
1835/// Reference: <https://github.com/rust-lang/rust/issues/34511>
1836#[derive(Debug, Clone)]
1837#[must_use = "does nothing by itself; needs to be attached to Logger"]
1838pub struct LevelFilter<D: Drain>(pub D, pub Level);
1839
1840impl<D: Drain> LevelFilter<D> {
1841    /// Create `LevelFilter`
1842    pub fn new(drain: D, level: Level) -> Self {
1843        LevelFilter(drain, level)
1844    }
1845}
1846
1847impl<D: Drain> Drain for LevelFilter<D> {
1848    type Ok = Option<D::Ok>;
1849    type Err = D::Err;
1850    fn log(
1851        &self,
1852        record: &Record<'_>,
1853        logger_values: &OwnedKVList,
1854    ) -> result::Result<Self::Ok, Self::Err> {
1855        if record.level().is_at_least(self.1) {
1856            Ok(Some(self.0.log(record, logger_values)?))
1857        } else {
1858            Ok(None)
1859        }
1860    }
1861    #[inline]
1862    fn is_enabled(&self, level: Level) -> bool {
1863        level.is_at_least(self.1) && self.0.is_enabled(level)
1864    }
1865    #[inline]
1866    fn flush(&self) -> result::Result<(), FlushError> {
1867        self.0.flush()
1868    }
1869}
1870
1871/// `Drain` mapping error returned by another `Drain`
1872///
1873/// See `Drain::map_err` for convenience function.
1874#[must_use = "does nothing by itself; needs to be attached to Logger"]
1875pub struct MapError<D: Drain, E> {
1876    drain: D,
1877    // eliminated dynamic dispatch, after rust learns `-> impl Trait`
1878    map_fn: Box<dyn MapErrFn<D::Err, E, Output = E>>,
1879}
1880
1881impl<D: Drain, E> MapError<D, E> {
1882    /// Create `Filter` wrapping given `drain`
1883    pub fn new<F>(drain: D, map_fn: F) -> Self
1884    where
1885        F: MapErrFn<<D as Drain>::Err, E>,
1886    {
1887        MapError {
1888            drain,
1889            map_fn: Box::new(map_fn),
1890        }
1891    }
1892}
1893
1894impl<D: Drain, E> Drain for MapError<D, E> {
1895    type Ok = D::Ok;
1896    type Err = E;
1897    fn log(
1898        &self,
1899        record: &Record<'_>,
1900        logger_values: &OwnedKVList,
1901    ) -> result::Result<Self::Ok, Self::Err> {
1902        self.drain
1903            .log(record, logger_values)
1904            .map_err(|e| (self.map_fn)(e))
1905    }
1906    #[inline]
1907    fn is_enabled(&self, level: Level) -> bool {
1908        self.drain.is_enabled(level)
1909    }
1910    #[inline]
1911    fn flush(&self) -> result::Result<(), FlushError> {
1912        self.drain.flush()
1913    }
1914}
1915
1916/// `Drain` duplicating records into two other `Drain`s
1917///
1918/// Can be nested for more than two outputs.
1919#[derive(Debug, Clone)]
1920#[must_use = "does nothing by itself; needs to be attached to Logger"]
1921pub struct Duplicate<D1: Drain, D2: Drain>(pub D1, pub D2);
1922
1923impl<D1: Drain, D2: Drain> Duplicate<D1, D2> {
1924    /// Create `Duplicate`
1925    pub fn new(drain1: D1, drain2: D2) -> Self {
1926        Duplicate(drain1, drain2)
1927    }
1928}
1929
1930impl<D1: Drain, D2: Drain> Drain for Duplicate<D1, D2> {
1931    type Ok = (D1::Ok, D2::Ok);
1932    type Err = (
1933        result::Result<D1::Ok, D1::Err>,
1934        result::Result<D2::Ok, D2::Err>,
1935    );
1936    fn log(
1937        &self,
1938        record: &Record<'_>,
1939        logger_values: &OwnedKVList,
1940    ) -> result::Result<Self::Ok, Self::Err> {
1941        let res1 = self.0.log(record, logger_values);
1942        let res2 = self.1.log(record, logger_values);
1943
1944        match (res1, res2) {
1945            (Ok(o1), Ok(o2)) => Ok((o1, o2)),
1946            (r1, r2) => Err((r1, r2)),
1947        }
1948    }
1949    #[inline]
1950    fn is_enabled(&self, level: Level) -> bool {
1951        self.0.is_enabled(level) || self.1.is_enabled(level)
1952    }
1953    /// Flush both drains.
1954    ///
1955    /// If one or both of the drains fails, this will return a [`DuplicateDrainFlushError`].
1956    /// Even if the first drain fails with an error, the second one will still be flushed.
1957    #[inline]
1958    fn flush(&self) -> result::Result<(), FlushError> {
1959        let first_res = self.0.flush();
1960        let second_res = self.1.flush();
1961        let err = match (first_res, second_res) {
1962            (Ok(()), Ok(())) => {
1963                return Ok(()); // short-circuit success
1964            }
1965            (Err(left), Ok(())) => DuplicateDrainFlushError::Left(left),
1966            (Ok(()), Err(right)) => DuplicateDrainFlushError::Right(right),
1967            (Err(left), Err(right)) => {
1968                DuplicateDrainFlushError::Both(left, right)
1969            }
1970        };
1971        Err(FlushError::Duplicate(Box::new(err)))
1972    }
1973}
1974
1975/// `Drain` panicking on error
1976///
1977/// `Logger` requires a root drain to handle all errors (`Drain::Error == ()`),
1978/// `Fuse` will wrap a `Drain` and panic if it returns any errors.
1979///
1980/// Note: `Drain::Err` must implement `Display` (for displaying on panic). It's
1981/// easy to create your own `Fuse` drain if this requirement can't be fulfilled.
1982#[derive(Debug, Clone)]
1983#[must_use = "does nothing by itself; needs to be attached to Logger"]
1984pub struct Fuse<D: Drain>(pub D)
1985where
1986    D::Err: fmt::Debug;
1987
1988impl<D: Drain> Fuse<D>
1989where
1990    D::Err: fmt::Debug,
1991{
1992    /// Create `Fuse` wrapping given `drain`
1993    pub fn new(drain: D) -> Self {
1994        Fuse(drain)
1995    }
1996}
1997
1998impl<D: Drain> Drain for Fuse<D>
1999where
2000    D::Err: fmt::Debug,
2001{
2002    type Ok = ();
2003    type Err = Never;
2004    fn log(
2005        &self,
2006        record: &Record<'_>,
2007        logger_values: &OwnedKVList,
2008    ) -> result::Result<Self::Ok, Never> {
2009        let _ = self
2010            .0
2011            .log(record, logger_values)
2012            .unwrap_or_else(|e| panic!("slog::Fuse Drain: {:?}", e));
2013        Ok(())
2014    }
2015    #[inline]
2016    fn is_enabled(&self, level: Level) -> bool {
2017        self.0.is_enabled(level)
2018    }
2019    #[inline]
2020    fn flush(&self) -> result::Result<(), FlushError> {
2021        self.0.flush()
2022    }
2023}
2024
2025/// `Drain` ignoring result
2026///
2027/// `Logger` requires a root drain to handle all errors (`Drain::Err=()`), and
2028/// returns nothing (`Drain::Ok=()`) `IgnoreResult` will ignore any result
2029/// returned by the `Drain` it wraps.
2030#[derive(Clone)]
2031#[must_use = "does nothing by itself; needs to be attached to Logger"]
2032pub struct IgnoreResult<D: Drain> {
2033    drain: D,
2034}
2035
2036impl<D: Drain> IgnoreResult<D> {
2037    /// Create `IgnoreResult` wrapping `drain`
2038    pub fn new(drain: D) -> Self {
2039        IgnoreResult { drain }
2040    }
2041}
2042
2043impl<D: Drain> Drain for IgnoreResult<D> {
2044    type Ok = ();
2045    type Err = Never;
2046    fn log(
2047        &self,
2048        record: &Record<'_>,
2049        logger_values: &OwnedKVList,
2050    ) -> result::Result<(), Never> {
2051        let _ = self.drain.log(record, logger_values);
2052        Ok(())
2053    }
2054
2055    #[inline]
2056    fn is_enabled(&self, level: Level) -> bool {
2057        self.drain.is_enabled(level)
2058    }
2059
2060    #[inline]
2061    fn flush(&self) -> result::Result<(), FlushError> {
2062        self.drain.flush()
2063    }
2064}
2065
2066/// Error returned by `Mutex<D : Drain>`
2067#[cfg(feature = "std")]
2068#[derive(Clone)]
2069pub enum MutexDrainError<D: Drain> {
2070    /// Error acquiring mutex
2071    Mutex,
2072    /// Error returned by drain
2073    Drain(D::Err),
2074}
2075
2076#[cfg(feature = "std")]
2077impl<D> fmt::Debug for MutexDrainError<D>
2078where
2079    D: Drain,
2080    D::Err: fmt::Debug,
2081{
2082    fn fmt(
2083        &self,
2084        f: &mut fmt::Formatter<'_>,
2085    ) -> result::Result<(), fmt::Error> {
2086        match *self {
2087            MutexDrainError::Mutex => write!(f, "MutexDrainError::Mutex"),
2088            MutexDrainError::Drain(ref e) => e.fmt(f),
2089        }
2090    }
2091}
2092
2093#[cfg(feature = "std")]
2094impl<D> StdError for MutexDrainError<D>
2095where
2096    D: Drain,
2097    D::Err: fmt::Debug + fmt::Display + StdError,
2098{
2099    // Deprecated in Rust 1.42
2100    #[allow(deprecated)]
2101    fn description(&self) -> &str {
2102        match *self {
2103            MutexDrainError::Mutex => "Mutex acquire failed",
2104            MutexDrainError::Drain(ref e) => e.description(),
2105        }
2106    }
2107
2108    fn cause(&self) -> Option<&dyn StdError> {
2109        match *self {
2110            MutexDrainError::Mutex => None,
2111            MutexDrainError::Drain(ref e) => Some(e),
2112        }
2113    }
2114}
2115
2116#[cfg(feature = "std")]
2117impl<'a, D: Drain> From<std::sync::PoisonError<std::sync::MutexGuard<'a, D>>>
2118    for MutexDrainError<D>
2119{
2120    fn from(
2121        _: std::sync::PoisonError<std::sync::MutexGuard<'a, D>>,
2122    ) -> MutexDrainError<D> {
2123        MutexDrainError::Mutex
2124    }
2125}
2126
2127#[cfg(feature = "std")]
2128impl<D: Drain> fmt::Display for MutexDrainError<D>
2129where
2130    D::Err: fmt::Display,
2131{
2132    fn fmt(
2133        &self,
2134        f: &mut fmt::Formatter<'_>,
2135    ) -> result::Result<(), fmt::Error> {
2136        match *self {
2137            MutexDrainError::Mutex => write!(f, "MutexError"),
2138            MutexDrainError::Drain(ref e) => write!(f, "{}", e),
2139        }
2140    }
2141}
2142
2143#[cfg(feature = "std")]
2144impl<D: Drain> Drain for std::sync::Mutex<D> {
2145    type Ok = D::Ok;
2146    type Err = MutexDrainError<D>;
2147    fn log(
2148        &self,
2149        record: &Record<'_>,
2150        logger_values: &OwnedKVList,
2151    ) -> result::Result<Self::Ok, Self::Err> {
2152        let d = self.lock()?;
2153        d.log(record, logger_values).map_err(MutexDrainError::Drain)
2154    }
2155    #[inline]
2156    fn is_enabled(&self, level: Level) -> bool {
2157        self.lock().ok().map_or(true, |lock| lock.is_enabled(level))
2158    }
2159    #[inline]
2160    fn flush(&self) -> result::Result<(), FlushError> {
2161        let guard = self.lock().map_err(|_poison| {
2162            std::io::Error::new(std::io::ErrorKind::Other, "Mutex is poisoned")
2163        })?;
2164        guard.flush()
2165    }
2166}
2167
2168#[cfg(feature = "parking_lot_0_12")]
2169impl<D: Drain> Drain for parking_lot_0_12::Mutex<D> {
2170    type Ok = D::Ok;
2171    type Err = D::Err;
2172    fn log(
2173        &self,
2174        record: &Record<'_>,
2175        logger_values: &OwnedKVList,
2176    ) -> result::Result<Self::Ok, Self::Err> {
2177        let d = self.lock();
2178        d.log(record, logger_values)
2179    }
2180    #[inline]
2181    fn is_enabled(&self, level: Level) -> bool {
2182        self.lock().is_enabled(level)
2183    }
2184}
2185// }}}
2186
2187// {{{ Level & FilterLevel
2188/// Official capitalized logging (and logging filtering) level names
2189///
2190/// In order of `as_usize()`.
2191pub static LOG_LEVEL_NAMES: [&str; 7] = [
2192    "OFF", "CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG", "TRACE",
2193];
2194
2195/// Official capitalized logging (and logging filtering) short level names
2196///
2197/// In order of `as_usize()`.
2198pub static LOG_LEVEL_SHORT_NAMES: [&str; 7] =
2199    ["OFF", "CRIT", "ERRO", "WARN", "INFO", "DEBG", "TRCE"];
2200
2201/// Logging level associated with a logging `Record`
2202#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
2203pub enum Level {
2204    /// Critical
2205    Critical,
2206    /// Error
2207    Error,
2208    /// Warning
2209    Warning,
2210    /// Info
2211    Info,
2212    /// Debug
2213    Debug,
2214    /// Trace
2215    Trace,
2216}
2217
2218/// Logging filtering level
2219#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
2220#[must_use = "has no effect unless attached to a drain"]
2221pub enum FilterLevel {
2222    /// Log nothing
2223    Off,
2224    /// Log critical level only
2225    Critical,
2226    /// Log only error level and above
2227    Error,
2228    /// Log only warning level and above
2229    Warning,
2230    /// Log only info level and above
2231    Info,
2232    /// Log only debug level and above
2233    Debug,
2234    /// Log everything
2235    Trace,
2236}
2237
2238impl Level {
2239    /// Convert to `str` from `LOG_LEVEL_SHORT_NAMES`
2240    pub fn as_short_str(&self) -> &'static str {
2241        LOG_LEVEL_SHORT_NAMES[self.as_usize()]
2242    }
2243
2244    /// Convert to `str` from `LOG_LEVEL_NAMES`
2245    pub fn as_str(&self) -> &'static str {
2246        LOG_LEVEL_NAMES[self.as_usize()]
2247    }
2248
2249    /// Cast `Level` to ordering integer
2250    ///
2251    /// `Critical` is the smallest and `Trace` the biggest value
2252    #[inline]
2253    pub fn as_usize(&self) -> usize {
2254        match *self {
2255            Level::Critical => 1,
2256            Level::Error => 2,
2257            Level::Warning => 3,
2258            Level::Info => 4,
2259            Level::Debug => 5,
2260            Level::Trace => 6,
2261        }
2262    }
2263
2264    /// Get a `Level` from an `usize`
2265    ///
2266    /// This complements `as_usize`
2267    #[inline]
2268    pub fn from_usize(u: usize) -> Option<Level> {
2269        match u {
2270            1 => Some(Level::Critical),
2271            2 => Some(Level::Error),
2272            3 => Some(Level::Warning),
2273            4 => Some(Level::Info),
2274            5 => Some(Level::Debug),
2275            6 => Some(Level::Trace),
2276            _ => None,
2277        }
2278    }
2279}
2280
2281impl FilterLevel {
2282    /// Convert to `str` from `LOG_LEVEL_SHORT_NAMES`
2283    pub fn as_short_str(&self) -> &'static str {
2284        LOG_LEVEL_SHORT_NAMES[self.as_usize()]
2285    }
2286
2287    /// Convert to `str` from `LOG_LEVEL_NAMES`
2288    pub fn as_str(&self) -> &'static str {
2289        LOG_LEVEL_NAMES[self.as_usize()]
2290    }
2291
2292    /// Convert to `usize` value
2293    ///
2294    /// `Off` is 0, and `Trace` 6
2295    #[inline]
2296    pub fn as_usize(&self) -> usize {
2297        match *self {
2298            FilterLevel::Off => 0,
2299            FilterLevel::Critical => 1,
2300            FilterLevel::Error => 2,
2301            FilterLevel::Warning => 3,
2302            FilterLevel::Info => 4,
2303            FilterLevel::Debug => 5,
2304            FilterLevel::Trace => 6,
2305        }
2306    }
2307
2308    /// Get a `FilterLevel` from an `usize`
2309    ///
2310    /// This complements `as_usize`
2311    #[inline]
2312    pub fn from_usize(u: usize) -> Option<FilterLevel> {
2313        match u {
2314            0 => Some(FilterLevel::Off),
2315            1 => Some(FilterLevel::Critical),
2316            2 => Some(FilterLevel::Error),
2317            3 => Some(FilterLevel::Warning),
2318            4 => Some(FilterLevel::Info),
2319            5 => Some(FilterLevel::Debug),
2320            6 => Some(FilterLevel::Trace),
2321            _ => None,
2322        }
2323    }
2324
2325    /// Maximum logging level (log everything)
2326    #[inline]
2327    pub fn max() -> Self {
2328        FilterLevel::Trace
2329    }
2330
2331    /// Minimum logging level (log nothing)
2332    #[inline]
2333    pub fn min() -> Self {
2334        FilterLevel::Off
2335    }
2336
2337    /// Check if message with given level should be logged
2338    pub fn accepts(self, level: Level) -> bool {
2339        self.as_usize() >= level.as_usize()
2340    }
2341}
2342
2343impl FromStr for Level {
2344    type Err = ();
2345    fn from_str(name: &str) -> core::result::Result<Level, ()> {
2346        index_of_log_level_name(name)
2347            .and_then(Level::from_usize)
2348            .ok_or(())
2349    }
2350}
2351
2352impl FromStr for FilterLevel {
2353    type Err = ();
2354    fn from_str(name: &str) -> core::result::Result<FilterLevel, ()> {
2355        index_of_log_level_name(name)
2356            .and_then(FilterLevel::from_usize)
2357            .ok_or(())
2358    }
2359}
2360
2361fn index_of_log_level_name(name: &str) -> Option<usize> {
2362    index_of_str_ignore_case(&LOG_LEVEL_NAMES, name)
2363        .or_else(|| index_of_str_ignore_case(&LOG_LEVEL_SHORT_NAMES, name))
2364}
2365
2366fn index_of_str_ignore_case(haystack: &[&str], needle: &str) -> Option<usize> {
2367    if needle.is_empty() {
2368        return None;
2369    }
2370    haystack
2371        .iter()
2372        // This will never panic because haystack has only ASCII characters
2373        .map(|hay| &hay[..needle.len().min(hay.len())])
2374        .position(|hay| hay.eq_ignore_ascii_case(needle))
2375}
2376
2377impl fmt::Display for Level {
2378    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2379        write!(f, "{}", self.as_short_str())
2380    }
2381}
2382
2383impl fmt::Display for FilterLevel {
2384    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2385        write!(f, "{}", self.as_short_str())
2386    }
2387}
2388
2389impl Level {
2390    /// Returns true if `self` is at least `level` logging level
2391    #[inline]
2392    pub fn is_at_least(&self, level: Self) -> bool {
2393        self.as_usize() <= level.as_usize()
2394    }
2395}
2396
2397#[test]
2398fn level_at_least() {
2399    assert!(Level::Debug.is_at_least(Level::Debug));
2400    assert!(Level::Debug.is_at_least(Level::Trace));
2401    assert!(!Level::Debug.is_at_least(Level::Info));
2402}
2403
2404#[test]
2405fn filter_level_sanity() {
2406    assert!(Level::Critical.as_usize() > FilterLevel::Off.as_usize());
2407    assert!(Level::Critical.as_usize() == FilterLevel::Critical.as_usize());
2408    assert!(Level::Trace.as_usize() == FilterLevel::Trace.as_usize());
2409}
2410
2411#[test]
2412fn level_from_str() {
2413    refute_from_str::<Level>("off");
2414    assert_from_str(Level::Critical, "critical");
2415    assert_from_str(Level::Critical, "crit");
2416    assert_from_str(Level::Error, "error");
2417    assert_from_str(Level::Error, "erro");
2418    assert_from_str(Level::Warning, "warn");
2419    assert_from_str(Level::Info, "info");
2420    assert_from_str(Level::Debug, "debug");
2421    assert_from_str(Level::Debug, "debg");
2422    assert_from_str(Level::Trace, "trace");
2423    assert_from_str(Level::Trace, "trce");
2424
2425    assert_from_str(Level::Info, "Info");
2426    assert_from_str(Level::Info, "INFO");
2427    assert_from_str(Level::Info, "iNfO");
2428
2429    refute_from_str::<Level>("");
2430    assert_from_str(Level::Info, "i");
2431    assert_from_str(Level::Info, "in");
2432    assert_from_str(Level::Info, "inf");
2433    refute_from_str::<Level>("infor"); // spellchecker:ignore
2434
2435    refute_from_str::<Level>("?");
2436    refute_from_str::<Level>("info ");
2437    refute_from_str::<Level>(" info");
2438    refute_from_str::<Level>("desinfo");
2439}
2440
2441#[test]
2442fn filter_level_from_str() {
2443    assert_from_str(FilterLevel::Off, "off");
2444    assert_from_str(FilterLevel::Critical, "critical");
2445    assert_from_str(FilterLevel::Critical, "crit");
2446    assert_from_str(FilterLevel::Error, "error");
2447    assert_from_str(FilterLevel::Error, "erro");
2448    assert_from_str(FilterLevel::Warning, "warn");
2449    assert_from_str(FilterLevel::Info, "info");
2450    assert_from_str(FilterLevel::Debug, "debug");
2451    assert_from_str(FilterLevel::Debug, "debg");
2452    assert_from_str(FilterLevel::Trace, "trace");
2453    assert_from_str(FilterLevel::Trace, "trce");
2454
2455    assert_from_str(FilterLevel::Info, "Info");
2456    assert_from_str(FilterLevel::Info, "INFO");
2457    assert_from_str(FilterLevel::Info, "iNfO");
2458
2459    refute_from_str::<FilterLevel>("");
2460    assert_from_str(FilterLevel::Info, "i");
2461    assert_from_str(FilterLevel::Info, "in");
2462    assert_from_str(FilterLevel::Info, "inf");
2463    refute_from_str::<FilterLevel>("infor"); // spellchecker:ignore
2464
2465    refute_from_str::<FilterLevel>("?");
2466    refute_from_str::<FilterLevel>("info ");
2467    refute_from_str::<FilterLevel>(" info");
2468    refute_from_str::<FilterLevel>("desinfo");
2469}
2470
2471#[cfg(test)]
2472fn assert_from_str<T>(expected: T, level_str: &str)
2473where
2474    T: FromStr + fmt::Debug + PartialEq,
2475    T::Err: fmt::Debug,
2476{
2477    let result = T::from_str(level_str);
2478
2479    let actual = result.unwrap_or_else(|e| {
2480        panic!("Failed to parse filter level '{}': {:?}", level_str, e)
2481    });
2482    assert_eq!(
2483        expected, actual,
2484        "Invalid filter level parsed from '{}'",
2485        level_str
2486    );
2487}
2488
2489#[cfg(test)]
2490fn refute_from_str<T>(level_str: &str)
2491where
2492    T: FromStr + fmt::Debug,
2493{
2494    let result = T::from_str(level_str);
2495
2496    if let Ok(level) = result {
2497        panic!(
2498            "Parsing filter level '{}' succeeded: {:?}",
2499            level_str, level
2500        )
2501    }
2502}
2503
2504#[cfg(feature = "std")]
2505#[test]
2506fn level_to_string_and_from_str_are_compatible() {
2507    assert_to_string_from_str(Level::Critical);
2508    assert_to_string_from_str(Level::Error);
2509    assert_to_string_from_str(Level::Warning);
2510    assert_to_string_from_str(Level::Info);
2511    assert_to_string_from_str(Level::Debug);
2512    assert_to_string_from_str(Level::Trace);
2513}
2514
2515#[cfg(feature = "std")]
2516#[test]
2517fn filter_level_to_string_and_from_str_are_compatible() {
2518    assert_to_string_from_str(FilterLevel::Off);
2519    assert_to_string_from_str(FilterLevel::Critical);
2520    assert_to_string_from_str(FilterLevel::Error);
2521    assert_to_string_from_str(FilterLevel::Warning);
2522    assert_to_string_from_str(FilterLevel::Info);
2523    assert_to_string_from_str(FilterLevel::Debug);
2524    assert_to_string_from_str(FilterLevel::Trace);
2525}
2526
2527#[cfg(all(test, feature = "std"))]
2528fn assert_to_string_from_str<T>(expected: T)
2529where
2530    T: alloc::string::ToString + FromStr + PartialEq + fmt::Debug,
2531    <T as FromStr>::Err: fmt::Debug,
2532{
2533    let string = expected.to_string();
2534
2535    let actual = T::from_str(&string).unwrap_or_else(|_err| {
2536        panic!("Failed to parse string representation of {:?}", expected)
2537    });
2538
2539    assert_eq!(
2540        expected, actual,
2541        "Invalid value parsed from string representation of {:?}",
2542        actual
2543    );
2544}
2545
2546#[test]
2547fn filter_level_accepts_tests() {
2548    assert!(FilterLevel::Warning.accepts(Level::Error));
2549    assert!(FilterLevel::Warning.accepts(Level::Warning));
2550    assert!(!FilterLevel::Warning.accepts(Level::Info));
2551    assert!(!FilterLevel::Off.accepts(Level::Critical));
2552}
2553// }}}
2554
2555// {{{ Record
2556#[doc(hidden)]
2557#[derive(Clone, Copy)]
2558pub struct RecordLocation {
2559    /// File
2560    pub file: &'static str,
2561    /// Line
2562    pub line: u32,
2563    /// Column (currently not implemented)
2564    pub column: u32,
2565    /// Function (currently not implemented)
2566    pub function: &'static str,
2567    /// Module
2568    pub module: &'static str,
2569}
2570/// Information that can be static in the given record thus allowing to optimize
2571/// record creation to be done mostly at compile-time.
2572///
2573/// This should be constructed via the `record_static!` macro.
2574pub struct RecordStatic<'a> {
2575    /// Code location
2576    #[doc(hidden)]
2577    pub location: &'a RecordLocation,
2578    /// Tag
2579    #[doc(hidden)]
2580    pub tag: &'a str,
2581    /// Logging level
2582    #[doc(hidden)]
2583    pub level: Level,
2584}
2585
2586/// One logging record
2587///
2588/// Corresponds to one logging statement like `info!(...)` and carries all its
2589/// data: eg. message, immediate key-value pairs and key-value pairs of `Logger`
2590/// used to execute it.
2591///
2592/// Record is passed to a `Logger`, which delivers it to its own `Drain`,
2593/// where actual logging processing is implemented.
2594#[must_use = "does nothing by itself"]
2595pub struct Record<'a> {
2596    rstatic: &'a RecordStatic<'a>,
2597    msg: &'a fmt::Arguments<'a>,
2598    kv: BorrowedKV<'a>,
2599}
2600
2601impl<'a> Record<'a> {
2602    /// Create a new `Record`
2603    ///
2604    /// Most of the time, it is slightly more performant to construct a `Record`
2605    /// via the `record!` macro because it enforces that the *entire*
2606    /// `RecordStatic` is built at compile-time.
2607    ///
2608    /// Use this if runtime record creation is a requirement, as is the case with
2609    /// [slog-async](https://docs.rs/slog-async/latest/slog_async/struct.Async.html),
2610    /// for example.
2611    #[inline]
2612    pub fn new(
2613        s: &'a RecordStatic<'a>,
2614        msg: &'a fmt::Arguments<'a>,
2615        kv: BorrowedKV<'a>,
2616    ) -> Self {
2617        Record {
2618            rstatic: s,
2619            msg,
2620            kv,
2621        }
2622    }
2623
2624    /// Get a log record message
2625    pub fn msg(&self) -> &fmt::Arguments<'_> {
2626        self.msg
2627    }
2628
2629    /// Get record logging level
2630    pub fn level(&self) -> Level {
2631        self.rstatic.level
2632    }
2633
2634    /// Get line number
2635    pub fn line(&self) -> u32 {
2636        self.rstatic.location.line
2637    }
2638
2639    /// Get line number
2640    pub fn location(&self) -> &RecordLocation {
2641        self.rstatic.location
2642    }
2643
2644    /// Get error column
2645    pub fn column(&self) -> u32 {
2646        self.rstatic.location.column
2647    }
2648
2649    /// Get file path
2650    pub fn file(&self) -> &'static str {
2651        self.rstatic.location.file
2652    }
2653
2654    /// Get tag
2655    ///
2656    /// Tag is information that can be attached to `Record` that is not meant
2657    /// to be part of the normal key-value pairs, but only as an ad-hoc control
2658    /// flag for quick lookup in the `Drain`s. As such should be used carefully
2659    /// and mostly in application code (as opposed to libraries) - where tag
2660    /// meaning across the system can be coordinated. When used in libraries,
2661    /// make sure to prefix it with something reasonably distinct, like crate
2662    /// name.
2663    pub fn tag(&self) -> &str {
2664        self.rstatic.tag
2665    }
2666
2667    /// Get odule
2668    pub fn module(&self) -> &'static str {
2669        self.rstatic.location.module
2670    }
2671
2672    /// Get function (placeholder)
2673    ///
2674    /// There's currently no way to obtain that information
2675    /// in Rust at compile time, so it is not implemented.
2676    ///
2677    /// It will be implemented at first opportunity, and
2678    /// it will not be considered a breaking change.
2679    pub fn function(&self) -> &'static str {
2680        self.rstatic.location.function
2681    }
2682
2683    /// Get key-value pairs
2684    pub fn kv(&self) -> BorrowedKV<'_> {
2685        BorrowedKV(self.kv.0)
2686    }
2687}
2688// }}}
2689
2690// {{{ Serializer
2691
2692macro_rules! impl_default_as_fmt{
2693    ($(#[$m:meta])* $t:ty => $f:ident) => {
2694        $(#[$m])*
2695        fn $f(&mut self, key : Key, val : $t)
2696            -> Result {
2697                self.emit_arguments(key, &format_args!("{}", val))
2698            }
2699    };
2700}
2701
2702/// This is a workaround to be able to pass &mut Serializer, from
2703/// `Serializer::emit_serde` default implementation. `&Self` can't be casted to
2704/// `&Serializer` (without : Sized, which break object safety), but it can be
2705/// used as <T: Serializer>.
2706#[cfg(feature = "nested-values")]
2707struct SerializerForward<'a, T: ?Sized>(&'a mut T);
2708
2709#[cfg(feature = "nested-values")]
2710impl<'a, T: Serializer + 'a + ?Sized> Serializer for SerializerForward<'a, T> {
2711    fn emit_arguments(&mut self, key: Key, val: &fmt::Arguments<'_>) -> Result {
2712        self.0.emit_arguments(key, val)
2713    }
2714
2715    #[cfg(feature = "nested-values")]
2716    fn emit_serde(&mut self, _key: Key, _value: &dyn SerdeValue) -> Result {
2717        panic!();
2718    }
2719}
2720
2721/// Serializer
2722///
2723/// Drains using `Format` will internally use
2724/// types implementing this trait.
2725pub trait Serializer {
2726    impl_default_as_fmt! {
2727        /// Emit `usize`
2728        usize => emit_usize
2729    }
2730    impl_default_as_fmt! {
2731        /// Emit `isize`
2732        isize => emit_isize
2733    }
2734    impl_default_as_fmt! {
2735        /// Emit `bool`
2736        bool => emit_bool
2737    }
2738    impl_default_as_fmt! {
2739        /// Emit `char`
2740        char => emit_char
2741    }
2742    impl_default_as_fmt! {
2743        /// Emit `u8`
2744        u8 => emit_u8
2745    }
2746    impl_default_as_fmt! {
2747        /// Emit `i8`
2748        i8 => emit_i8
2749    }
2750    impl_default_as_fmt! {
2751        /// Emit `u16`
2752        u16 => emit_u16
2753    }
2754    impl_default_as_fmt! {
2755        /// Emit `i16`
2756        i16 => emit_i16
2757    }
2758    impl_default_as_fmt! {
2759        /// Emit `u32`
2760        u32 => emit_u32
2761    }
2762    impl_default_as_fmt! {
2763        /// Emit `i32`
2764        i32 => emit_i32
2765    }
2766    impl_default_as_fmt! {
2767        /// Emit `f32`
2768        f32 => emit_f32
2769    }
2770    impl_default_as_fmt! {
2771        /// Emit `u64`
2772        u64 => emit_u64
2773    }
2774    impl_default_as_fmt! {
2775        /// Emit `i64`
2776        i64 => emit_i64
2777    }
2778    impl_default_as_fmt! {
2779        /// Emit `f64`
2780        f64 => emit_f64
2781    }
2782    impl_default_as_fmt! {
2783        /// Emit `u128`
2784        u128 => emit_u128
2785    }
2786    impl_default_as_fmt! {
2787        /// Emit `i128`
2788        i128 => emit_i128
2789    }
2790    impl_default_as_fmt! {
2791        /// Emit `&str`
2792        &str => emit_str
2793    }
2794
2795    /// Emit `()`
2796    fn emit_unit(&mut self, key: Key) -> Result {
2797        self.emit_arguments(key, &format_args!("()"))
2798    }
2799
2800    /// Emit `None`
2801    fn emit_none(&mut self, key: Key) -> Result {
2802        self.emit_arguments(key, &format_args!(""))
2803    }
2804
2805    /// Emit bytes
2806    ///
2807    /// Note: this has literally bytes semantics, not array semantics.
2808    /// It is probably most appropriate to display it as hex which is
2809    /// also the default (space-separated).
2810    fn emit_bytes(
2811        &mut self,
2812        key: Key,
2813        bytes: &[u8],
2814        kind: BytesKind,
2815    ) -> Result {
2816        self.emit_arguments(
2817            key,
2818            &format_args!("{}", BytesAsFmt { bytes, kind }),
2819        )
2820    }
2821
2822    /// Emit `fmt::Arguments`
2823    ///
2824    /// This is the only method that has to implemented, but for performance and
2825    /// to retain type information most serious `Serializer`s will want to
2826    /// implement all other methods as well.
2827    fn emit_arguments(&mut self, key: Key, val: &fmt::Arguments<'_>) -> Result;
2828
2829    /// Emit a value implementing
2830    /// [`serde::Serialize`](https://docs.rs/serde/1/serde/trait.Serialize.html)
2831    ///
2832    /// This is especially useful for composite values, eg. structs as Json values, or sequences.
2833    ///
2834    /// To prevent pulling-in `serde` dependency, this is an extension behind a
2835    /// `serde` feature flag.
2836    ///
2837    /// The value needs to implement `SerdeValue`.
2838    #[cfg(feature = "nested-values")]
2839    fn emit_serde(&mut self, key: Key, value: &dyn SerdeValue) -> Result {
2840        value.serialize_fallback(key, &mut SerializerForward(self))
2841    }
2842
2843    /// Emit a type implementing [`std::error::Error`]
2844    ///
2845    /// Error values are a bit special as their `Display` implementation doesn't show full
2846    /// information about the type but must be retrieved using `source()`. This can be used
2847    /// for formatting sources of errors differently.
2848    ///
2849    /// The default implementation of this method formats the sources separated with `: `.
2850    /// Serializers are encouraged to take advantage of the type information and format it as
2851    /// appropriate.
2852    ///
2853    /// This method is available if either the `std` feature is enabled,
2854    /// or if [`core::error::Error`] is supported by the current rust version (1.81+)
2855    #[cfg(has_std_error)]
2856    fn emit_error(
2857        &mut self,
2858        key: Key,
2859        error: &(dyn StdError + 'static),
2860    ) -> Result {
2861        self.emit_arguments(key, &format_args!("{}", ErrorAsFmt(error)))
2862    }
2863}
2864
2865/// Serializer to closure adapter.
2866///
2867/// Formats all arguments as `fmt::Arguments` and passes them to a given closure.
2868struct AsFmtSerializer<F>(pub F)
2869where
2870    F: for<'a> FnMut(Key, fmt::Arguments<'a>) -> Result;
2871
2872impl<F> Serializer for AsFmtSerializer<F>
2873where
2874    F: for<'a> FnMut(Key, fmt::Arguments<'a>) -> Result,
2875{
2876    fn emit_arguments(&mut self, key: Key, val: &fmt::Arguments<'_>) -> Result {
2877        (self.0)(key, *val)
2878    }
2879}
2880
2881/// The kind of bytes to log
2882///
2883/// The main distinction is between bytes as "values" (like checksums)
2884/// or bytes as "streams" (like user input)
2885///
2886/// This changes the default formatting,
2887/// although different `Drain` implementations can handle
2888/// this information differently.
2889#[non_exhaustive]
2890#[derive(Copy, Clone, Debug)]
2891#[must_use = "does nothing by itself"]
2892pub enum BytesKind {
2893    /// Format the bytes as a "stream"
2894    ///
2895    /// By default, this prints as hex bytes prefixed with `0x` (but without underscores).
2896    ///
2897    /// Drain implementations are encouraged to switch to
2898    /// more efficient formats like base64 (or direct binary).
2899    Stream,
2900    /// Format the bytes as a "value"
2901    ///
2902    /// By default, this prints as uppercase hex prefixed with `0x`,
2903    /// implicitly separated by underscores
2904    ///
2905    /// For example, `sha1("foo")` would format as `0xF1D2_D2F9_24E9_86AC_86FD_F7B3_6C94_BCDF_32BE_EC15`
2906    /// Notice the leading `0x` and the underscores.
2907    ///
2908    /// If this leading `0x` and underscores are not desired, consider [BytesKind::PlainValue]
2909    Value,
2910    /// Format the bytes as a "plain" value.
2911    ///
2912    /// This is very similar to [BytesKind::Value],
2913    /// however by default it avoids underscores and a leading `0x`.
2914    ///
2915    /// For example, `sha1("foo")` would format as `F1D2D2F924E986AC86FDF7B36C94BCDF32BEEC15`
2916    /// Notice the lack of leading `0x` and the lack of underscores.
2917    PlainValue,
2918}
2919impl Default for BytesKind {
2920    #[inline]
2921    fn default() -> BytesKind {
2922        BytesKind::Value
2923    }
2924}
2925
2926/// A helper for formatting bytes as hex separated with spaces.
2927///
2928/// This avoids allocation in the default implementation of `Serializer::emit_bytes()`.
2929struct BytesAsFmt<'a> {
2930    bytes: &'a [u8],
2931    kind: BytesKind,
2932}
2933
2934impl fmt::Display for BytesAsFmt<'_> {
2935    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2936        use core::fmt::Write;
2937        let (use_prefix, separate_with_underscore) = match self.kind {
2938            BytesKind::Stream => (true, false),
2939            BytesKind::Value => (true, true),
2940            BytesKind::PlainValue => (false, false),
2941        };
2942        if use_prefix {
2943            f.write_str("0x")?;
2944        }
2945        for (index, byte) in self.bytes.iter().enumerate() {
2946            if separate_with_underscore && (index % 2) == 0 {
2947                f.write_char('_')?;
2948            }
2949            write!(f, "{:02X}", byte)?;
2950        }
2951        Ok(())
2952    }
2953}
2954
2955/// A helper for formatting std::error::Error types by joining sources with `: `
2956///
2957/// This avoids allocation in the default implementation of `Serializer::emit_error()`.
2958/// This is only enabled with `std` as the trait is only available there.
2959#[cfg(has_std_error)]
2960struct ErrorAsFmt<'a>(pub &'a (dyn StdError + 'static));
2961
2962#[cfg(has_std_error)]
2963impl fmt::Display for ErrorAsFmt<'_> {
2964    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2965        // For backwards compatibility
2966        // This is fine because we don't need downcasting
2967        #![allow(deprecated)]
2968        write!(f, "{}", self.0)?;
2969        let mut error = self.0.cause();
2970        while let Some(source) = error {
2971            write!(f, ": {}", source)?;
2972            error = source.cause();
2973        }
2974        Ok(())
2975    }
2976}
2977
2978// }}}
2979
2980// {{{ serde
2981/// A value that can be serialized via serde
2982///
2983/// This is useful for implementing nested values, like sequences or structures.
2984#[cfg(feature = "nested-values")]
2985pub trait SerdeValue: erased_serde::Serialize + Value {
2986    /// Serialize the value in a way that is compatible with `slog::Serializer`s
2987    /// that do not support serde.
2988    ///
2989    /// The implementation should *not* call `slog::Serialize::serialize`
2990    /// on itself, as it will lead to infinite recursion.
2991    ///
2992    /// Default implementation is provided, but it returns error, so use it
2993    /// only for internal types in systems and libraries where `serde` is always
2994    /// enabled.
2995    fn serialize_fallback(
2996        &self,
2997        _key: Key,
2998        _serializer: &mut dyn Serializer,
2999    ) -> Result<()> {
3000        // Use std::io::ErrorKind::Other as a hack to give a custom error,
3001        // without adding another variant to the slog::Error enum
3002        // TODO: Figure out a better way to
3003        #[cfg(feature = "std")]
3004        {
3005            #[derive(Debug)]
3006            struct NestedValuesUnsupportedError {
3007                value_type_name: &'static str,
3008            }
3009            impl fmt::Display for NestedValuesUnsupportedError {
3010                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3011                    write!(f, "Logger does not implement nested-values and {} does not implement serialize_fallback", self.value_type_name)
3012                }
3013            }
3014            impl StdError for NestedValuesUnsupportedError {}
3015            Err(Error::Io(std::io::Error::new(
3016                std::io::ErrorKind::Other,
3017                Box::new(NestedValuesUnsupportedError {
3018                    value_type_name: core::any::type_name::<Self>(),
3019                }),
3020            )))
3021        }
3022        #[cfg(not(feature = "std"))]
3023        {
3024            Err(Error::Other)
3025        }
3026    }
3027
3028    /// Convert to `erased_serialize::Serialize` of the underlying value,
3029    /// so `slog::Serializer`s can use it to serialize via `serde`.
3030    fn as_serde(&self) -> &dyn erased_serde::Serialize;
3031
3032    /// Convert to a boxed value that can be sent across threads
3033    ///
3034    /// This enables functionality like `slog-async` and similar.
3035    fn to_sendable(&self) -> Box<dyn SerdeValue + Send + 'static>;
3036}
3037
3038/// Use to wrap a value that implements [serde::Serialize](serde_core::Serialize) so it's written to
3039/// the log record as an object, rather than a primitive.
3040///
3041/// # Examples
3042/// ```
3043/// # use serde_derive::Serialize;
3044/// # use slog::{info, o, Drain, Logger};
3045///
3046/// #[derive(Clone, Serialize)]
3047/// struct Thing {
3048///     one: String,
3049///     two: String,
3050/// }
3051///
3052/// # fn main() {
3053/// #   let log = Logger::root(slog::Discard, o!());
3054/// #   fn get_thing() -> Thing { Thing{ one: "a".to_string(), two: "b".to_string() } }
3055///
3056///     let thing = get_thing();
3057///
3058///     info!(log, "Got a thing"; "thing" => slog::Serde(thing.clone()));
3059/// # }
3060/// ```
3061#[cfg(feature = "nested-values")]
3062#[derive(Clone)]
3063#[must_use = "must be passed to logger to actually log"]
3064pub struct Serde<T>(pub T)
3065where
3066    T: serde_core::Serialize + Clone + Send + 'static;
3067
3068#[cfg(feature = "nested-values")]
3069impl<T: serde_core::Serialize + Clone + Send + 'static> serde_core::Serialize
3070    for Serde<T>
3071{
3072    #[inline]
3073    fn serialize<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error>
3074    where
3075        S: serde_core::Serializer,
3076    {
3077        serde_core::Serialize::serialize(&self.0, serializer)
3078    }
3079}
3080
3081#[cfg(feature = "nested-values")]
3082impl<T> SerdeValue for Serde<T>
3083where
3084    T: serde_core::Serialize + Clone + Send + 'static,
3085{
3086    fn as_serde(&self) -> &dyn erased_serde::Serialize {
3087        &self.0
3088    }
3089
3090    fn to_sendable(&self) -> Box<dyn SerdeValue + Send + 'static> {
3091        Box::new(self.clone())
3092    }
3093}
3094
3095// }}}
3096
3097// {{{ Value
3098/// Value that can be serialized
3099///
3100/// Types that implement this trait have custom serialization in the
3101/// structured part of the log macros. Without an implementation of `Value` for
3102/// your type you must emit using either the `?` "debug", `#?` "pretty-debug",
3103/// `%` "display", `#%` "alternate display" or [`SerdeValue`](trait.SerdeValue.html)
3104/// (if you have the `nested-values` feature enabled) formatters.
3105///
3106/// # Example
3107///
3108/// ```
3109/// use slog::{Key, Value, Record, Result, Serializer};
3110/// struct MyNewType(i64);
3111///
3112/// impl Value for MyNewType {
3113///     fn serialize(&self, _rec: &Record, key: Key, serializer: &mut dyn Serializer) -> Result {
3114///         serializer.emit_i64(key, self.0)
3115///     }
3116/// }
3117/// ```
3118///
3119/// See also [`KV`](trait.KV.html) for formatting both the key and value.
3120pub trait Value {
3121    /// Serialize self into `Serializer`
3122    ///
3123    /// Structs implementing this trait should generally
3124    /// only call respective methods of `serializer`.
3125    fn serialize(
3126        &self,
3127        record: &Record<'_>,
3128        key: Key,
3129        serializer: &mut dyn Serializer,
3130    ) -> Result;
3131}
3132
3133impl<V> Value for &V
3134where
3135    V: Value + ?Sized,
3136{
3137    fn serialize(
3138        &self,
3139        record: &Record<'_>,
3140        key: Key,
3141        serializer: &mut dyn Serializer,
3142    ) -> Result {
3143        (*self).serialize(record, key, serializer)
3144    }
3145}
3146
3147macro_rules! impl_value_for {
3148    ($t:ty, $f:ident) => {
3149        impl Value for $t {
3150            fn serialize(
3151                &self,
3152                _record: &Record<'_>,
3153                key: Key,
3154                serializer: &mut dyn Serializer,
3155            ) -> Result {
3156                serializer.$f(key, *self)
3157            }
3158        }
3159    };
3160}
3161
3162impl_value_for!(usize, emit_usize);
3163impl_value_for!(isize, emit_isize);
3164impl_value_for!(bool, emit_bool);
3165impl_value_for!(char, emit_char);
3166impl_value_for!(u8, emit_u8);
3167impl_value_for!(i8, emit_i8);
3168impl_value_for!(u16, emit_u16);
3169impl_value_for!(i16, emit_i16);
3170impl_value_for!(u32, emit_u32);
3171impl_value_for!(i32, emit_i32);
3172impl_value_for!(f32, emit_f32);
3173impl_value_for!(u64, emit_u64);
3174impl_value_for!(i64, emit_i64);
3175impl_value_for!(f64, emit_f64);
3176impl_value_for!(u128, emit_u128);
3177impl_value_for!(i128, emit_i128);
3178
3179impl Value for () {
3180    fn serialize(
3181        &self,
3182        _record: &Record<'_>,
3183        key: Key,
3184        serializer: &mut dyn Serializer,
3185    ) -> Result {
3186        serializer.emit_unit(key)
3187    }
3188}
3189
3190impl Value for str {
3191    fn serialize(
3192        &self,
3193        _record: &Record<'_>,
3194        key: Key,
3195        serializer: &mut dyn Serializer,
3196    ) -> Result {
3197        serializer.emit_str(key, self)
3198    }
3199}
3200
3201impl Value for fmt::Arguments<'_> {
3202    fn serialize(
3203        &self,
3204        _record: &Record<'_>,
3205        key: Key,
3206        serializer: &mut dyn Serializer,
3207    ) -> Result {
3208        serializer.emit_arguments(key, self)
3209    }
3210}
3211
3212impl Value for String {
3213    fn serialize(
3214        &self,
3215        _record: &Record<'_>,
3216        key: Key,
3217        serializer: &mut dyn Serializer,
3218    ) -> Result {
3219        serializer.emit_str(key, self.as_str())
3220    }
3221}
3222
3223impl Value for [u8] {
3224    fn serialize(
3225        &self,
3226        _record: &Record<'_>,
3227        key: Key,
3228        serializer: &mut dyn Serializer,
3229    ) -> Result {
3230        serializer.emit_bytes(key, self, BytesKind::Stream)
3231    }
3232}
3233
3234impl Value for Vec<u8> {
3235    fn serialize(
3236        &self,
3237        _record: &Record<'_>,
3238        key: Key,
3239        serializer: &mut dyn Serializer,
3240    ) -> Result {
3241        serializer.emit_bytes(key, self, BytesKind::Stream)
3242    }
3243}
3244
3245impl<T: Value> Value for Option<T> {
3246    fn serialize(
3247        &self,
3248        record: &Record<'_>,
3249        key: Key,
3250        serializer: &mut dyn Serializer,
3251    ) -> Result {
3252        match *self {
3253            Some(ref s) => s.serialize(record, key, serializer),
3254            None => serializer.emit_none(key),
3255        }
3256    }
3257}
3258
3259impl<T> Value for Box<T>
3260where
3261    T: Value + ?Sized,
3262{
3263    fn serialize(
3264        &self,
3265        record: &Record<'_>,
3266        key: Key,
3267        serializer: &mut dyn Serializer,
3268    ) -> Result {
3269        (**self).serialize(record, key, serializer)
3270    }
3271}
3272impl<T> Value for Arc<T>
3273where
3274    T: Value + ?Sized,
3275{
3276    fn serialize(
3277        &self,
3278        record: &Record<'_>,
3279        key: Key,
3280        serializer: &mut dyn Serializer,
3281    ) -> Result {
3282        (**self).serialize(record, key, serializer)
3283    }
3284}
3285
3286impl<T> Value for Rc<T>
3287where
3288    T: Value,
3289{
3290    fn serialize(
3291        &self,
3292        record: &Record<'_>,
3293        key: Key,
3294        serializer: &mut dyn Serializer,
3295    ) -> Result {
3296        (**self).serialize(record, key, serializer)
3297    }
3298}
3299
3300impl<T> Value for core::num::Wrapping<T>
3301where
3302    T: Value,
3303{
3304    fn serialize(
3305        &self,
3306        record: &Record<'_>,
3307        key: Key,
3308        serializer: &mut dyn Serializer,
3309    ) -> Result {
3310        self.0.serialize(record, key, serializer)
3311    }
3312}
3313
3314impl<T> Value for Cow<'_, T>
3315where
3316    T: Value + ToOwned + ?Sized,
3317{
3318    fn serialize(
3319        &self,
3320        record: &Record<'_>,
3321        key: Key,
3322        serializer: &mut dyn Serializer,
3323    ) -> Result {
3324        (**self).serialize(record, key, serializer)
3325    }
3326}
3327
3328#[cfg(feature = "std")]
3329impl Value for std::path::Display<'_> {
3330    fn serialize(
3331        &self,
3332        _record: &Record<'_>,
3333        key: Key,
3334        serializer: &mut dyn Serializer,
3335    ) -> Result {
3336        serializer.emit_arguments(key, &format_args!("{}", *self))
3337    }
3338}
3339
3340#[cfg(feature = "std")]
3341impl Value for std::net::SocketAddr {
3342    fn serialize(
3343        &self,
3344        _record: &Record<'_>,
3345        key: Key,
3346        serializer: &mut dyn Serializer,
3347    ) -> Result {
3348        serializer.emit_arguments(key, &format_args!("{}", self))
3349    }
3350}
3351
3352#[cfg(feature = "std")]
3353impl Value for std::io::Error {
3354    fn serialize(
3355        &self,
3356        _record: &Record<'_>,
3357        key: Key,
3358        serializer: &mut dyn Serializer,
3359    ) -> Result {
3360        serializer.emit_error(key, self)
3361    }
3362}
3363
3364#[cfg(has_std_error)]
3365impl Value for dyn StdError + 'static {
3366    fn serialize(
3367        &self,
3368        _record: &Record<'_>,
3369        key: Key,
3370        serializer: &mut dyn Serializer,
3371    ) -> Result {
3372        serializer.emit_error(key, self)
3373    }
3374}
3375#[cfg(has_std_error)]
3376impl Value for dyn StdError + Send + 'static {
3377    fn serialize(
3378        &self,
3379        _record: &Record<'_>,
3380        key: Key,
3381        serializer: &mut dyn Serializer,
3382    ) -> Result {
3383        serializer.emit_error(key, self)
3384    }
3385}
3386#[cfg(has_std_error)]
3387impl Value for dyn StdError + Send + Sync + 'static {
3388    fn serialize(
3389        &self,
3390        _record: &Record<'_>,
3391        key: Key,
3392        serializer: &mut dyn Serializer,
3393    ) -> Result {
3394        serializer.emit_error(key, self)
3395    }
3396}
3397
3398#[cfg(feature = "anyhow")]
3399impl Value for anyhow::Error {
3400    fn serialize(
3401        &self,
3402        _record: &Record<'_>,
3403        key: Key,
3404        serializer: &mut dyn Serializer,
3405    ) -> Result {
3406        serializer.emit_error(key, self.as_ref())
3407    }
3408}
3409
3410/// Explicit lazy-closure `Value`
3411#[must_use = "must be passed to logger to actually log"]
3412pub struct FnValue<V: Value, F>(pub F)
3413where
3414    F: for<'c, 'd> Fn(&'c Record<'d>) -> V;
3415
3416impl<V: Value, F> Value for FnValue<V, F>
3417where
3418    F: for<'c, 'd> Fn(&'c Record<'d>) -> V,
3419{
3420    fn serialize(
3421        &self,
3422        record: &Record<'_>,
3423        key: Key,
3424        serializer: &mut dyn Serializer,
3425    ) -> Result {
3426        (self.0)(record).serialize(record, key, serializer)
3427    }
3428}
3429
3430#[deprecated(note = "Renamed to `PushFnValueSerializer`")]
3431/// Old name of `PushFnValueSerializer`
3432pub type PushFnSerializer<'a> = PushFnValueSerializer<'a>;
3433
3434/// Handle passed to `PushFnValue` closure
3435///
3436/// It makes sure only one value is serialized, and will automatically emit
3437/// `()` if nothing else was serialized.
3438#[must_use = "must be passed to logger to actually log"]
3439pub struct PushFnValueSerializer<'a> {
3440    record: &'a Record<'a>,
3441    key: Key,
3442    serializer: &'a mut dyn Serializer,
3443    done: bool,
3444}
3445
3446impl PushFnValueSerializer<'_> {
3447    #[deprecated(note = "Renamed to `emit`")]
3448    /// Emit a value
3449    pub fn serialize<'b, S: 'b + Value>(self, s: S) -> Result {
3450        self.emit(s)
3451    }
3452
3453    /// Emit a value
3454    ///
3455    /// This consumes `self` to prevent serializing one value multiple times
3456    pub fn emit<'b, S: 'b + Value>(mut self, s: S) -> Result {
3457        self.done = true;
3458        #[cfg_attr(not(feature = "dynamic-keys"), allow(noop_method_call))]
3459        s.serialize(self.record, self.key.clone(), self.serializer)
3460    }
3461}
3462
3463impl Drop for PushFnValueSerializer<'_> {
3464    fn drop(&mut self) {
3465        if !self.done {
3466            // unfortunately this gives no change to return serialization errors
3467            #[cfg_attr(not(feature = "dynamic-keys"), allow(noop_method_call))]
3468            let _ = self.serializer.emit_unit(self.key.clone());
3469        }
3470    }
3471}
3472
3473/// Lazy `Value` that writes to Serializer
3474///
3475/// It's more ergonomic for closures used as lazy values to return type
3476/// implementing `Serialize`, but sometimes that forces an allocation (eg.
3477/// `String`s)
3478///
3479/// In some cases it might make sense for another closure form to be used - one
3480/// taking a serializer as an argument, which avoids lifetimes / allocation
3481/// issues.
3482///
3483/// Generally this method should be used if it avoids a big allocation of
3484/// `Serialize`-implementing type in performance-critical logging statement.
3485///
3486/// ```
3487/// use slog::{PushFnValue, Logger, Discard};
3488/// // Create a logger with a key-value printing
3489/// // `file:line` string value for every logging statement.
3490/// // `Discard` `Drain` used for brevity.
3491/// let root = Logger::root(Discard, slog::o!(
3492///     "source_location" => PushFnValue(|record , s| {
3493///         s.serialize(
3494///             format_args!(
3495///                 "{}:{}",
3496///                 record.file(),
3497///                 record.line(),
3498///             )
3499///         )
3500///     })
3501/// ));
3502/// ```
3503#[must_use = "must be passed to logger to actually log"]
3504pub struct PushFnValue<F>(pub F)
3505where
3506    F: 'static
3507        + for<'c, 'd> Fn(&'c Record<'d>, PushFnValueSerializer<'c>) -> Result;
3508
3509impl<F> Value for PushFnValue<F>
3510where
3511    F: 'static
3512        + for<'c, 'd> Fn(&'c Record<'d>, PushFnValueSerializer<'c>) -> Result,
3513{
3514    fn serialize(
3515        &self,
3516        record: &Record<'_>,
3517        key: Key,
3518        serializer: &mut dyn Serializer,
3519    ) -> Result {
3520        let ser = PushFnValueSerializer {
3521            record,
3522            key,
3523            serializer,
3524            done: false,
3525        };
3526        (self.0)(record, ser)
3527    }
3528}
3529
3530/// Wrapper for auto-deref specialization for error values and references.
3531///
3532/// See <https://lukaskalbertodt.github.io/2019/12/05/generalized-autoref-based-specialization.html>
3533/// and <https://github.com/dtolnay/case-studies/tree/master/autoref-specialization> for
3534/// details about the technique.
3535///
3536/// This type allows to detect if it received an error reference or value.
3537/// To test the kind of `e`, you have to call it as `(&&ErrorTagWrapper(e)).slog_error_kind()`.
3538/// It will return [`ErrorValueTag`] for values and [`ErrorRefTag`] for references.
3539///
3540/// This is an internal implementation detail of the `kv!` macro and should not
3541/// be used directly.
3542#[cfg(has_std_error)]
3543#[doc(hidden)]
3544pub struct ErrorTagWrapper<E>(E);
3545
3546#[cfg(has_std_error)]
3547#[test]
3548fn test_error_tag_wrapper() {
3549    #[derive(Debug, Clone, Copy)]
3550    struct MyError(&'static str);
3551    impl core::fmt::Display for MyError {
3552        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3553            f.write_str(self.0)
3554        }
3555    }
3556    impl StdError for MyError {}
3557    let e = MyError("everything is on fire");
3558    assert_eq!(
3559        {
3560            #[allow(clippy::needless_borrow)]
3561            // The "needless" borrow is part of the point
3562            (&&ErrorTagWrapper(e)).slog_error_kind()
3563        },
3564        ErrorValueTag
3565    );
3566    let e = &e;
3567    assert_eq!((&&ErrorTagWrapper(e)).slog_error_kind(), ErrorRefTag);
3568}
3569
3570/// Unit struct indicating that the content of `ErrorTagWrapper` was a value.
3571///
3572/// This is an internal implementation detail of the `kv!` macro and should not
3573/// be used directly.
3574#[cfg(has_std_error)]
3575#[doc(hidden)]
3576#[derive(Debug, PartialEq, Eq)]
3577pub struct ErrorValueTag;
3578#[cfg(has_std_error)]
3579impl ErrorValueTag {
3580    /// Create a [`Value`] wrapper for an owned error value.
3581    pub fn wrap<E>(self, e: E) -> ErrorValue<E>
3582    where
3583        E: StdError,
3584    {
3585        ErrorValue(e)
3586    }
3587}
3588
3589/// Auxiliary trait for auto-deref dispatch of owned error values
3590///
3591/// This is an internal implementation detail of the `kv!` macro and should not
3592/// be used directly.
3593#[cfg(has_std_error)]
3594#[doc(hidden)]
3595pub trait ErrorValueKind {
3596    #[inline]
3597    fn slog_error_kind(&self) -> ErrorValueTag {
3598        ErrorValueTag
3599    }
3600}
3601#[cfg(has_std_error)]
3602impl<E: StdError> ErrorValueKind for ErrorTagWrapper<E> {}
3603
3604/// Unit struct indicating that the content of `ErrorTagWrapper` was a reference.
3605///
3606/// This is an internal implementation detail of the `kv!` macro and should not
3607/// be used directly.
3608#[cfg(has_std_error)]
3609#[doc(hidden)]
3610#[derive(Debug, PartialEq, Eq)]
3611pub struct ErrorRefTag;
3612#[cfg(has_std_error)]
3613impl ErrorRefTag {
3614    /// Create a [`Value`] wrapper for an error reference.
3615    pub fn wrap<E>(self, e: &E) -> ErrorRef<'_, E>
3616    where
3617        E: ?Sized + 'static + StdError,
3618    {
3619        ErrorRef(e)
3620    }
3621}
3622
3623/// Auxiliary trait for auto-deref dispatch of error references
3624///
3625/// This is an internal implementation detail of the `kv!` macro and should not
3626/// be used directly.
3627#[cfg(has_std_error)]
3628#[doc(hidden)]
3629pub trait ErrorRefKind {
3630    #[inline]
3631    fn slog_error_kind(self) -> ErrorRefTag
3632    where
3633        Self: Sized,
3634    {
3635        ErrorRefTag
3636    }
3637}
3638#[cfg(has_std_error)]
3639impl<ERef> ErrorRefKind for &&ErrorTagWrapper<ERef>
3640where
3641    ERef: core::ops::Deref,
3642    ERef::Target: StdError,
3643{
3644}
3645
3646/// A wrapper struct for serializing errors
3647///
3648/// This struct can be used to wrap types that don't implement `slog::Value` but
3649/// do implement `std::error::Error` so that they can be logged.
3650/// This is usually not used directly but using `#error` in the macros.
3651///
3652/// This struct is only available in `std` because the `Error` trait is not available
3653/// without `std`.
3654///
3655/// Use [`ErrorRef`] if you have an error reference.
3656#[cfg(has_std_error)]
3657#[must_use = "must be passed to logger to actually log"]
3658pub struct ErrorValue<E: StdError>(pub E);
3659
3660#[cfg(has_std_error)]
3661impl<E> Value for ErrorValue<E>
3662where
3663    E: 'static + StdError,
3664{
3665    fn serialize(
3666        &self,
3667        _record: &Record<'_>,
3668        key: Key,
3669        serializer: &mut dyn Serializer,
3670    ) -> Result {
3671        serializer.emit_error(key, &self.0)
3672    }
3673}
3674
3675/// A wrapper struct for serializing errors references.
3676///
3677/// This struct can be used to wrap types that don't implement `slog::Value` but
3678/// do implement `std::error::Error` so that they can be logged.
3679/// This is usually not used directly but using `#error` in the macros.
3680///
3681/// This struct is available if either `std` or [`core::error::Error`] is.
3682///
3683/// Use [`ErrorValue`] if you want to move ownership of the error value.
3684#[cfg(has_std_error)]
3685#[must_use = "must be passed to logger to actually log"]
3686pub struct ErrorRef<'a, E: ?Sized + StdError>(pub &'a E);
3687
3688#[cfg(has_std_error)]
3689impl<E> Value for ErrorRef<'_, E>
3690where
3691    E: 'static + StdError,
3692{
3693    fn serialize(
3694        &self,
3695        _record: &Record<'_>,
3696        key: Key,
3697        serializer: &mut dyn Serializer,
3698    ) -> Result {
3699        serializer.emit_error(key, self.0)
3700    }
3701}
3702
3703#[cfg(feature = "nested-values")]
3704impl<T> Value for Serde<T>
3705where
3706    T: serde_core::Serialize + Clone + Send + 'static,
3707{
3708    fn serialize(
3709        &self,
3710        _: &Record<'_>,
3711        key: Key,
3712        serializer: &mut dyn Serializer,
3713    ) -> Result {
3714        serializer.emit_serde(key, self)
3715    }
3716}
3717
3718// }}}
3719
3720// {{{ KV
3721/// Key-value pair(s) for log events
3722///
3723/// Zero, one or more key value pairs chained together
3724///
3725/// Any logging data must implement this trait for slog to be able to use it,
3726/// although slog comes with default implementations within its macros (the
3727/// `=>` and `kv!` portions of the log macros).
3728///
3729/// If you don't use this trait, you must emit your structured data by
3730/// specifying both key and value in each log event:
3731///
3732/// ```ignore
3733/// info!(logger, "my event"; "type_key" => %my_val);
3734/// ```
3735///
3736/// If you implement this trait, that can become:
3737///
3738/// ```ignore
3739/// info!(logger, "my event"; my_val);
3740/// ```
3741///
3742/// Types implementing this trait can emit multiple key-value pairs, and can
3743/// customize their structured representation. The order of emitting them
3744/// should be consistent with the way key-value pair hierarchy is traversed:
3745/// from data most specific to the logging context to the most general one. Or
3746/// in other words: from newest to oldest.
3747///
3748/// Implementers are are responsible for calling the `emit_*` methods on the
3749/// `Serializer` passed in, the `Record` can be used to make display decisions
3750/// based on context, but for most plain-value structs you will just call
3751/// `emit_*`.
3752///
3753/// # Example
3754///
3755/// ```
3756/// use slog::{KV, Record, Result, Serializer};
3757///
3758/// struct MyNewType(i64);
3759///
3760/// impl KV for MyNewType {
3761///    fn serialize(&self, _rec: &Record, serializer: &mut dyn Serializer) -> Result {
3762///        serializer.emit_i64("my_new_type".into(), self.0)
3763///    }
3764/// }
3765/// ```
3766///
3767/// See also [`Value`](trait.Value.html), which allows you to customize just
3768/// the right hand side of the `=>` structure macro, and (if you have the
3769/// `nested-values` feature enabled) [`SerdeValue`](trait.SerdeValue.html)
3770/// which allows emitting anything serde can emit.
3771pub trait KV {
3772    /// Serialize self into `Serializer`
3773    ///
3774    /// `KV` should call respective `Serializer` methods
3775    /// for each key-value pair it contains.
3776    fn serialize(
3777        &self,
3778        record: &Record<'_>,
3779        serializer: &mut dyn Serializer,
3780    ) -> Result;
3781}
3782
3783impl<T> KV for &T
3784where
3785    T: KV,
3786{
3787    fn serialize(
3788        &self,
3789        record: &Record<'_>,
3790        serializer: &mut dyn Serializer,
3791    ) -> Result {
3792        (**self).serialize(record, serializer)
3793    }
3794}
3795
3796/// Thread-local safety bound for `KV`
3797///
3798/// This type is used to enforce `KV`s stored in `Logger`s are thread-safe.
3799pub trait SendSyncRefUnwindSafeKV:
3800    KV + maybe::Send + maybe::Sync + maybe::RefUnwindSafe
3801{
3802}
3803
3804impl<T> SendSyncRefUnwindSafeKV for T where
3805    T: KV + maybe::Send + maybe::Sync + maybe::RefUnwindSafe + ?Sized
3806{
3807}
3808
3809/// Single pair `Key` and `Value`
3810#[must_use = "does nothing by itself"]
3811pub struct SingleKV<V>(pub Key, pub V)
3812where
3813    V: Value;
3814
3815#[cfg(feature = "dynamic-keys")]
3816impl<V: Value> From<(String, V)> for SingleKV<V> {
3817    fn from(x: (String, V)) -> SingleKV<V> {
3818        SingleKV(Key::from(x.0), x.1)
3819    }
3820}
3821#[cfg(feature = "dynamic-keys")]
3822impl<V: Value> From<(&'static str, V)> for SingleKV<V> {
3823    fn from(x: (&'static str, V)) -> SingleKV<V> {
3824        SingleKV(Key::from(x.0), x.1)
3825    }
3826}
3827#[cfg(not(feature = "dynamic-keys"))]
3828impl<V: Value> From<(&'static str, V)> for SingleKV<V> {
3829    fn from(x: (&'static str, V)) -> SingleKV<V> {
3830        SingleKV(x.0, x.1)
3831    }
3832}
3833
3834impl<V> KV for SingleKV<V>
3835where
3836    V: Value,
3837{
3838    fn serialize(
3839        &self,
3840        record: &Record<'_>,
3841        serializer: &mut dyn Serializer,
3842    ) -> Result {
3843        #[cfg_attr(not(feature = "dynamic-keys"), allow(noop_method_call))]
3844        self.1.serialize(record, self.0.clone(), serializer)
3845    }
3846}
3847
3848impl KV for () {
3849    fn serialize(
3850        &self,
3851        _record: &Record<'_>,
3852        _serializer: &mut dyn Serializer,
3853    ) -> Result {
3854        Ok(())
3855    }
3856}
3857
3858impl<T: KV, R: KV> KV for (T, R) {
3859    fn serialize(
3860        &self,
3861        record: &Record<'_>,
3862        serializer: &mut dyn Serializer,
3863    ) -> Result {
3864        self.0.serialize(record, serializer)?;
3865        self.1.serialize(record, serializer)
3866    }
3867}
3868
3869impl<T> KV for Box<T>
3870where
3871    T: KV + ?Sized,
3872{
3873    fn serialize(
3874        &self,
3875        record: &Record<'_>,
3876        serializer: &mut dyn Serializer,
3877    ) -> Result {
3878        (**self).serialize(record, serializer)
3879    }
3880}
3881
3882impl<T> KV for Arc<T>
3883where
3884    T: KV + ?Sized,
3885{
3886    fn serialize(
3887        &self,
3888        record: &Record<'_>,
3889        serializer: &mut dyn Serializer,
3890    ) -> Result {
3891        (**self).serialize(record, serializer)
3892    }
3893}
3894
3895impl<T> KV for OwnedKV<T>
3896where
3897    T: SendSyncRefUnwindSafeKV + ?Sized,
3898{
3899    fn serialize(
3900        &self,
3901        record: &Record<'_>,
3902        serializer: &mut dyn Serializer,
3903    ) -> Result {
3904        self.0.serialize(record, serializer)
3905    }
3906}
3907
3908impl KV for BorrowedKV<'_> {
3909    fn serialize(
3910        &self,
3911        record: &Record<'_>,
3912        serializer: &mut dyn Serializer,
3913    ) -> Result {
3914        self.0.serialize(record, serializer)
3915    }
3916}
3917// }}}
3918
3919// {{{ OwnedKV
3920/// Owned KV
3921///
3922/// "Owned" means that the contained data (key-value pairs) can belong
3923/// to a `Logger` and thus must be thread-safe (`'static`, `Send`, `Sync`)
3924///
3925/// Zero, one or more owned key-value pairs.
3926///
3927/// Can be constructed with [`o!` macro](macro.o.html).
3928#[must_use = "does nothing unless attached to logger"]
3929pub struct OwnedKV<T>(
3930    #[doc(hidden)]
3931    /// The exact details of that it are not considered public
3932    /// and stable API. `slog_o` or `o` macro should be used
3933    /// instead to create `OwnedKV` instances.
3934    pub T,
3935)
3936where
3937    T: SendSyncRefUnwindSafeKV + ?Sized;
3938// }}}
3939
3940// {{{ BorrowedKV
3941/// Borrowed `KV`
3942///
3943/// "Borrowed" means that the data is only a temporary
3944/// referenced (`&T`) and can't be stored directly.
3945///
3946/// Zero, one or more borrowed key-value pairs.
3947///
3948/// Can be constructed with [`b!` macro](macro.b.html).
3949#[must_use = "does nothing unless attached to logger"]
3950pub struct BorrowedKV<'a>(
3951    /// The exact details of it function are not
3952    /// considered public and stable API. `log` and other
3953    /// macros should be used instead to create
3954    /// `BorrowedKV` instances.
3955    #[doc(hidden)]
3956    pub &'a dyn KV,
3957);
3958
3959// }}}
3960
3961// {{{ OwnedKVList
3962struct OwnedKVListNode<T>
3963where
3964    T: SendSyncRefUnwindSafeKV + 'static,
3965{
3966    next_node: Arc<dyn SendSyncRefUnwindSafeKV + 'static>,
3967    kv: T,
3968}
3969
3970struct MultiListNode {
3971    next_node: Arc<dyn SendSyncRefUnwindSafeKV + 'static>,
3972    node: Arc<dyn SendSyncRefUnwindSafeKV + 'static>,
3973}
3974
3975/// Chain of `SyncMultiSerialize`-s of a `Logger` and its ancestors
3976#[derive(Clone)]
3977#[must_use = "does nothing unless attached to logger"]
3978pub struct OwnedKVList {
3979    node: Arc<dyn SendSyncRefUnwindSafeKV + 'static>,
3980}
3981
3982impl<T> KV for OwnedKVListNode<T>
3983where
3984    T: SendSyncRefUnwindSafeKV + 'static,
3985{
3986    fn serialize(
3987        &self,
3988        record: &Record<'_>,
3989        serializer: &mut dyn Serializer,
3990    ) -> Result {
3991        self.kv.serialize(record, serializer)?;
3992        self.next_node.serialize(record, serializer)?;
3993
3994        Ok(())
3995    }
3996}
3997
3998impl KV for MultiListNode {
3999    fn serialize(
4000        &self,
4001        record: &Record<'_>,
4002        serializer: &mut dyn Serializer,
4003    ) -> Result {
4004        self.next_node.serialize(record, serializer)?;
4005        self.node.serialize(record, serializer)?;
4006
4007        Ok(())
4008    }
4009}
4010
4011impl KV for OwnedKVList {
4012    fn serialize(
4013        &self,
4014        record: &Record<'_>,
4015        serializer: &mut dyn Serializer,
4016    ) -> Result {
4017        self.node.serialize(record, serializer)?;
4018
4019        Ok(())
4020    }
4021}
4022
4023impl fmt::Debug for OwnedKVList {
4024    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4025        write!(f, "(")?;
4026        let mut i = 0;
4027
4028        {
4029            let mut as_str_ser = AsFmtSerializer(|key, _val| {
4030                if i != 0 {
4031                    write!(f, ", ")?;
4032                }
4033
4034                write!(f, "{}", key)?;
4035                i += 1;
4036                Ok(())
4037            });
4038            let record_static = record_static!(Level::Trace, "");
4039
4040            self.node
4041                .serialize(
4042                    &Record::new(
4043                        &record_static,
4044                        &format_args!(""),
4045                        BorrowedKV(&STATIC_TERMINATOR_UNIT),
4046                    ),
4047                    &mut as_str_ser,
4048                )
4049                .map_err(|_| fmt::Error)?;
4050        }
4051
4052        write!(f, ")")?;
4053        Ok(())
4054    }
4055}
4056
4057impl OwnedKVList {
4058    /// New `OwnedKVList` node without a parent (root)
4059    fn root<T>(values: OwnedKV<T>) -> Self
4060    where
4061        T: SendSyncRefUnwindSafeKV + 'static,
4062    {
4063        OwnedKVList {
4064            node: Arc::new(OwnedKVListNode {
4065                next_node: Arc::new(()),
4066                kv: values.0,
4067            }),
4068        }
4069    }
4070
4071    /// New `OwnedKVList` node with an existing parent
4072    fn new<T>(
4073        values: OwnedKV<T>,
4074        next_node: Arc<dyn SendSyncRefUnwindSafeKV + 'static>,
4075    ) -> Self
4076    where
4077        T: SendSyncRefUnwindSafeKV + 'static,
4078    {
4079        OwnedKVList {
4080            node: Arc::new(OwnedKVListNode {
4081                next_node,
4082                kv: values.0,
4083            }),
4084        }
4085    }
4086}
4087
4088impl<T> convert::From<OwnedKV<T>> for OwnedKVList
4089where
4090    T: SendSyncRefUnwindSafeKV + 'static,
4091{
4092    fn from(from: OwnedKV<T>) -> Self {
4093        OwnedKVList::root(from)
4094    }
4095}
4096// }}}
4097
4098// {{{ Error
4099#[derive(Debug)]
4100/// Serialization Error
4101pub enum Error {
4102    /// `io::Error` (not available in ![no_std] mode)
4103    #[cfg(feature = "std")]
4104    Io(std::io::Error),
4105    /// `fmt::Error`
4106    Fmt(core::fmt::Error),
4107    /// Other error
4108    Other,
4109}
4110
4111/// Serialization `Result`
4112pub type Result<T = ()> = result::Result<T, Error>;
4113
4114#[cfg(feature = "std")]
4115impl From<std::io::Error> for Error {
4116    fn from(err: std::io::Error) -> Error {
4117        Error::Io(err)
4118    }
4119}
4120
4121impl From<core::fmt::Error> for Error {
4122    fn from(_: core::fmt::Error) -> Error {
4123        Error::Other
4124    }
4125}
4126
4127#[cfg(feature = "std")]
4128impl From<Error> for std::io::Error {
4129    fn from(e: Error) -> std::io::Error {
4130        match e {
4131            Error::Io(e) => e,
4132            Error::Fmt(_) => std::io::Error::new(
4133                std::io::ErrorKind::Other,
4134                "formatting error",
4135            ),
4136            Error::Other => {
4137                std::io::Error::new(std::io::ErrorKind::Other, "other error")
4138            }
4139        }
4140    }
4141}
4142
4143#[cfg(has_std_error)]
4144impl StdError for Error {
4145    // Deprecated in Rust 1.42
4146    #[allow(deprecated)]
4147    fn description(&self) -> &str {
4148        match *self {
4149            #[cfg(feature = "std")]
4150            Error::Io(ref e) => e.description(),
4151            Error::Fmt(_) => "formatting error",
4152            Error::Other => "serialization error",
4153        }
4154    }
4155
4156    fn cause(&self) -> Option<&dyn StdError> {
4157        match *self {
4158            #[cfg(feature = "std")]
4159            Error::Io(ref e) => Some(e),
4160            Error::Fmt(ref e) => Some(e),
4161            Error::Other => None,
4162        }
4163    }
4164}
4165
4166impl core::fmt::Display for Error {
4167    fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4168        match *self {
4169            #[cfg(feature = "std")]
4170            Error::Io(ref e) => e.fmt(fmt),
4171            Error::Fmt(ref e) => e.fmt(fmt),
4172            Error::Other => fmt.write_str("Other serialization error"),
4173        }
4174    }
4175}
4176// }}}
4177
4178// {{{ Misc
4179/// This type is here just to abstract away lack of `!` type support in stable rust.
4180///
4181/// It is an alias to [`core::convert::Infallible`],
4182/// which will eventually become an alias itself to `!`.
4183#[doc(hidden)]
4184pub type Never = core::convert::Infallible;
4185
4186/// This is not part of "stable" API
4187#[doc(hidden)]
4188pub static STATIC_TERMINATOR_UNIT: () = ();
4189
4190#[allow(clippy::inline_always)]
4191#[inline(always)]
4192#[doc(hidden)]
4193/// Not an API
4194///
4195/// Generally it's a bad idea to depend on static logging level
4196/// in your code. Use closures to perform operations lazily
4197/// only when logging actually takes place.
4198pub fn __slog_static_max_level() -> FilterLevel {
4199    if !cfg!(debug_assertions) {
4200        if cfg!(feature = "release_max_level_off") {
4201            return FilterLevel::Off;
4202        } else if cfg!(feature = "release_max_level_error") {
4203            return FilterLevel::Error;
4204        } else if cfg!(feature = "release_max_level_warn") {
4205            return FilterLevel::Warning;
4206        } else if cfg!(feature = "release_max_level_info") {
4207            return FilterLevel::Info;
4208        } else if cfg!(feature = "release_max_level_debug") {
4209            return FilterLevel::Debug;
4210        } else if cfg!(feature = "release_max_level_trace") {
4211            return FilterLevel::Trace;
4212        }
4213    }
4214    if cfg!(feature = "max_level_off") {
4215        FilterLevel::Off
4216    } else if cfg!(feature = "max_level_error") {
4217        FilterLevel::Error
4218    } else if cfg!(feature = "max_level_warn") {
4219        FilterLevel::Warning
4220    } else if cfg!(feature = "max_level_info") {
4221        FilterLevel::Info
4222    } else if cfg!(feature = "max_level_debug") {
4223        FilterLevel::Debug
4224    } else if cfg!(feature = "max_level_trace") {
4225        FilterLevel::Trace
4226    } else if !cfg!(debug_assertions) {
4227        FilterLevel::Info
4228    } else {
4229        FilterLevel::Debug
4230    }
4231}
4232
4233// }}}
4234
4235// {{{ Slog v1 Compat
4236#[deprecated(note = "Renamed to `Value`")]
4237/// Compatibility name to ease upgrading from `slog v1`
4238pub type Serialize = dyn Value;
4239
4240#[deprecated(note = "Renamed to `PushFnValue`")]
4241/// Compatibility name to ease upgrading from `slog v1`
4242pub type PushLazy<T> = PushFnValue<T>;
4243
4244#[deprecated(note = "Renamed to `PushFnValueSerializer`")]
4245/// Compatibility name to ease upgrading from `slog v1`
4246pub type ValueSerializer<'a> = PushFnValueSerializer<'a>;
4247
4248#[deprecated(note = "Renamed to `OwnedKVList`")]
4249/// Compatibility name to ease upgrading from `slog v1`
4250pub type OwnedKeyValueList = OwnedKVList;
4251
4252#[deprecated(note = "Content of ser module moved to main namespace")]
4253/// Compatibility name to ease upgrading from `slog v1`
4254pub mod ser {
4255    #[allow(deprecated)]
4256    pub use super::{
4257        OwnedKeyValueList, PushLazy, Serialize, Serializer, ValueSerializer,
4258    };
4259}
4260// }}}
4261
4262// {{{ Test
4263#[cfg(test)]
4264mod tests;
4265
4266// }}}
4267
4268// vim: foldmethod=marker foldmarker={{{,}}}