Handle adding vector of statuses.

This commit is contained in:
James Pace 2026-06-20 11:41:08 -04:00
parent 4cf54d18c3
commit 6e714a2325
2 changed files with 129 additions and 14 deletions

View File

@ -38,9 +38,11 @@ impl DiagnosticStatus {
hardware_id: String,
values: BTreeMap<String, String>,
) -> Self {
let cleaned_name = Self::clean_name(&name);
Self {
level: level,
name: name,
name: cleaned_name,
message: message,
hardware_id: hardware_id,
values: values,
@ -132,6 +134,15 @@ impl DiagnosticStatus {
to_return.name = self.get_child_name();
return to_return;
}
fn clean_name(name: &str) -> String {
// Remove prefix "/"
let without_prefix = name.strip_prefix("/").unwrap_or(name);
// and suffix
let without_suffix = name.strip_suffix("/").unwrap_or(without_prefix);
return without_suffix.to_owned();
}
}
#[cfg(test)]
@ -180,4 +191,24 @@ mod tests {
assert!(parent_names[1] == "b");
assert!(child_name == "c");
}
#[test]
fn diagnostic_name_cleaning() {
let level = DiagnosticLevel::OK;
let name = "/a";
let message = "I'm ok";
let hardware_id = "";
let values = BTreeMap::<String, String>::new();
let diag_status = DiagnosticStatus::new(
level,
name.to_owned(),
message.to_owned(),
hardware_id.to_owned(),
values,
);
assert!(diag_status.name_is_basic());
assert!(diag_status.name() == "a");
}
}

View File

@ -89,6 +89,22 @@ impl DiagnosticGraph {
Ok(result)
}
pub fn child_of_with_name(
&self,
parent: &limbo_graph::Key,
desired_child_name: &str,
) -> anyhow::Result<Option<limbo_graph::Key>> {
let all_children = self.children_of(parent)?;
for child in all_children.iter() {
let child_name = self.value_of(&child)?.name();
if child_name == desired_child_name {
return Ok(Some(child.clone()));
}
}
return Ok(None);
}
pub fn add_status(&mut self, status: DiagnosticStatus) -> anyhow::Result<()> {
// If I'm basic I just need to be added as a child of the root.
if status.name_is_basic() {
@ -105,6 +121,8 @@ impl DiagnosticGraph {
'parent_loop: for parent_name in parent_names.iter() {
let children = self.graph.children_of(&cur_key)?;
// There are no children of this parent, so we can add
// the parent and go to the next parent.
if children.len() == 0 {
let holder_for_parent = DiagnosticStatus::from_name(parent_name.clone());
cur_key = self
@ -112,11 +130,13 @@ impl DiagnosticGraph {
.add(DiagnosticNode::DiagnosticStatus(holder_for_parent), cur_key)?;
continue 'parent_loop;
}
'child_loop: for child in children {
// This parent does have children, look at them and
// update loop if appropriate.
for child in children {
let child_node = self.graph.value_of(&child)?;
if child_node.is_root() {
// child node can't be root, but we'll catch here anyway.
continue 'child_loop;
// A child node can't be root.
return Err(anyhow!("A child node can't be root!"));
}
if child_node.value().unwrap().name() == *parent_name {
// The child node matched the parent we were looking for.
@ -133,11 +153,34 @@ impl DiagnosticGraph {
.add(DiagnosticNode::DiagnosticStatus(holder_for_parent), cur_key)?;
}
// We've updated all the parents, so we can add ourselves now.
self.graph.add(
DiagnosticNode::DiagnosticStatus(status.copy_with_child_name()),
cur_key,
)?;
// Do we already exist as a child of parent?
let children_of_this_parent = self.graph.children_of(&cur_key)?;
let mut names_of_children_of_this_parent = children_of_this_parent.iter().map(|x| {
self.graph
.value_of(&x)
.expect("Given child not in graph.")
.value()
.expect("Given root node as child?")
.name()
});
let child_in_children_of_this_parent =
names_of_children_of_this_parent.any(|x| x == status.get_child_name());
if !child_in_children_of_this_parent {
// If we don't we can be added.
self.graph.add(
DiagnosticNode::DiagnosticStatus(status.copy_with_child_name()),
cur_key,
)?;
}
Ok(())
}
pub fn add_status_vec(&mut self, statuses: &Vec<DiagnosticStatus>) -> anyhow::Result<()> {
for status in statuses {
self.add_status(status.clone())?;
}
Ok(())
}
}
@ -145,25 +188,27 @@ impl DiagnosticGraph {
#[cfg(test)]
mod tests {
use super::*;
use alloc::vec;
#[test]
fn add_one_to_graph() -> anyhow::Result<()> {
fn make_a_status_with_name(name: &str) -> DiagnosticStatus {
let level = DiagnosticLevel::OK;
let name = "/a/b/c";
let message = "I'm ok";
let hardware_id = "";
let values = BTreeMap::<String, String>::new();
let diag_status = DiagnosticStatus::new(
DiagnosticStatus::new(
level,
name.to_owned(),
message.to_owned(),
hardware_id.to_owned(),
values,
);
)
}
#[test]
fn add_one_to_graph() -> anyhow::Result<()> {
let mut graph = DiagnosticGraph::new();
graph.add_status(diag_status)?;
graph.add_status(make_a_status_with_name("/a/b/c"))?;
let first_child_keys = graph.children_of(&graph.root())?;
assert!(first_child_keys.len() == 1);
@ -186,4 +231,43 @@ mod tests {
Ok(())
}
#[test]
fn add_multiple_to_graph() -> anyhow::Result<()> {
let statuses = vec![
make_a_status_with_name("/a"),
make_a_status_with_name("/a/b"),
make_a_status_with_name("/a/b/c"),
make_a_status_with_name("/a/d/e"),
make_a_status_with_name("/a/d/f"),
make_a_status_with_name("/a/d"),
];
let mut graph = DiagnosticGraph::new();
graph.add_status_vec(&statuses)?;
let root_children = graph.children_of(&graph.root())?;
assert!(root_children.len() == 1);
assert!(graph.value_of(&root_children[0])?.name() == "a");
let children_of_a = graph.children_of(&root_children[0])?;
let mut children_of_a_names = children_of_a
.iter()
.map(|x| graph.value_of(&x).expect("Value of failed.").name());
assert!(children_of_a.len() == 2);
assert!(children_of_a_names.any(|x| x == "b"));
assert!(children_of_a_names.any(|x| x == "d"));
let b_key = graph.child_of_with_name(&root_children[0], "b")?;
assert!(b_key.is_some());
let b_children = graph.children_of(&b_key.unwrap())?;
assert!(b_children.len() == 1);
let d_key = graph.child_of_with_name(&root_children[0], "d")?;
assert!(d_key.is_some());
let d_children = graph.children_of(&d_key.unwrap())?;
assert!(d_children.len() == 2);
Ok(())
}
}