Skip to content

Commit

Permalink
FullFormatter outputs key-values
Browse files Browse the repository at this point in the history
  • Loading branch information
SpriteOvO committed Nov 24, 2024
1 parent 846e917 commit 02ab539
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 9 deletions.
26 changes: 23 additions & 3 deletions spdlog/src/formatter/full_formatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,22 @@ impl FullFormatter {
dest.write_str("] ")?;
dest.write_str(record.payload())?;

let kvs = record.key_values();
if !kvs.is_empty() {
dest.write_str(" { ")?;

let mut iter = kvs.peekable();
while let Some((key, value)) = iter.next() {
dest.write_str(key.as_str())?;
dest.write_str("=")?;
write!(dest, "{}", value)?;
if iter.peek().is_some() {
dest.write_str(", ")?;
}
}
dest.write_str(" }")?;
}

if self.with_eol {
dest.write_str(__EOL)?;
}
Expand Down Expand Up @@ -126,11 +142,15 @@ mod tests {
use chrono::prelude::*;

use super::*;
use crate::{Level, __EOL};
use crate::{kv, Level, __EOL};

#[test]
fn format() {
let record = Record::new(Level::Warn, "test log content", None, None, &[]);
let kvs = [
(kv::Key::__from_static_str("k1"), kv::Value::from(114)),
(kv::Key::__from_static_str("k2"), kv::Value::from("514")),
];
let record = Record::new(Level::Warn, "test log content", None, None, &kvs);
let mut buf = StringBuf::new();
let mut ctx = FormatterContext::new();
FullFormatter::new()
Expand All @@ -140,7 +160,7 @@ mod tests {
let local_time: DateTime<Local> = record.time().into();
assert_eq!(
format!(
"[{}] [warn] test log content{}",
"[{}] [warn] test log content {{ k1=114, k2=514 }}{}",
local_time.format("%Y-%m-%d %H:%M:%S.%3f"),
__EOL
),
Expand Down
55 changes: 54 additions & 1 deletion spdlog/src/kv.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::borrow::Cow;
use std::{borrow::Cow, marker::PhantomData};

use value_bag::{OwnedValueBag, ValueBag};

Expand All @@ -14,6 +14,15 @@ pub(crate) enum KeyInner<'a> {
#[derive(Debug, Clone)]
pub struct Key<'a>(KeyInner<'a>);

impl<'a> Key<'a> {
pub fn as_str(&self) -> &str {
match &self.0 {
KeyInner::Str(s) => s,
KeyInner::StaticStr(s) => s,
}
}
}

impl<'a> Key<'a> {
#[doc(hidden)]
pub fn __from_static_str(key: &'static str) -> Self {
Expand Down Expand Up @@ -61,6 +70,50 @@ impl KeyOwned {
pub type Value<'a> = ValueBag<'a>;
pub(crate) type ValueOwned = OwnedValueBag;

pub struct KeyValuesIter<'a, I> {
iter: I,
len: usize,
phantom: PhantomData<&'a ()>,
}

impl<I> KeyValuesIter<'_, I> {
pub fn len(&self) -> usize {
self.len
}

pub fn is_empty(&self) -> bool {
self.len == 0
}
}

impl<'a, I> KeyValuesIter<'a, I>
where
I: Iterator<Item = (Key<'a>, Value<'a>)>,
{
pub(crate) fn new(iter: I, len: usize) -> Self {
Self {
iter,
len,
phantom: PhantomData,
}
}
}

impl<'a, I> Iterator for KeyValuesIter<'a, I>
where
I: Iterator<Item = (Key<'a>, Value<'a>)>,
{
type Item = I::Item;

fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}

fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}

pub(crate) type Pair<'a> = (Key<'a>, Value<'a>);

#[cfg(feature = "log")]
Expand Down
16 changes: 11 additions & 5 deletions spdlog/src/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,12 @@ impl<'a> Record<'a> {
}

#[must_use]
pub fn key_values(&self) -> impl IntoIterator<Item = (kv::Key, kv::Value)> {
// The 2 clones should be cheap
self.kvs.iter().map(|(k, v)| (k.clone(), v.clone()))
pub fn key_values(&self) -> kv::KeyValuesIter<impl Iterator<Item = (kv::Key, kv::Value)>> {
kv::KeyValuesIter::new(
// The 2 clones should be cheap
self.kvs.iter().map(|(k, v)| (k.clone(), v.clone())),
self.kvs.len(),
)
}

// When adding more getters, also add to `RecordOwned`
Expand Down Expand Up @@ -239,8 +242,11 @@ impl RecordOwned {
}

#[must_use]
pub fn key_values(&self) -> impl IntoIterator<Item = (kv::Key, kv::Value)> {
self.kvs.iter().map(|(k, v)| (k.as_ref(), v.by_ref()))
pub fn key_values(&self) -> kv::KeyValuesIter<impl Iterator<Item = (kv::Key, kv::Value)>> {
kv::KeyValuesIter::new(
self.kvs.iter().map(|(k, v)| (k.as_ref(), v.by_ref())),
self.kvs.len(),
)
}

// When adding more getters, also add to `Record`
Expand Down

0 comments on commit 02ab539

Please sign in to comment.