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