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.
45use crate::writer::private::InspectTypeInternal;
6use crate::writer::{Error, InnerType, State};
7use inspect_format::BlockIndex;
89/// Trait implemented by properties.
10pub trait Property<'t>: InspectTypeInternal {
11/// The type of the property.
12type Type;
1314/// Set the property value to |value|.
15fn set(&self, value: Self::Type);
1617/// Takes a function to execute as under a single lock of the Inspect VMO. This function
18 /// receives a reference to the `Property` on which it is called.
19fn atomic_update<R, F: FnOnce(&Self) -> R>(&self, update_fn: F) -> R {
20self.atomic_access(update_fn)
21 }
22}
2324/// Trait implemented by numeric properties providing common operations.
25pub trait NumericProperty<'t>: Property<'t> {
26/// Add the given |value| to the property current value.
27fn add(&self, value: <Self as Property<'t>>::Type) -> Option<<Self as Property<'t>>::Type>;
2829/// Subtract the given |value| from the property current value.
30fn subtract(&self, value: <Self as Property<'t>>::Type)
31 -> Option<<Self as Property<'t>>::Type>;
32}
3334/// Get the usable length of a type.
35pub trait Length {
36fn len(&self) -> Option<usize>;
37fn is_empty(&self) -> Option<bool> {
38self.len().map(|s| s == 0)
39 }
40}
4142impl<T: ArrayProperty + InspectTypeInternal> Length for T {
43fn len(&self) -> Option<usize> {
44if let Ok(state) = self.state()?.try_lock() {
45return Some(state.get_array_size(self.block_index()?));
46 }
47None
48}
49}
5051/// Trait implemented by all array properties providing common operations on arrays.
52pub trait ArrayProperty: Length + InspectTypeInternal {
53/// The type of the array entries.
54type Type<'a>
55where
56Self: 'a;
5758/// Sets the array value to `value` at the given `index`.
59fn set<'a>(&self, index: usize, value: impl Into<Self::Type<'a>>)
60where
61Self: 'a;
6263/// Sets all slots of the array to 0 and releases any references.
64fn clear(&self);
6566/// Takes a function to execute as under a single lock of the Inspect VMO. This function
67 /// receives a reference to the `ArrayProperty` on which it is called.
68fn atomic_update<R, F: FnOnce(&Self) -> R>(&self, update_fn: F) -> R {
69self.atomic_access(update_fn)
70 }
71}
7273pub trait ArithmeticArrayProperty: ArrayProperty {
74/// Adds the given `value` to the property current value at the given `index`.
75fn add<'a>(&self, index: usize, value: Self::Type<'a>)
76where
77Self: 'a;
7879/// Subtracts the given `value` to the property current value at the given `index`.
80fn subtract<'a>(&self, index: usize, value: Self::Type<'a>)
81where
82Self: 'a;
83}
8485/// Trait implemented by all histogram properties providing common operations.
86pub trait HistogramProperty {
87/// The type of each value added to the histogram.
88type Type;
8990/// Inserts the given `value` in the histogram.
91fn insert(&self, value: Self::Type);
9293/// Inserts the given `value` in the histogram `count` times.
94fn insert_multiple(&self, value: Self::Type, count: usize);
9596/// Clears all buckets of the histogram.
97fn clear(&self);
98}
99100#[derive(Default, Debug)]
101pub(crate) struct InnerPropertyType;
102103impl InnerType for InnerPropertyType {
104type Data = ();
105fn free(state: &State, _: &Self::Data, block_index: BlockIndex) -> Result<(), Error> {
106let mut state_lock = state.try_lock()?;
107 state_lock
108 .free_string_or_bytes_buffer_property(block_index)
109 .map_err(|err| Error::free("property", block_index, err))
110 }
111}