Skip to main content

fuchsia_inspect/writer/types/
string_array.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::writer::{ArrayProperty, Inner, InnerValueType, InspectType};
6use std::borrow::Cow;
7
8#[derive(Debug, PartialEq, Eq, Default)]
9pub struct StringArrayProperty {
10    inner: Inner<InnerValueType>,
11}
12
13impl InspectType for StringArrayProperty {
14    fn into_recorded(self) -> crate::writer::types::RecordedInspectType {
15        crate::writer::types::RecordedInspectType::StringArray(self)
16    }
17}
18
19crate::impl_inspect_type_internal!(StringArrayProperty);
20
21impl ArrayProperty for StringArrayProperty {
22    type Type<'a> = Cow<'a, str>;
23
24    fn set<'a>(&self, index: usize, value: impl Into<Self::Type<'a>>) {
25        if let Some(ref inner_ref) = self.inner.inner_ref() {
26            inner_ref
27                .state
28                .try_lock()
29                .and_then(|mut state| {
30                    state.set_array_string_slot(inner_ref.block_index, index, value.into())
31                })
32                .ok();
33        }
34    }
35
36    fn clear(&self) {
37        if let Some(ref inner_ref) = self.inner.inner_ref() {
38            inner_ref
39                .state
40                .try_lock()
41                .and_then(|mut state| state.clear_array(inner_ref.block_index, 0))
42                .ok();
43        }
44    }
45}
46
47impl Drop for StringArrayProperty {
48    fn drop(&mut self) {
49        self.clear();
50    }
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56    use crate::writer::Length;
57    use crate::writer::private::InspectTypeInternal;
58    use crate::writer::testing_utils::GetBlockExt;
59    use crate::{Inspector, assert_update_is_atomic};
60    use diagnostics_assertions::assert_json_diff;
61
62    impl StringArrayProperty {
63        pub fn load_string_slot(&self, slot: usize) -> Option<String> {
64            self.inner.inner_ref().and_then(|inner_ref| {
65                inner_ref.state.try_lock().ok().and_then(|state| {
66                    let index =
67                        state.get_block(self.block_index().unwrap()).get_string_index_at(slot)?;
68                    state.load_string(index).ok()
69                })
70            })
71        }
72    }
73
74    #[fuchsia::test]
75    async fn string_array_property() {
76        let inspector = Inspector::default();
77        let root = inspector.root();
78        let node = root.create_child("node");
79
80        {
81            let array = node.create_string_array("string_array", 5);
82            assert_eq!(array.len().unwrap(), 5);
83            node.get_block::<_, inspect_format::Node>(|node_block| {
84                assert_eq!(node_block.child_count(), 1);
85            });
86
87            array.set(0, "0");
88            array.set(1, "1");
89            array.set(2, "2");
90            array.set(3, "3");
91            array.set(4, "4");
92
93            // this should fail silently
94            array.set(5, "5");
95            assert!(array.load_string_slot(5).is_none());
96
97            let expected: Vec<String> =
98                vec!["0".into(), "1".into(), "2".into(), "3".into(), "4".into()];
99
100            assert_json_diff!(inspector, root: {
101                node: {
102                    string_array: expected,
103                },
104            });
105
106            array.clear();
107
108            let expected: Vec<String> = vec![String::new(); 5];
109
110            assert_json_diff!(inspector, root: {
111                node: {
112                    string_array: expected,
113                },
114            });
115
116            assert!(array.load_string_slot(5).is_none());
117        }
118
119        node.get_block::<_, inspect_format::Node>(|node_block| {
120            assert_eq!(node_block.child_count(), 0);
121        });
122    }
123
124    #[fuchsia::test]
125    fn property_atomics() {
126        let inspector = Inspector::default();
127        let array = inspector.root().create_string_array("string_array", 5);
128
129        assert_update_is_atomic!(array, |array| {
130            array.set(0, "0");
131            array.set(1, "1");
132            array.set(2, "2");
133            array.set(3, "3");
134            array.set(4, "4");
135        });
136    }
137}