115 lines
3.1 KiB
Rust
115 lines
3.1 KiB
Rust
//
|
|
// Copyright 2026 James Pace
|
|
//
|
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
//
|
|
// This Source Code Form is "Incompatible With Secondary Licenses", as
|
|
// defined by the Mozilla Public License, v. 2.0.
|
|
//
|
|
use crate::diagnostic_graph::DiagnosticGraph;
|
|
use crate::diagnostic_status::DiagnosticStatus;
|
|
use crate::error::Result;
|
|
use alloc::string::String;
|
|
use alloc::vec::Vec;
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Clone, Serialize, Deserialize)]
|
|
pub struct TreeView {
|
|
children: Vec<TreeViewNode>,
|
|
}
|
|
|
|
#[derive(Clone, Serialize, Deserialize)]
|
|
struct TreeViewNode {
|
|
id: String,
|
|
status: DiagnosticStatus,
|
|
children: Vec<TreeViewNode>,
|
|
}
|
|
|
|
impl TreeView {
|
|
fn get_nodes(key: &limbo_graph::Key, graph: &DiagnosticGraph) -> Result<Vec<TreeViewNode>> {
|
|
let children = graph.children_of(&key)?;
|
|
if children.len() == 0 {
|
|
return Ok(Vec::<TreeViewNode>::new());
|
|
}
|
|
|
|
let mut to_ret = Vec::<TreeViewNode>::new();
|
|
|
|
for child in children {
|
|
let status = graph.value_of(&child)?;
|
|
let node = TreeViewNode {
|
|
id: graph.full_name_from_key(&child)?,
|
|
status: status,
|
|
children: Self::get_nodes(&child, &graph)?,
|
|
};
|
|
|
|
to_ret.push(node);
|
|
}
|
|
return Ok(to_ret);
|
|
}
|
|
|
|
pub fn from_graph(graph: &DiagnosticGraph) -> Result<TreeView> {
|
|
let view = TreeView {
|
|
children: Self::get_nodes(&graph.root(), &graph)?,
|
|
};
|
|
|
|
Ok(view)
|
|
}
|
|
|
|
pub fn to_json(&self) -> Result<String> {
|
|
Ok(serde_json::to_string(self)?)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use crate::*;
|
|
use alloc::collections::BTreeMap;
|
|
|
|
fn make_a_status_with_name(name: &str) -> DiagnosticStatus {
|
|
let level = DiagnosticLevel::OK;
|
|
let message = "I'm ok";
|
|
let hardware_id = "";
|
|
let values = BTreeMap::<String, String>::new();
|
|
|
|
DiagnosticStatus::new(
|
|
level,
|
|
name.to_owned(),
|
|
message.to_owned(),
|
|
hardware_id.to_owned(),
|
|
values,
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn make_view() -> 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"),
|
|
];
|
|
|
|
let mut graph = DiagnosticGraph::new();
|
|
graph.add_status_vec(&statuses)?;
|
|
|
|
let view = TreeView::from_graph(&graph)?;
|
|
|
|
// First level is just a
|
|
assert!(view.children.len() == 1);
|
|
// a has children b and d.
|
|
assert!(view.children[0].children.len() == 2);
|
|
// regardless is this is b or d, it has one child.
|
|
// TODO: This isn't the best test.
|
|
assert!(view.children[0].children[0].children.len() == 1);
|
|
|
|
// Just to confirm it doesn't panic.
|
|
let _js = view.to_json()?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|