settings_inspect_utils/
managed_inspect_map.rs1use fuchsia_inspect::Node;
6use fuchsia_inspect_derive::{AttachError, Inspect, WithInspect};
7use std::collections::HashMap;
8
9#[derive(Default)]
15pub struct ManagedInspectMap<V> {
16 map: HashMap<String, V>,
17 node: Node,
18}
19
20impl<V> ManagedInspectMap<V>
21where
22 for<'a> &'a mut V: Inspect,
23{
24 pub fn with_node(node: Node) -> Self {
26 Self { map: HashMap::new(), node }
27 }
28
29 pub fn map(&self) -> &HashMap<String, V> {
32 &self.map
33 }
34
35 pub fn map_mut(&mut self) -> &mut HashMap<String, V> {
38 &mut self.map
39 }
40
41 pub fn insert(&mut self, key: String, value: V) -> Option<V> {
44 let value_with_inspect =
46 value.with_inspect(&self.node, &key).expect("Failed to attach new map entry");
47 self.map.insert(key, value_with_inspect)
48 }
49
50 pub fn insert_with_property_name(
56 &mut self,
57 map_key: String,
58 property_name: String,
59 value: V,
60 ) -> Option<V> {
61 let value_with_inspect =
63 value.with_inspect(&self.node, property_name).expect("Failed to attach new map entry");
64 self.map.insert(map_key, value_with_inspect)
65 }
66
67 pub fn get_or_insert_with(&mut self, key: String, value: impl FnOnce() -> V) -> &mut V {
69 let node = &self.node;
70 self.map.entry(key.clone()).or_insert_with(|| {
71 value().with_inspect(node, &key).expect("Failed to attach new map entry")
73 })
74 }
75
76 pub fn get_mut(&mut self, key: &str) -> Option<&mut V> {
78 self.map.get_mut(key)
79 }
80
81 pub fn get(&self, key: &str) -> Option<&V> {
83 self.map.get(key)
84 }
85
86 pub fn inspect_node(&self) -> &Node {
88 &self.node
89 }
90}
91
92impl<V> Inspect for &mut ManagedInspectMap<V>
93where
94 for<'a> &'a mut V: Inspect,
95{
96 fn iattach(self, parent: &Node, name: impl AsRef<str>) -> Result<(), AttachError> {
97 self.node = parent.create_child(name.as_ref());
98 Ok(())
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use crate::managed_inspect_map::ManagedInspectMap;
105 use diagnostics_assertions::assert_data_tree;
106 use fuchsia_inspect::{Inspector, Node};
107 use fuchsia_inspect_derive::{IValue, Inspect, WithInspect};
108
109 #[derive(Default, Inspect)]
110 struct TestInspectWrapper {
111 inspect_node: Node,
112 pub test_map: ManagedInspectMap<IValue<String>>,
113 }
114
115 #[fuchsia::test]
117 fn test_map_insert() {
118 let inspector = Inspector::default();
119
120 let mut map = ManagedInspectMap::<IValue<String>>::with_node(
121 inspector.root().create_child("managed_node"),
122 );
123
124 let _ = map.insert("key1".to_string(), "value1".to_string().into());
125 let _ = map.insert("key2".to_string(), "value2".to_string().into());
126
127 assert_data_tree!(inspector, root: {
128 managed_node: {
129 "key1": "value1",
130 "key2": "value2"
131 }
132 });
133 }
134
135 #[fuchsia::test]
137 fn test_map_remove() {
138 let inspector = Inspector::default();
139
140 let mut map = ManagedInspectMap::<IValue<String>>::with_node(
141 inspector.root().create_child("managed_node"),
142 );
143
144 let _ = map.insert("key1".to_string(), "value1".to_string().into());
145 let _ = map.insert("key2".to_string(), "value2".to_string().into());
146
147 let _ = map.map_mut().remove(&"key1".to_string());
148
149 assert_data_tree!(inspector, root: {
150 managed_node: {
151 "key2": "value2"
152 }
153 });
154 }
155
156 #[fuchsia::test]
159 fn test_map_insert_with_property_name() {
160 let inspector = Inspector::default();
161
162 let mut map = ManagedInspectMap::<IValue<String>>::with_node(
163 inspector.root().create_child("managed_node"),
164 );
165
166 let _ = map.insert_with_property_name(
167 "key1".to_string(),
168 "property_name_1".to_string(),
169 "value1".to_string().into(),
170 );
171
172 let _ = map.insert_with_property_name(
174 "key1".to_string(),
175 "property_name_2".to_string(),
176 "value2".to_string().into(),
177 );
178
179 assert_data_tree!(inspector, root: {
180 managed_node: {
181 "property_name_2": "value2"
182 }
183 });
184 }
185
186 #[fuchsia::test]
189 fn test_map_derive_inspect() {
190 let inspector = Inspector::default();
191
192 let mut wrapper = TestInspectWrapper::default()
193 .with_inspect(inspector.root(), "wrapper_node")
194 .expect("Failed to attach wrapper_node");
195
196 let _ = wrapper.test_map.insert("key1".to_string(), "value1".to_string().into());
197
198 assert_data_tree!(inspector, root: {
200 wrapper_node: {
201 test_map: {
202 "key1": "value1",
203 }
204 }
205 });
206 }
207}