rocket/trace/subscriber/
visit.rs
1use std::fmt;
2
3use tinyvec::TinyVec;
4use tracing::field::{Field, Visit};
5use tracing_subscriber::field::RecordFields;
6
7use crate::util::Formatter;
8
9pub trait RecordDisplay: RecordFields {
10 fn find_map_display<T, F: Fn(&dyn fmt::Display) -> T>(&self, name: &str, f: F) -> Option<T>;
11 fn record_display<F: FnMut(&Field, &dyn fmt::Display)>(&self, f: F);
12}
13
14#[derive(Debug)]
15pub struct Data {
16 map: TinyVec<[(&'static str, String); 3]>,
18}
19
20impl Data {
21 pub fn new<T: RecordFields>(attrs: T) -> Self {
22 let mut data = Data {
23 map: TinyVec::new(),
25 };
26
27 attrs.record(&mut data);
28 data
29 }
30
31 pub fn get(&self, key: &str) -> Option<&str> {
32 self.map.iter()
33 .find(|(k, _)| k == &key)
34 .map(|(_, v)| v.as_str())
35 }
36}
37
38impl std::ops::Index<&str> for Data {
39 type Output = str;
40
41 fn index(&self, index: &str) -> &Self::Output {
42 self.get(index).unwrap_or("[internal error: missing key]")
43 }
44}
45
46impl Visit for Data {
47 fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
48 self.map.push((field.name(), format!("{:?}", value)));
49 }
50
51 fn record_str(&mut self, field: &Field, value: &str) {
52 self.map.push((field.name(), value.into()));
53 }
54}
55
56impl<T: RecordFields> RecordDisplay for T {
57 fn find_map_display<V, F: Fn(&dyn fmt::Display) -> V>(&self, name: &str, f: F) -> Option<V> {
58 let mut value = None;
59 self.record_display(|field, item| if field.name() == name { value = Some(f(item)); });
60 value
61 }
62
63 fn record_display<F: FnMut(&Field, &dyn fmt::Display)>(&self, f: F) {
64 struct DisplayVisit<F>(F);
65
66 impl<F: FnMut(&Field, &dyn fmt::Display)> Visit for DisplayVisit<F> {
67 fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
68 (self.0)(field, &Formatter(|f| value.fmt(f)));
69 }
70
71 fn record_str(&mut self, field: &Field, value: &str) {
72 (self.0)(field, &value)
73 }
74 }
75
76 self.record(&mut DisplayVisit(f));
77 }
78}