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