1 | //! WARNING: this is not part of the crate's public API and is subject to change at any time |
2 | |
3 | use self::sealed::KVs; |
4 | use crate::{Level, Metadata, Record}; |
5 | use std::fmt::Arguments; |
6 | pub use std::{file, format_args, line, module_path, stringify}; |
7 | |
8 | #[cfg (not(feature = "kv" ))] |
9 | pub type Value<'a> = &'a str; |
10 | |
11 | mod sealed { |
12 | /// Types for the `kv` argument. |
13 | pub trait KVs<'a> { |
14 | fn into_kvs(self) -> Option<&'a [(&'a str, super::Value<'a>)]>; |
15 | } |
16 | } |
17 | |
18 | // Types for the `kv` argument. |
19 | |
20 | impl<'a> KVs<'a> for &'a [(&'a str, Value<'a>)] { |
21 | #[inline ] |
22 | fn into_kvs(self) -> Option<&'a [(&'a str, Value<'a>)]> { |
23 | Some(self) |
24 | } |
25 | } |
26 | |
27 | impl<'a> KVs<'a> for () { |
28 | #[inline ] |
29 | fn into_kvs(self) -> Option<&'a [(&'a str, Value<'a>)]> { |
30 | None |
31 | } |
32 | } |
33 | |
34 | // Log implementation. |
35 | |
36 | fn log_impl( |
37 | args: Arguments, |
38 | level: Level, |
39 | &(target: &str, module_path: &str, file: &str): &(&str, &'static str, &'static str), |
40 | line: u32, |
41 | kvs: Option<&[(&str, Value)]>, |
42 | ) { |
43 | #[cfg (not(feature = "kv" ))] |
44 | if kvs.is_some() { |
45 | panic!("key-value support is experimental and must be enabled using the `kv` feature" ) |
46 | } |
47 | |
48 | let mut builder: RecordBuilder<'_> = Record::builder(); |
49 | |
50 | builder&mut RecordBuilder<'_> |
51 | .args(args) |
52 | .level(level) |
53 | .target(target) |
54 | .module_path_static(Some(module_path)) |
55 | .file_static(file:Some(file)) |
56 | .line(Some(line)); |
57 | |
58 | #[cfg (feature = "kv" )] |
59 | builder.key_values(&kvs); |
60 | |
61 | crate::logger().log(&builder.build()); |
62 | } |
63 | |
64 | pub fn log<'a, K>( |
65 | args: Arguments, |
66 | level: Level, |
67 | target_module_path_and_file: &(&str, &'static str, &'static str), |
68 | line: u32, |
69 | kvs: K, |
70 | ) where |
71 | K: KVs<'a>, |
72 | { |
73 | log_impl( |
74 | args, |
75 | level, |
76 | target_module_path_and_file, |
77 | line, |
78 | kvs.into_kvs(), |
79 | ) |
80 | } |
81 | |
82 | pub fn enabled(level: Level, target: &str) -> bool { |
83 | crate::logger().enabled(&Metadata::builder().level(arg:level).target(target).build()) |
84 | } |
85 | |
86 | #[cfg (feature = "kv" )] |
87 | mod kv_support { |
88 | use crate::kv; |
89 | |
90 | pub type Value<'a> = kv::Value<'a>; |
91 | |
92 | // NOTE: Many functions here accept a double reference &&V |
93 | // This is so V itself can be ?Sized, while still letting us |
94 | // erase it to some dyn Trait (because &T is sized) |
95 | |
96 | pub fn capture_to_value<'a, V: kv::ToValue + ?Sized>(v: &'a &'a V) -> Value<'a> { |
97 | v.to_value() |
98 | } |
99 | |
100 | pub fn capture_debug<'a, V: core::fmt::Debug + ?Sized>(v: &'a &'a V) -> Value<'a> { |
101 | Value::from_debug(v) |
102 | } |
103 | |
104 | pub fn capture_display<'a, V: core::fmt::Display + ?Sized>(v: &'a &'a V) -> Value<'a> { |
105 | Value::from_display(v) |
106 | } |
107 | |
108 | #[cfg (feature = "kv_std" )] |
109 | pub fn capture_error<'a>(v: &'a (dyn std::error::Error + 'static)) -> Value<'a> { |
110 | Value::from_dyn_error(v) |
111 | } |
112 | |
113 | #[cfg (feature = "kv_sval" )] |
114 | pub fn capture_sval<'a, V: sval::Value + ?Sized>(v: &'a &'a V) -> Value<'a> { |
115 | Value::from_sval(v) |
116 | } |
117 | |
118 | #[cfg (feature = "kv_serde" )] |
119 | pub fn capture_serde<'a, V: serde::Serialize + ?Sized>(v: &'a &'a V) -> Value<'a> { |
120 | Value::from_serde(v) |
121 | } |
122 | } |
123 | |
124 | #[cfg (feature = "kv" )] |
125 | pub use self::kv_support::*; |
126 | |