Skip to main content

log/
__private_api.rs

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