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    // start: Instant,
17    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            // start: Instant::now(),
24            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}