diagnostics_traits/
fuchsia.rs
1use alloc::format;
6use alloc::string::String;
7use core::fmt::Display;
8use core::marker::PhantomData;
9
10use fuchsia_async as fasync;
11use fuchsia_inspect::Node;
12use log::warn;
13
14use crate::{InspectableInstant, Inspector, InspectorDeviceExt, InstantPropertyName};
15
16pub trait InspectorDeviceIdProvider<DeviceId> {
18 fn device_id(id: &DeviceId) -> u64;
20}
21
22pub struct FuchsiaInspector<'a, D> {
24 node: &'a Node,
25 unnamed_count: usize,
26 _marker: PhantomData<D>,
27}
28
29impl<'a, D> FuchsiaInspector<'a, D> {
30 pub fn new(node: &'a Node) -> Self {
32 Self { node, unnamed_count: 0, _marker: Default::default() }
33 }
34}
35
36impl<'a, D> Inspector for FuchsiaInspector<'a, D> {
37 type ChildInspector<'l> = FuchsiaInspector<'l, D>;
38
39 fn record_child<F: FnOnce(&mut Self::ChildInspector<'_>)>(&mut self, name: &str, f: F) {
40 self.node.record_child(name, |node| f(&mut FuchsiaInspector::new(node)))
41 }
42
43 fn record_unnamed_child<F: FnOnce(&mut Self::ChildInspector<'_>)>(&mut self, f: F) {
44 let Self { node: _, unnamed_count, _marker: _ } = self;
45 let id = core::mem::replace(unnamed_count, *unnamed_count + 1);
46 self.record_child(&format!("{id}"), f)
47 }
48
49 fn record_usize<T: Into<usize>>(&mut self, name: &str, value: T) {
50 let value: u64 = value.into().try_into().unwrap_or_else(|e| {
51 warn!("failed to inspect usize value that does not fit in a u64: {e:?}");
52 u64::MAX
53 });
54 self.node.record_uint(name, value)
55 }
56
57 fn record_uint<T: Into<u64>>(&mut self, name: &str, value: T) {
58 self.node.record_uint(name, value.into())
59 }
60
61 fn record_int<T: Into<i64>>(&mut self, name: &str, value: T) {
62 self.node.record_int(name, value.into())
63 }
64
65 fn record_double<T: Into<f64>>(&mut self, name: &str, value: T) {
66 self.node.record_double(name, value.into())
67 }
68
69 fn record_str(&mut self, name: &str, value: &str) {
70 self.node.record_string(name, value)
71 }
72
73 fn record_string(&mut self, name: &str, value: String) {
74 self.node.record_string(name, value)
75 }
76
77 fn record_bool(&mut self, name: &str, value: bool) {
78 self.node.record_bool(name, value)
79 }
80}
81
82impl<'a, D, P: InspectorDeviceIdProvider<D>> InspectorDeviceExt<D> for FuchsiaInspector<'a, P> {
83 fn record_device<I: Inspector>(inspector: &mut I, name: &str, device: &D) {
84 inspector.record_uint(name, P::device_id(device))
85 }
86
87 fn device_identifier_as_address_zone(id: D) -> impl Display {
88 P::device_id(&id)
89 }
90}
91
92impl InspectableInstant for fasync::MonotonicInstant {
93 fn record<I: Inspector>(&self, name: InstantPropertyName, inspector: &mut I) {
94 inspector.record_int(name.into(), self.into_nanos());
95 }
96}