Start working on the tree system again.

This commit is contained in:
Michael Mikovsky
2026-02-15 17:59:35 -07:00
parent 2a18639d84
commit ffde84e60c
5 changed files with 142 additions and 59 deletions
+105
View File
@@ -0,0 +1,105 @@
use std::collections::HashMap;
use serde_json::{json, Value};
use crate::tree::symbols;
pub struct Branch {
children: HashMap<String, Box<dyn TreeElement>>,
branch_type: &'static str,
}
impl Branch {
pub fn new(branch_type: &'static str) -> Self {
Self {
children: HashMap::new(),
branch_type,
}
}
pub fn add_child(&mut self, name: impl Into<String>, child: Box<dyn TreeElement>) {
self.children.insert(name.into(), child);
}
pub fn with_child(mut self, name: impl Into<String>, child: Box<dyn TreeElement>) -> Self {
self.add_child(name, child);
self
}
pub fn get_child(&mut self, name: &str) -> Option<&mut Box<dyn TreeElement>> {
self.children.get_mut(name)
}
pub fn children(&self) -> &HashMap<String, Box<dyn TreeElement>> {
&self.children
}
pub fn get_type(&self) -> Value {
json!(self.branch_type)
}
pub fn send_message(&mut self, target: Value, message: Value) -> Value {
self.handle_local_message(target, message)
}
fn handle_local_message(&mut self, target: Value, message: Value) -> Value {
match target {
Value::Null => {
if let Some(cmd) = message.as_str() {
match cmd {
symbols::CMD_GET_CHILDREN => {
let children = self
.children
.iter()
.map(|(k, v)| (Value::String(k.clone()), v.get_type()))
.collect::<HashMap<Value, Value>>();
json!(children)
}
_ => self.handle_message(message),
}
} else {
self.handle_message(message)
}
}
Value::Array(mut path) => {
if path.is_empty() {
return json!(symbols::ERR_INVALID_PATH);
}
let next = path.remove(0);
if let Value::String(next_name) = next {
if let Some(child) = self.children.get_mut(&next_name) {
child.send_message(Value::Array(path), message)
} else {
json!(symbols::ERR_CHILD_NOT_FOUND)
}
} else {
json!(symbols::ERR_INVALID_PATH)
}
}
Value::String(target) => {
if let Some(child) = self.children.get_mut(&target) {
child.send_message(Value::Null, message)
} else {
json!(symbols::ERR_CHILD_NOT_FOUND)
}
}
_ => json!(symbols::ERR_INVALID_TARGET),
}
}
pub fn handle_message(&mut self, _message: Value) -> Value {
json!(symbols::ERR_UNSUPPORTED_METHOD)
}
}
impl TreeElement for Branch {
fn get_type(&self) -> Value {
self.get_type()
}
fn send_message(&mut self, target: Value, message: Value) -> Value {
self.handle_local_message(target, message)
}
}
use crate::tree::TreeElement;
+2 -2
View File
@@ -1,10 +1,10 @@
/// Implement logging for the manager
use crossbeam_channel::{Receiver, Sender};
use serde_json::{Value, json};
use serde_json::{json, Value};
use crate::{
logger::{Logger, Record},
tree::{Tree, TreeElement, symbols},
tree::{symbols, Tree, TreeElement},
};
struct LoggerTX(Sender<Record>);
+26 -27
View File
@@ -1,12 +1,14 @@
use std::collections::HashMap;
use serde_json::{Value, json};
use serde_json::{json, Value};
mod log;
mod branch;
pub mod log;
pub mod symbols;
pub use branch::Branch;
pub trait TreeElement {
// fn get_children(&self) -> HashMap<TreeType, TreeType>;
fn get_type(&self) -> Value;
fn send_message(&mut self, target: Value, message: Value) -> Value;
}
@@ -31,51 +33,48 @@ impl TreeElement for Tree {
fn get_type(&self) -> Value {
json!(symbols::TYPE_TREE)
}
// fn send_message_child(&mut self, element: Value, message: TreeMessage) -> TreeMessage {
// let name = if let TreeType::String(name) = element {
// name
// } else {
// return TreeMessage::Error(ModuleError::InvalidType);
// };
// if let Some(element) = self.elements.get_mut(&name) {
// element.send_message(message)
// } else {
// TreeMessage::Error(ModuleError::TreeNotExist)
// }
// }
fn send_message(&mut self, target: Value, message: Value) -> Value {
match target {
Value::Null => {
if let Some(message) = message.as_str() {
match message {
"GetChildren" => {
symbols::CMD_GET_CHILDREN => {
let children = self
.elements
.iter()
.map(|c| (Value::String(c.0.clone()), c.1.get_type()))
.into_iter()
.map(|(k, v)| (Value::String(k.clone()), v.get_type()))
.collect::<HashMap<Value, Value>>();
json!(children)
}
_ => Value::String("UnsupportedMethod".to_owned()),
_ => json!(symbols::ERR_UNSUPPORTED_METHOD),
}
} else {
Value::String("UnsupportedMethod".to_owned())
json!(symbols::ERR_UNSUPPORTED_METHOD)
}
}
Value::Array(mut path) => {
if path.is_empty() {
return json!(symbols::ERR_INVALID_PATH);
}
let next = path.remove(0);
if let Value::String(next_name) = next {
if let Some(child) = self.elements.get_mut(&next_name) {
child.send_message(Value::Array(path), message)
} else {
json!(symbols::ERR_CHILD_NOT_FOUND)
}
} else {
json!(symbols::ERR_INVALID_PATH)
}
}
Value::String(target) => {
if let Some(child) = self.elements.get_mut(&target) {
child.send_message(Value::Null, message)
} else {
Value::String("UnsupportedMethod".to_owned())
json!(symbols::ERR_CHILD_NOT_FOUND)
}
}
_ => Value::String("UnsupportedMethod".to_owned()),
_ => json!(symbols::ERR_INVALID_TARGET),
}
}
}
+3
View File
@@ -13,3 +13,6 @@ pub const CMD_GET_CHILDREN: &'static str = symbol!("GetChildren");
pub const ERR_UNSUPPORTED_METHOD: &'static str = symbol!("UnsupportedMethod");
pub const ERR_INVALID_COMMAND: &'static str = symbol!("InvalidCommand");
pub const ERR_INVALID_CHILD: &'static str = symbol!("InvalidChild");
pub const ERR_INVALID_TARGET: &'static str = symbol!("InvalidTarget");
pub const ERR_CHILD_NOT_FOUND: &'static str = symbol!("ChildNotFound");
pub const ERR_INVALID_PATH: &'static str = symbol!("InvalidPath");
+6 -30
View File
@@ -1,9 +1,4 @@
use unshell::{
Value, info,
logger::{Record, log},
obfuscate::{junk_asm, symbol},
tree::{Tree, TreeElement, symbols},
};
use unshell::{info, tree::Tree};
fn main() {
let mut manager = Tree::new();
@@ -12,34 +7,15 @@ fn main() {
info!("Test thing!");
info!("Test thing!");
loop {
if test123(&mut manager) {
break;
}
}
// loop {
// if test123(&mut manager) {
// break;
// }
// }
// println!("Test");
}
fn test123(manager: &mut Tree) -> bool {
let result = manager.send_message(
Value::String(symbol!("Logger").to_string()),
Value::String(symbols::CMD_GET.to_string()),
);
junk_asm!(20.);
let is_null = result.is_null();
if let Ok(result) = serde_json::from_value::<Record>(result) {
log(&result);
}
is_null
// println!("Logger: {}", result);
}
// use std::{any::Any, collections::HashMap, fs::File, io::Read};
// use static_init::dynamic;