Skip to main content

fuchsia_inspect/writer/types/
int_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::{ArithmeticArrayProperty, ArrayProperty, Inner, InnerValueType, InspectType};
6use log::error;
7
8/// Inspect int array data type.
9///
10/// NOTE: do not rely on PartialEq implementation for true comparison.
11/// Instead leverage the reader.
12///
13/// NOTE: Operations on a Default value are no-ops.
14#[derive(Debug, PartialEq, Eq, Default)]
15pub struct IntArrayProperty {
16    pub(crate) inner: Inner<InnerValueType>,
17}
18
19impl InspectType for IntArrayProperty {
20    fn into_recorded(self) -> crate::writer::types::RecordedInspectType {
21        crate::writer::types::RecordedInspectType::IntArray(self)
22    }
23}
24
25crate::impl_inspect_type_internal!(IntArrayProperty);
26
27impl ArrayProperty for IntArrayProperty {
28    type Type<'a> = i64;
29
30    fn set<'a>(&self, index: usize, value: impl Into<Self::Type<'a>>) {
31        if let Some(ref inner_ref) = self.inner.inner_ref() {
32            match inner_ref.state.try_lock() {
33                Ok(mut state) => {
34                    state.set_array_int_slot(inner_ref.block_index, index, value.into())
35                }
36                Err(err) => error!(err:?; "Failed to set property"),
37            }
38        }
39    }
40
41    fn clear(&self) {
42        if let Some(ref inner_ref) = self.inner.inner_ref() {
43            inner_ref
44                .state
45                .try_lock()
46                .and_then(|mut state| state.clear_array(inner_ref.block_index, 0))
47                .unwrap_or_else(|e| {
48                    error!("Failed to clear property. Error: {:?}", e);
49                });
50        }
51    }
52}
53
54impl ArithmeticArrayProperty for IntArrayProperty {
55    fn add<'a>(&self, index: usize, value: Self::Type<'a>)
56    where
57        Self: 'a,
58    {
59        if let Some(ref inner_ref) = self.inner.inner_ref() {
60            match inner_ref.state.try_lock() {
61                Ok(mut state) => {
62                    state.add_array_int_slot(inner_ref.block_index, index, value);
63                }
64                Err(err) => error!(err:?; "Failed to add property"),
65            }
66        }
67    }
68
69    fn subtract<'a>(&self, index: usize, value: Self::Type<'a>)
70    where
71        Self: 'a,
72    {
73        if let Some(ref inner_ref) = self.inner.inner_ref() {
74            match inner_ref.state.try_lock() {
75                Ok(mut state) => {
76                    state.subtract_array_int_slot(inner_ref.block_index, index, value);
77                }
78                Err(err) => error!(err:?; "Failed to subtract property"),
79            }
80        }
81    }
82}
83
84#[cfg(test)]
85mod tests {
86    use super::*;
87    use crate::writer::Length;
88    use crate::writer::testing_utils::GetBlockExt;
89    use crate::{Inspector, assert_update_is_atomic};
90    use inspect_format::{Array, Int};
91
92    #[fuchsia::test]
93    fn test_int_array() {
94        // Create and use a default value.
95        let default = IntArrayProperty::default();
96        default.add(1, 1);
97
98        let inspector = Inspector::default();
99        let root = inspector.root();
100        let node = root.create_child("node");
101        {
102            let array = node.create_int_array("array_property", 5);
103            assert_eq!(array.len().unwrap(), 5);
104
105            array.set(0, 5);
106            array.get_block::<_, Array<Int>>(|array_block| {
107                assert_eq!(array_block.get(0).unwrap(), 5);
108            });
109
110            array.add(0, 5);
111            array.get_block::<_, Array<Int>>(|array_block| {
112                assert_eq!(array_block.get(0).unwrap(), 10);
113            });
114
115            array.subtract(0, 3);
116
117            array.get_block::<_, Array<Int>>(|array_block| {
118                assert_eq!(array_block.get(0).unwrap(), 7);
119            });
120
121            array.set(1, 2);
122            array.set(3, -3);
123
124            array.get_block::<_, Array<Int>>(|array_block| {
125                for (i, value) in [7, 2, 0, -3, 0].iter().enumerate() {
126                    assert_eq!(array_block.get(i).unwrap(), *value);
127                }
128            });
129
130            array.clear();
131            array.get_block::<_, Array<Int>>(|array_block| {
132                for i in 0..5 {
133                    assert_eq!(0, array_block.get(i).unwrap());
134                }
135            });
136
137            node.get_block::<_, inspect_format::Node>(|node_block| {
138                assert_eq!(node_block.child_count(), 1);
139            });
140        }
141        node.get_block::<_, inspect_format::Node>(|node_block| {
142            assert_eq!(node_block.child_count(), 0);
143        });
144    }
145
146    #[fuchsia::test]
147    fn property_atomics() {
148        let inspector = Inspector::default();
149        let array = inspector.root().create_int_array("array", 5);
150
151        assert_update_is_atomic!(array, |array| {
152            array.set(0, 0);
153            array.set(1, 1);
154            array.set(2, 2);
155            array.set(3, 3);
156            array.set(4, 4);
157        });
158    }
159}