From 20431706a863f92cb37dc512fef6e48d192aaf2c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:11:38 +0200 Subject: Merging upstream version 1.66.0+dfsg1. Signed-off-by: Daniel Baumann --- .../src/field/delimited.rs | 184 +++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 vendor/tracing-subscriber-0.3.3/src/field/delimited.rs (limited to 'vendor/tracing-subscriber-0.3.3/src/field/delimited.rs') diff --git a/vendor/tracing-subscriber-0.3.3/src/field/delimited.rs b/vendor/tracing-subscriber-0.3.3/src/field/delimited.rs new file mode 100644 index 000000000..8c78c4b20 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/field/delimited.rs @@ -0,0 +1,184 @@ +//! A `MakeVisitor` wrapper that separates formatted fields with a delimiter. +use super::{MakeVisitor, VisitFmt, VisitOutput}; + +use core::fmt; +use tracing_core::field::{Field, Visit}; + +/// A `MakeVisitor` wrapper that wraps a visitor that writes formatted output so +/// that a delimiter is inserted between writing formatted field values. +#[derive(Debug, Clone)] +pub struct Delimited { + delimiter: D, + inner: V, +} + +/// A visitor wrapper that inserts a delimiter after the wrapped visitor formats +/// a field value. +#[derive(Debug)] +pub struct VisitDelimited { + delimiter: D, + seen: bool, + inner: V, + err: fmt::Result, +} + +// === impl Delimited === + +impl MakeVisitor for Delimited +where + D: AsRef + Clone, + V: MakeVisitor, + V::Visitor: VisitFmt, +{ + type Visitor = VisitDelimited; + fn make_visitor(&self, target: T) -> Self::Visitor { + let inner = self.inner.make_visitor(target); + VisitDelimited::new(self.delimiter.clone(), inner) + } +} + +impl Delimited { + /// Returns a new [`MakeVisitor`] implementation that wraps `inner` so that + /// it will format each visited field separated by the provided `delimiter`. + /// + /// [`MakeVisitor`]: ../trait.MakeVisitor.html + pub fn new(delimiter: D, inner: V) -> Self { + Self { delimiter, inner } + } +} + +// === impl VisitDelimited === + +impl VisitDelimited { + /// Returns a new [`Visit`] implementation that wraps `inner` so that + /// each formatted field is separated by the provided `delimiter`. + /// + /// [`Visit`]: https://docs.rs/tracing-core/0.1.6/tracing_core/field/trait.Visit.html + pub fn new(delimiter: D, inner: V) -> Self { + Self { + delimiter, + inner, + seen: false, + err: Ok(()), + } + } + + fn delimit(&mut self) + where + V: VisitFmt, + D: AsRef, + { + if self.err.is_err() { + return; + } + + if self.seen { + self.err = self.inner.writer().write_str(self.delimiter.as_ref()); + } + + self.seen = true; + } +} + +impl Visit for VisitDelimited +where + V: VisitFmt, + D: AsRef, +{ + fn record_i64(&mut self, field: &Field, value: i64) { + self.delimit(); + self.inner.record_i64(field, value); + } + + fn record_u64(&mut self, field: &Field, value: u64) { + self.delimit(); + self.inner.record_u64(field, value); + } + + fn record_bool(&mut self, field: &Field, value: bool) { + self.delimit(); + self.inner.record_bool(field, value); + } + + fn record_str(&mut self, field: &Field, value: &str) { + self.delimit(); + self.inner.record_str(field, value); + } + + fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { + self.delimit(); + self.inner.record_debug(field, value); + } +} + +impl VisitOutput for VisitDelimited +where + V: VisitFmt, + D: AsRef, +{ + fn finish(self) -> fmt::Result { + self.err?; + self.inner.finish() + } +} + +impl VisitFmt for VisitDelimited +where + V: VisitFmt, + D: AsRef, +{ + fn writer(&mut self) -> &mut dyn fmt::Write { + self.inner.writer() + } +} + +#[cfg(test)] +#[cfg(all(test, feature = "alloc"))] +mod test { + use super::*; + use crate::field::test_util::*; + + #[test] + fn delimited_visitor() { + let mut s = String::new(); + let visitor = DebugVisitor::new(&mut s); + let mut visitor = VisitDelimited::new(", ", visitor); + + TestAttrs1::with(|attrs| attrs.record(&mut visitor)); + visitor.finish().unwrap(); + + assert_eq!( + s.as_str(), + "question=\"life, the universe, and everything\", tricky=true, can_you_do_it=true" + ); + } + + #[test] + fn delimited_new_visitor() { + let make = Delimited::new("; ", MakeDebug); + + TestAttrs1::with(|attrs| { + let mut s = String::new(); + { + let mut v = make.make_visitor(&mut s); + attrs.record(&mut v); + } + assert_eq!( + s.as_str(), + "question=\"life, the universe, and everything\"; tricky=true; can_you_do_it=true" + ); + }); + + TestAttrs2::with(|attrs| { + let mut s = String::new(); + { + let mut v = make.make_visitor(&mut s); + attrs.record(&mut v); + } + assert_eq!( + s.as_str(), + "question=None; question.answer=42; tricky=true; can_you_do_it=false" + ); + }); + } +} -- cgit v1.2.3