fuchsia_inspect/writer/types/
string_array.rs1use crate::writer::private::InspectTypeInternal;
6use crate::writer::{ArrayProperty, Inner, InnerValueType, InspectType, State};
7use inspect_format::BlockIndex;
8use std::borrow::Cow;
9
10#[derive(Debug, PartialEq, Eq, Default)]
11pub struct StringArrayProperty {
12 inner: Inner<InnerValueType>,
13}
14
15impl InspectType for StringArrayProperty {
16 fn into_recorded(self) -> crate::writer::types::RecordedInspectType {
17 crate::writer::types::RecordedInspectType::StringArray(self)
18 }
19}
20
21impl InspectTypeInternal for StringArrayProperty {
22 fn new(state: State, block_index: BlockIndex) -> Self {
23 Self { inner: Inner::new(state, block_index) }
24 }
25
26 fn is_valid(&self) -> bool {
27 self.inner.is_valid()
28 }
29
30 fn new_no_op() -> Self {
31 Self { inner: Inner::None }
32 }
33
34 fn state(&self) -> Option<State> {
35 Some(self.inner.inner_ref()?.state.clone())
36 }
37
38 fn block_index(&self) -> Option<BlockIndex> {
39 Some(self.inner.inner_ref()?.block_index)
40 }
41
42 fn atomic_access<R, F: FnOnce(&Self) -> R>(&self, f: F) -> R {
43 match self.inner.inner_ref() {
44 None => {
45 f(self)
48 }
49 Some(inner_ref) => {
50 inner_ref.state.begin_transaction();
54 let result = f(self);
55 inner_ref.state.end_transaction();
56 result
57 }
58 }
59 }
60}
61
62impl ArrayProperty for StringArrayProperty {
63 type Type<'a> = Cow<'a, str>;
64
65 fn set<'a>(&self, index: usize, value: impl Into<Self::Type<'a>>) {
66 if let Some(ref inner_ref) = self.inner.inner_ref() {
67 inner_ref
68 .state
69 .try_lock()
70 .and_then(|mut state| {
71 state.set_array_string_slot(inner_ref.block_index, index, value.into())
72 })
73 .ok();
74 }
75 }
76
77 fn clear(&self) {
78 if let Some(ref inner_ref) = self.inner.inner_ref() {
79 inner_ref
80 .state
81 .try_lock()
82 .and_then(|mut state| state.clear_array(inner_ref.block_index, 0))
83 .ok();
84 }
85 }
86}
87
88impl Drop for StringArrayProperty {
89 fn drop(&mut self) {
90 self.clear();
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97 use crate::writer::Length;
98 use crate::writer::testing_utils::GetBlockExt;
99 use crate::{Inspector, assert_update_is_atomic};
100 use diagnostics_assertions::assert_json_diff;
101
102 impl StringArrayProperty {
103 pub fn load_string_slot(&self, slot: usize) -> Option<String> {
104 self.inner.inner_ref().and_then(|inner_ref| {
105 inner_ref.state.try_lock().ok().and_then(|state| {
106 let index =
107 state.get_block(self.block_index().unwrap()).get_string_index_at(slot)?;
108 state.load_string(index).ok()
109 })
110 })
111 }
112 }
113
114 #[fuchsia::test]
115 async fn string_array_property() {
116 let inspector = Inspector::default();
117 let root = inspector.root();
118 let node = root.create_child("node");
119
120 {
121 let array = node.create_string_array("string_array", 5);
122 assert_eq!(array.len().unwrap(), 5);
123 node.get_block::<_, inspect_format::Node>(|node_block| {
124 assert_eq!(node_block.child_count(), 1);
125 });
126
127 array.set(0, "0");
128 array.set(1, "1");
129 array.set(2, "2");
130 array.set(3, "3");
131 array.set(4, "4");
132
133 array.set(5, "5");
135 assert!(array.load_string_slot(5).is_none());
136
137 let expected: Vec<String> =
138 vec!["0".into(), "1".into(), "2".into(), "3".into(), "4".into()];
139
140 assert_json_diff!(inspector, root: {
141 node: {
142 string_array: expected,
143 },
144 });
145
146 array.clear();
147
148 let expected: Vec<String> = vec![String::new(); 5];
149
150 assert_json_diff!(inspector, root: {
151 node: {
152 string_array: expected,
153 },
154 });
155
156 assert!(array.load_string_slot(5).is_none());
157 }
158
159 node.get_block::<_, inspect_format::Node>(|node_block| {
160 assert_eq!(node_block.child_count(), 0);
161 });
162 }
163
164 #[fuchsia::test]
165 fn property_atomics() {
166 let inspector = Inspector::default();
167 let array = inspector.root().create_string_array("string_array", 5);
168
169 assert_update_is_atomic!(array, |array| {
170 array.set(0, "0");
171 array.set(1, "1");
172 array.set(2, "2");
173 array.set(3, "3");
174 array.set(4, "4");
175 });
176 }
177}