Skip to main content

fuchsia_inspect/writer/types/
int_property.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::{Inner, InnerValueType, InspectType, NumericProperty, Property};
6use log::error;
7
8/// Inspect int property 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 IntProperty {
16    inner: Inner<InnerValueType>,
17}
18
19impl InspectType for IntProperty {
20    fn into_recorded(self) -> crate::writer::types::RecordedInspectType {
21        crate::writer::types::RecordedInspectType::IntProperty(self)
22    }
23}
24
25crate::impl_inspect_type_internal!(IntProperty);
26
27impl Property<'_> for IntProperty {
28    type Type = i64;
29
30    fn set(&self, value: i64) {
31        if let Some(ref inner_ref) = self.inner.inner_ref() {
32            match inner_ref.state.try_lock() {
33                Ok(mut state) => state.set_int_metric(inner_ref.block_index, value),
34                Err(err) => error!(err:?; "Failed to set property"),
35            }
36        }
37    }
38}
39
40impl NumericProperty<'_> for IntProperty {
41    fn add(&self, value: i64) -> Option<i64> {
42        if let Some(ref inner_ref) = self.inner.inner_ref() {
43            match inner_ref.state.try_lock() {
44                Ok(mut state) => {
45                    return Some(state.add_int_metric(inner_ref.block_index, value));
46                }
47                Err(err) => error!(err:?; "Failed to add property"),
48            }
49        }
50        None
51    }
52
53    fn subtract(&self, value: i64) -> Option<i64> {
54        if let Some(ref inner_ref) = self.inner.inner_ref() {
55            match inner_ref.state.try_lock() {
56                Ok(mut state) => {
57                    return Some(state.subtract_int_metric(inner_ref.block_index, value));
58                }
59                Err(err) => error!(err:?; "Failed to subtract property"),
60            }
61        }
62        None
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69    use crate::assert_update_is_atomic;
70    use crate::writer::testing_utils::{GetBlockExt, get_state};
71    use crate::writer::{Inspector, Node};
72    use inspect_format::{BlockType, Int};
73
74    #[fuchsia::test]
75    fn int_property() {
76        // Create and use a default value.
77        let default = IntProperty::default();
78        default.add(1);
79
80        let state = get_state(4096);
81        let root = Node::new_root(state);
82        let node = root.create_child("node");
83        {
84            let property = node.create_int("property", 1);
85            property.get_block::<_, Int>(|property_block| {
86                assert_eq!(property_block.block_type(), Some(BlockType::IntValue));
87                assert_eq!(property_block.value(), 1);
88            });
89            node.get_block::<_, inspect_format::Node>(|node_block| {
90                assert_eq!(node_block.child_count(), 1);
91            });
92
93            property.set(2);
94            property.get_block::<_, Int>(|property_block| {
95                assert_eq!(property_block.value(), 2);
96            });
97
98            assert_eq!(property.subtract(5).unwrap(), -3);
99            property.get_block::<_, Int>(|property_block| {
100                assert_eq!(property_block.value(), -3);
101            });
102
103            assert_eq!(property.add(8).unwrap(), 5);
104            property.get_block::<_, Int>(|property_block| {
105                assert_eq!(property_block.value(), 5);
106            });
107        }
108        node.get_block::<_, inspect_format::Node>(|node_block| {
109            assert_eq!(node_block.child_count(), 0);
110        });
111    }
112
113    #[fuchsia::test]
114    fn property_atomics() {
115        let inspector = Inspector::default();
116        let property = inspector.root().create_int("property", 5);
117
118        assert_update_is_atomic!(property, |property| {
119            property.subtract(1);
120            property.subtract(2);
121        });
122    }
123}