fuchsia_inspect_derive/
inspect.rs1use fuchsia_inspect::{
6 BoolProperty, BytesProperty, DoubleProperty, IntProperty, Node, Property, StringProperty,
7 UintProperty,
8};
9use futures::lock;
10use std::{cell, sync};
11use thiserror::Error;
12
13#[derive(Error, Debug)]
16#[error("could not attach to inspect: {:?}", .msg)]
17pub struct AttachError {
18 msg: String,
19}
20
21impl From<&str> for AttachError {
22 fn from(msg: &str) -> Self {
23 Self { msg: msg.to_string() }
24 }
25}
26
27pub trait Inspect {
37 fn iattach(self, parent: &Node, name: impl AsRef<str>) -> Result<(), AttachError>;
55}
56
57macro_rules! impl_inspect_property {
59 ($prop_name:ident, $prop_name_cap:ident) => {
60 paste::paste! {
61 impl Inspect for &mut [<$prop_name_cap Property>] {
62 fn iattach(self, parent: &Node, name: impl AsRef<str>) -> Result<(), AttachError> {
63 let default = <[<$prop_name_cap Property>] as Property<'_>>::Type::default();
64 *self = parent.[<create_ $prop_name>](name.as_ref(), default);
65 Ok(())
66 }
67 }
68 }
69 };
70}
71
72impl_inspect_property!(uint, Uint);
73impl_inspect_property!(int, Int);
74impl_inspect_property!(double, Double);
75impl_inspect_property!(bool, Bool);
76impl_inspect_property!(string, String);
77impl_inspect_property!(bytes, Bytes);
78
79impl<T> Inspect for &cell::RefCell<T>
82where
83 for<'a> &'a mut T: Inspect,
84{
85 fn iattach(self, parent: &Node, name: impl AsRef<str>) -> Result<(), AttachError> {
86 match self.try_borrow_mut() {
87 Ok(mut inner) => inner.iattach(parent, name),
88 Err(_) => Err("could not get exclusive access to cell::RefCell".into()),
89 }
90 }
91}
92
93impl<T> Inspect for &sync::Mutex<T>
94where
95 for<'a> &'a mut T: Inspect,
96{
97 fn iattach(self, parent: &Node, name: impl AsRef<str>) -> Result<(), AttachError> {
98 match self.try_lock() {
99 Ok(mut inner) => inner.iattach(parent, name),
100 Err(_) => Err("could not get exclusive access to std::sync::Mutex".into()),
101 }
102 }
103}
104
105impl<T> Inspect for &sync::RwLock<T>
106where
107 for<'a> &'a mut T: Inspect,
108{
109 fn iattach(self, parent: &Node, name: impl AsRef<str>) -> Result<(), AttachError> {
110 match self.try_write() {
111 Ok(mut inner) => inner.iattach(parent, name),
112 Err(_) => Err("could not get exclusive access to std::sync::RwLock".into()),
113 }
114 }
115}
116
117impl<T> Inspect for &fuchsia_sync::Mutex<T>
118where
119 for<'a> &'a mut T: Inspect,
120{
121 fn iattach(self, parent: &Node, name: impl AsRef<str>) -> Result<(), AttachError> {
122 match self.try_lock() {
123 Some(mut inner) => inner.iattach(parent, name),
124 None => Err("could not get exclusive access to fuchsia_sync::Mutex".into()),
125 }
126 }
127}
128
129impl<T> Inspect for &fuchsia_sync::RwLock<T>
130where
131 for<'a> &'a mut T: Inspect,
132{
133 fn iattach(self, parent: &Node, name: impl AsRef<str>) -> Result<(), AttachError> {
134 match self.try_write() {
135 Some(mut inner) => inner.iattach(parent, name),
136 None => Err("could not get exclusive access to fuchsia_sync::RwLock".into()),
137 }
138 }
139}
140
141impl<T> Inspect for &lock::Mutex<T>
142where
143 for<'a> &'a mut T: Inspect,
144{
145 fn iattach(self, parent: &Node, name: impl AsRef<str>) -> Result<(), AttachError> {
146 match self.try_lock() {
147 Some(mut inner) => inner.iattach(parent, name),
148 None => Err("could not get exclusive access to futures::lock::Mutex".into()),
149 }
150 }
151}
152
153pub trait WithInspect
158where
159 Self: Sized,
160{
161 fn with_inspect(self, parent: &Node, name: impl AsRef<str>) -> Result<Self, AttachError>;
166}
167
168impl<T> WithInspect for T
169where
170 for<'a> &'a mut T: Inspect,
171{
172 fn with_inspect(mut self, parent: &Node, name: impl AsRef<str>) -> Result<Self, AttachError> {
173 self.iattach(parent, name).map(|()| self)
174 }
175}