tracing_indicatif/
util.rs1use std::fmt;
4
5use tracing::field::Visit;
6use tracing_core::Field;
7use tracing_subscriber::field::RecordFields;
8use tracing_subscriber::{
9 field::{MakeVisitor, VisitFmt, VisitOutput},
10 fmt::{format::Writer, FormatFields},
11};
12
13pub struct FilteredFormatFields<Format, Filter> {
16 format: Format,
17 filter: Filter,
18}
19
20impl<'writer, Format, Filter> FilteredFormatFields<Format, Filter>
21where
22 Format: MakeVisitor<Writer<'writer>>,
23 Format::Visitor: VisitFmt + VisitOutput<fmt::Result>,
24 Filter: Clone + Fn(&Field) -> bool,
25{
26 pub fn new(format: Format, filter: Filter) -> Self {
29 Self { format, filter }
30 }
31}
32
33impl<'writer, Format, Filter> FormatFields<'writer> for FilteredFormatFields<Format, Filter>
34where
35 Format: MakeVisitor<Writer<'writer>>,
36 Format::Visitor: VisitFmt + VisitOutput<fmt::Result>,
37 Filter: Clone + Fn(&Field) -> bool,
38{
39 fn format_fields<R: RecordFields>(
40 &self,
41 writer: Writer<'writer>,
42 fields: R,
43 ) -> std::fmt::Result {
44 let mut v =
45 FilteredFormatFieldsVisitor::new(self.format.make_visitor(writer), self.filter.clone());
46 fields.record(&mut v);
47 v.finish()?;
48
49 Ok(())
50 }
51}
52
53struct FilteredFormatFieldsVisitor<Visitor, Filter> {
54 visitor: Visitor,
55 filter: Filter,
56}
57
58impl<Visitor, Filter> FilteredFormatFieldsVisitor<Visitor, Filter> {
59 fn new(visitor: Visitor, filter: Filter) -> Self {
60 Self { visitor, filter }
61 }
62}
63
64impl<Visitor, Filter> Visit for FilteredFormatFieldsVisitor<Visitor, Filter>
65where
66 Visitor: Visit,
67 Filter: Fn(&Field) -> bool,
68{
69 fn record_debug(&mut self, field: &tracing_core::Field, value: &dyn std::fmt::Debug) {
70 if (self.filter)(field) {
71 self.visitor.record_debug(field, value);
72 }
73 }
74
75 fn record_f64(&mut self, field: &tracing_core::Field, value: f64) {
76 if (self.filter)(field) {
77 self.visitor.record_f64(field, value);
78 }
79 }
80
81 fn record_i64(&mut self, field: &tracing_core::Field, value: i64) {
82 if (self.filter)(field) {
83 self.visitor.record_i64(field, value);
84 }
85 }
86
87 fn record_u64(&mut self, field: &tracing_core::Field, value: u64) {
88 if (self.filter)(field) {
89 self.visitor.record_u64(field, value);
90 }
91 }
92
93 fn record_str(&mut self, field: &tracing_core::Field, value: &str) {
94 if (self.filter)(field) {
95 self.visitor.record_str(field, value);
96 }
97 }
98
99 fn record_i128(&mut self, field: &tracing_core::Field, value: i128) {
100 if (self.filter)(field) {
101 self.visitor.record_i128(field, value);
102 }
103 }
104
105 fn record_u128(&mut self, field: &tracing_core::Field, value: u128) {
106 if (self.filter)(field) {
107 self.visitor.record_u128(field, value);
108 }
109 }
110
111 fn record_bool(&mut self, field: &tracing_core::Field, value: bool) {
112 if (self.filter)(field) {
113 self.visitor.record_bool(field, value);
114 }
115 }
116
117 fn record_error(
118 &mut self,
119 field: &tracing_core::Field,
120 value: &(dyn std::error::Error + 'static),
121 ) {
122 if (self.filter)(field) {
123 self.visitor.record_error(field, value);
124 }
125 }
126}
127
128impl<Visitor, Filter> VisitOutput<fmt::Result> for FilteredFormatFieldsVisitor<Visitor, Filter>
129where
130 Visitor: VisitOutput<fmt::Result>,
131 Filter: Fn(&Field) -> bool,
132{
133 fn finish(self) -> fmt::Result {
134 self.visitor.finish()
135 }
136}
137
138impl<Visitor, Filter> VisitFmt for FilteredFormatFieldsVisitor<Visitor, Filter>
139where
140 Visitor: VisitFmt,
141 Filter: Fn(&Field) -> bool,
142{
143 fn writer(&mut self) -> &mut dyn fmt::Write {
144 self.visitor.writer()
145 }
146}