1 //! A `MakeVisitor` wrapper that separates formatted fields with a delimiter.
2 use super::{MakeVisitor, VisitFmt, VisitOutput}
;
5 use tracing_core
::field
::{Field, Visit}
;
7 /// A `MakeVisitor` wrapper that wraps a visitor that writes formatted output so
8 /// that a delimiter is inserted between writing formatted field values.
9 #[derive(Debug, Clone)]
10 pub struct Delimited
<D
, V
> {
15 /// A visitor wrapper that inserts a delimiter after the wrapped visitor formats
18 pub struct VisitDelimited
<D
, V
> {
25 // === impl Delimited ===
27 impl<D
, V
, T
> MakeVisitor
<T
> for Delimited
<D
, V
>
29 D
: AsRef
<str> + Clone
,
33 type Visitor
= VisitDelimited
<D
, V
::Visitor
>;
34 fn make_visitor(&self, target
: T
) -> Self::Visitor
{
35 let inner
= self.inner
.make_visitor(target
);
36 VisitDelimited
::new(self.delimiter
.clone(), inner
)
40 impl<D
, V
> Delimited
<D
, V
> {
41 /// Returns a new [`MakeVisitor`] implementation that wraps `inner` so that
42 /// it will format each visited field separated by the provided `delimiter`.
44 /// [`MakeVisitor`]: ../trait.MakeVisitor.html
45 pub fn new(delimiter
: D
, inner
: V
) -> Self {
46 Self { delimiter, inner }
50 // === impl VisitDelimited ===
52 impl<D
, V
> VisitDelimited
<D
, V
> {
53 /// Returns a new [`Visit`] implementation that wraps `inner` so that
54 /// each formatted field is separated by the provided `delimiter`.
56 /// [`Visit`]: https://docs.rs/tracing-core/0.1.6/tracing_core/field/trait.Visit.html
57 pub fn new(delimiter
: D
, inner
: V
) -> Self {
71 if self.err
.is_err() {
76 self.err
= self.inner
.writer().write_str(self.delimiter
.as_ref());
83 impl<D
, V
> Visit
for VisitDelimited
<D
, V
>
88 fn record_i64(&mut self, field
: &Field
, value
: i64) {
90 self.inner
.record_i64(field
, value
);
93 fn record_u64(&mut self, field
: &Field
, value
: u64) {
95 self.inner
.record_u64(field
, value
);
98 fn record_bool(&mut self, field
: &Field
, value
: bool
) {
100 self.inner
.record_bool(field
, value
);
103 fn record_str(&mut self, field
: &Field
, value
: &str) {
105 self.inner
.record_str(field
, value
);
108 fn record_debug(&mut self, field
: &Field
, value
: &dyn fmt
::Debug
) {
110 self.inner
.record_debug(field
, value
);
114 impl<D
, V
> VisitOutput
<fmt
::Result
> for VisitDelimited
<D
, V
>
119 fn finish(self) -> fmt
::Result
{
125 impl<D
, V
> VisitFmt
for VisitDelimited
<D
, V
>
130 fn writer(&mut self) -> &mut dyn fmt
::Write
{
136 #[cfg(all(test, feature = "alloc"))]
139 use crate::field
::test_util
::*;
142 fn delimited_visitor() {
143 let mut s
= String
::new();
144 let visitor
= DebugVisitor
::new(&mut s
);
145 let mut visitor
= VisitDelimited
::new(", ", visitor
);
147 TestAttrs1
::with(|attrs
| attrs
.record(&mut visitor
));
148 visitor
.finish().unwrap();
152 "question=\"life, the universe, and everything\", tricky=true, can_you_do_it=true"
157 fn delimited_new_visitor() {
158 let make
= Delimited
::new("; ", MakeDebug
);
160 TestAttrs1
::with(|attrs
| {
161 let mut s
= String
::new();
163 let mut v
= make
.make_visitor(&mut s
);
164 attrs
.record(&mut v
);
168 "question=\"life, the universe, and everything\"; tricky=true; can_you_do_it=true"
172 TestAttrs2
::with(|attrs
| {
173 let mut s
= String
::new();
175 let mut v
= make
.make_visitor(&mut s
);
176 attrs
.record(&mut v
);
180 "question=None; question.answer=42; tricky=true; can_you_do_it=false"