settings_inspect_utils/
managed_inspect_queue.rsuse fuchsia_inspect::Node;
use fuchsia_inspect_derive::{AttachError, Inspect, WithInspect};
use std::collections::VecDeque;
#[derive(Default)]
pub struct ManagedInspectQueue<V> {
items: VecDeque<V>,
size_limit: usize,
inspect_node: Node,
}
impl<V> ManagedInspectQueue<V>
where
for<'a> &'a mut V: Inspect,
V: std::fmt::Debug + std::default::Default,
{
pub fn new(size_limit: usize) -> Self {
let mut default = ManagedInspectQueue::<V>::default();
default.set_size_limit(size_limit);
default
}
pub fn with_node(node: Node, size_limit: usize) -> Self {
Self { items: VecDeque::with_capacity(size_limit), size_limit, inspect_node: node }
}
fn set_size_limit(&mut self, new_size_limit: usize) {
while self.items.len() > new_size_limit {
let _ = self.items.pop_front();
}
self.size_limit = new_size_limit;
}
pub fn iter_mut(&mut self) -> std::collections::vec_deque::IterMut<'_, V> {
self.items.iter_mut()
}
pub fn items_mut(&mut self) -> &mut VecDeque<V> {
&mut self.items
}
pub fn retain<F>(&mut self, f: F)
where
F: FnMut(&V) -> bool,
{
self.items.retain(f);
}
pub fn inspect_node(&self) -> &Node {
&self.inspect_node
}
pub fn push(&mut self, key: &str, item: V) {
if self.items.len() == self.size_limit && self.size_limit != 0 {
let _ = self.items.pop_front();
}
let node = &self.inspect_node;
self.items
.push_back(item.with_inspect(node, key).expect("Failed to attach new queue entry."));
}
#[cfg(test)]
pub(crate) fn len(&self) -> usize {
self.items.len()
}
}
impl<V> Inspect for &mut ManagedInspectQueue<V>
where
for<'a> &'a mut V: Inspect,
{
fn iattach(self, parent: &Node, name: impl AsRef<str>) -> Result<(), AttachError> {
self.inspect_node = parent.create_child(name.as_ref());
Ok(())
}
}
#[cfg(test)]
mod tests {
use crate::managed_inspect_queue::ManagedInspectQueue;
use diagnostics_assertions::assert_data_tree;
use fuchsia_inspect::{self as inspect, Node};
use fuchsia_inspect_derive::{IValue, Inspect, WithInspect};
#[derive(Default, Inspect)]
struct TestInspectWrapper {
inspect_node: Node,
queue: ManagedInspectQueue<TestInspectItem>,
}
#[derive(Debug, Default, Inspect)]
struct TestInspectItem {
inspect_node: Node,
id: IValue<u64>,
}
impl TestInspectItem {
fn new(id: u64) -> Self {
Self { inspect_node: Node::default(), id: id.into() }
}
}
#[fuchsia::test]
fn test_queue_under_capacity() {
let inspector = inspect::Inspector::default();
let mut wrapper = TestInspectWrapper::default()
.with_inspect(inspector.root(), "inspect_wrapper")
.expect("failed to create TestInspectWrapper inspect node");
wrapper.queue.set_size_limit(2);
let test_val_1 = TestInspectItem::new(6);
let test_val_2 = TestInspectItem::new(5);
wrapper.queue.push("0", test_val_1);
wrapper.queue.push("1", test_val_2);
assert_data_tree!(inspector, root: {
inspect_wrapper: {
queue: {
"0": {
"id": 6_u64,
},
"1": {
"id": 5_u64,
},
},
}
});
assert_eq!(wrapper.queue.len(), 2);
}
#[fuchsia::test]
fn test_queue_over_capacity() {
let inspector = inspect::Inspector::default();
let mut wrapper = TestInspectWrapper::default()
.with_inspect(inspector.root(), "inspect_wrapper")
.expect("failed to create TestInspectWrapper inspect node");
wrapper.queue.set_size_limit(2);
let test_val_1 = TestInspectItem::new(6);
let test_val_2 = TestInspectItem::new(5);
let test_val_3 = TestInspectItem::new(4);
wrapper.queue.push("0", test_val_1);
wrapper.queue.push("1", test_val_2);
wrapper.queue.push("2", test_val_3);
assert_data_tree!(inspector, root: {
inspect_wrapper: {
queue: {
"1": {
"id": 5_u64,
},
"2": {
"id": 4_u64,
},
},
}
});
assert_eq!(wrapper.queue.len(), 2);
}
#[fuchsia::test]
fn test_size_limit() {
let inspector = inspect::Inspector::default();
let mut wrapper = TestInspectWrapper::default()
.with_inspect(inspector.root(), "inspect_wrapper")
.expect("failed to create TestInspectWrapper inspect node");
let test_val_1 = TestInspectItem::new(6);
let test_val_2 = TestInspectItem::new(5);
let test_val_3 = TestInspectItem::new(4);
wrapper.queue.push("0", test_val_1);
wrapper.queue.push("1", test_val_2);
wrapper.queue.push("2", test_val_3);
wrapper.queue.set_size_limit(1);
assert_data_tree!(inspector, root: {
inspect_wrapper: {
queue: {
"2": {
"id": 4_u64,
},
},
}
});
assert_eq!(wrapper.queue.len(), 1);
}
#[fuchsia::test]
fn test_queue_remove() {
let inspector = inspect::Inspector::default();
let mut queue = ManagedInspectQueue::<IValue<String>>::with_node(
inspector.root().create_child("managed_node"),
10,
);
queue.push("0", "value1".to_string().into());
queue.push("1", "value2".to_string().into());
queue.retain(|item| **item != "value1");
assert_data_tree!(inspector, root: {
managed_node: {
"1": "value2"
}
});
}
}