Skip to main content

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