1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
use std::io::{self, Write};
#[cfg(feature = "color")]
use super::WriteStyle;
use super::{Formatter, StyledValue};
#[cfg(feature = "color")]
use anstyle::Style;
use log::kv::{Error, Key, Source, Value, VisitSource};
/// Format function for serializing key/value pairs
///
/// This function determines how key/value pairs for structured logs are serialized within the default
/// format.
pub(crate) type KvFormatFn = dyn Fn(&mut Formatter, &dyn Source) -> io::Result<()> + Sync + Send;
/// Null Key Value Format
///
/// This function is intended to be passed to
/// [`Builder::format_key_values`](crate::Builder::format_key_values).
///
/// This key value format simply ignores any key/value fields and doesn't include them in the
/// output.
pub fn hidden_kv_format(_formatter: &mut Formatter, _fields: &dyn Source) -> io::Result<()> {
Ok(())
}
/// Default Key Value Format
///
/// This function is intended to be passed to
/// [`Builder::format_key_values`](crate::Builder::format_key_values).
///
/// This is the default key/value format. Which uses an "=" as the separator between the key and
/// value and a " " between each pair.
///
/// For example: `ip=127.0.0.1 port=123456 path=/example`
pub fn default_kv_format(formatter: &mut Formatter, fields: &dyn Source) -> io::Result<()> {
fields
.visit(&mut DefaultVisitSource(formatter))
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))
}
struct DefaultVisitSource<'a>(&'a mut Formatter);
impl<'a, 'kvs> VisitSource<'kvs> for DefaultVisitSource<'a> {
fn visit_pair(&mut self, key: Key, value: Value<'kvs>) -> Result<(), Error> {
write!(self.0, " {}={}", self.style_key(key), value)?;
Ok(())
}
}
impl DefaultVisitSource<'_> {
fn style_key<'k>(&self, text: Key<'k>) -> StyledValue<Key<'k>> {
#[cfg(feature = "color")]
{
StyledValue {
style: if self.0.write_style == WriteStyle::Never {
Style::new()
} else {
Style::new().italic()
},
value: text,
}
}
#[cfg(not(feature = "color"))]
{
text
}
}
}