1 //! `MakeVisitor` wrappers for working with `fmt::Debug` fields. 2 use super::{MakeVisitor, VisitFmt, VisitOutput}; 3 use tracing_core::field::{Field, Visit}; 4 5 use core::fmt; 6 7 /// A visitor wrapper that ensures any `fmt::Debug` fields are formatted using 8 /// the alternate (`:#`) formatter. 9 #[derive(Debug, Clone)] 10 pub struct Alt<V>(V); 11 12 // TODO(eliza): When `error` as a primitive type is stable, add a 13 // `DisplayErrors` wrapper... 14 15 // === impl Alt === 16 // 17 impl<V> Alt<V> { 18 /// Wraps the provided visitor so that any `fmt::Debug` fields are formatted 19 /// using the alternative (`:#`) formatter. new(inner: V) -> Self20 pub fn new(inner: V) -> Self { 21 Alt(inner) 22 } 23 } 24 25 impl<T, V> MakeVisitor<T> for Alt<V> 26 where 27 V: MakeVisitor<T>, 28 { 29 type Visitor = Alt<V::Visitor>; 30 31 #[inline] make_visitor(&self, target: T) -> Self::Visitor32 fn make_visitor(&self, target: T) -> Self::Visitor { 33 Alt(self.0.make_visitor(target)) 34 } 35 } 36 37 impl<V> Visit for Alt<V> 38 where 39 V: Visit, 40 { 41 #[inline] record_f64(&mut self, field: &Field, value: f64)42 fn record_f64(&mut self, field: &Field, value: f64) { 43 self.0.record_f64(field, value) 44 } 45 46 #[inline] record_i64(&mut self, field: &Field, value: i64)47 fn record_i64(&mut self, field: &Field, value: i64) { 48 self.0.record_i64(field, value) 49 } 50 51 #[inline] record_u64(&mut self, field: &Field, value: u64)52 fn record_u64(&mut self, field: &Field, value: u64) { 53 self.0.record_u64(field, value) 54 } 55 56 #[inline] record_bool(&mut self, field: &Field, value: bool)57 fn record_bool(&mut self, field: &Field, value: bool) { 58 self.0.record_bool(field, value) 59 } 60 61 /// Visit a string value. record_str(&mut self, field: &Field, value: &str)62 fn record_str(&mut self, field: &Field, value: &str) { 63 self.0.record_str(field, value) 64 } 65 66 // TODO(eliza): add RecordError when stable 67 // fn record_error(&mut self, field: &Field, value: &(dyn std::error::Error + 'static)) { 68 // self.record_debug(field, &format_args!("{}", value)) 69 // } 70 71 #[inline] record_debug(&mut self, field: &Field, value: &dyn fmt::Debug)72 fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { 73 self.0.record_debug(field, &format_args!("{:#?}", value)) 74 } 75 } 76 77 impl<V, O> VisitOutput<O> for Alt<V> 78 where 79 V: VisitOutput<O>, 80 { 81 #[inline] finish(self) -> O82 fn finish(self) -> O { 83 self.0.finish() 84 } 85 } 86 87 feature! { 88 #![feature = "std"] 89 use super::VisitWrite; 90 use std::io; 91 92 impl<V> VisitWrite for Alt<V> 93 where 94 V: VisitWrite, 95 { 96 #[inline] 97 fn writer(&mut self) -> &mut dyn io::Write { 98 self.0.writer() 99 } 100 } 101 } 102 103 impl<V> VisitFmt for Alt<V> 104 where 105 V: VisitFmt, 106 { 107 #[inline] writer(&mut self) -> &mut dyn fmt::Write108 fn writer(&mut self) -> &mut dyn fmt::Write { 109 self.0.writer() 110 } 111 } 112