fuchsia_inspect/writer/types/
string_array.rsuse crate::writer::private::InspectTypeInternal;
use crate::writer::{ArrayProperty, Inner, InnerValueType, InspectType, State, StringReference};
use inspect_format::BlockIndex;
#[derive(Debug, PartialEq, Eq, Default)]
pub struct StringArrayProperty {
inner: Inner<InnerValueType>,
}
impl InspectType for StringArrayProperty {}
impl InspectTypeInternal for StringArrayProperty {
fn new(state: State, block_index: BlockIndex) -> Self {
Self { inner: Inner::new(state, block_index) }
}
fn is_valid(&self) -> bool {
self.inner.is_valid()
}
fn new_no_op() -> Self {
Self { inner: Inner::None }
}
fn state(&self) -> Option<State> {
Some(self.inner.inner_ref()?.state.clone())
}
fn block_index(&self) -> Option<BlockIndex> {
Some(self.inner.inner_ref()?.block_index)
}
fn atomic_access<R, F: FnOnce(&Self) -> R>(&self, f: F) -> R {
match self.inner.inner_ref() {
None => {
f(self)
}
Some(inner_ref) => {
inner_ref.state.begin_transaction();
let result = f(self);
inner_ref.state.end_transaction();
result
}
}
}
}
impl ArrayProperty for StringArrayProperty {
type Type = StringReference;
fn set(&self, index: usize, value: impl Into<Self::Type>) {
if let Some(ref inner_ref) = self.inner.inner_ref() {
inner_ref
.state
.try_lock()
.and_then(|mut state| {
state.set_array_string_slot(inner_ref.block_index, index, value.into())
})
.ok();
}
}
fn clear(&self) {
if let Some(ref inner_ref) = self.inner.inner_ref() {
inner_ref
.state
.try_lock()
.and_then(|mut state| state.clear_array(inner_ref.block_index, 0))
.ok();
}
}
}
impl Drop for StringArrayProperty {
fn drop(&mut self) {
self.clear();
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::writer::testing_utils::GetBlockExt;
use crate::writer::Length;
use crate::{assert_update_is_atomic, Inspector};
use diagnostics_assertions::assert_json_diff;
impl StringArrayProperty {
pub fn load_string_slot(&self, slot: usize) -> Option<String> {
self.inner.inner_ref().and_then(|inner_ref| {
inner_ref
.state
.try_lock()
.and_then(|state| {
state.load_string(
state
.get_block(self.block_index().unwrap())
.array_get_string_index_slot(slot)?,
)
})
.ok()
})
}
}
#[fuchsia::test]
fn string_array_property() {
let inspector = Inspector::default();
let root = inspector.root();
let node = root.create_child("node");
{
let array = node.create_string_array("string_array", 5);
assert_eq!(array.len().unwrap(), 5);
node.get_block(|node_block| {
assert_eq!(node_block.child_count().unwrap(), 1);
});
array.set(0, "0");
array.set(1, "1");
array.set(2, "2");
array.set(3, "3");
array.set(4, "4");
array.set(5, "5");
assert!(array.load_string_slot(5).is_none());
let expected: Vec<String> =
vec!["0".into(), "1".into(), "2".into(), "3".into(), "4".into()];
assert_json_diff!(inspector, root: {
node: {
string_array: expected,
},
});
array.clear();
let expected: Vec<String> = vec![String::new(); 5];
assert_json_diff!(inspector, root: {
node: {
string_array: expected,
},
});
assert!(array.load_string_slot(5).is_none());
}
node.get_block(|node_block| {
assert_eq!(node_block.child_count().unwrap(), 0);
});
}
#[fuchsia::test]
fn property_atomics() {
let inspector = Inspector::default();
let array = inspector.root().create_string_array("string_array", 5);
assert_update_is_atomic!(array, |array| {
array.set(0, "0");
array.set(1, "1");
array.set(2, "2");
array.set(3, "3");
array.set(4, "4");
});
}
}