Files
unshell/src/tree/branch.rs
T

124 lines
3.8 KiB
Rust
Raw Normal View History

2026-02-16 10:03:23 -07:00
//! Branch - A TreeElement with child elements for hierarchical routing.
2026-02-15 17:59:35 -07:00
use std::collections::HashMap;
use serde_json::{json, Value};
use crate::tree::symbols;
2026-02-16 10:03:23 -07:00
use crate::tree::TreeElement;
2026-02-15 17:59:35 -07:00
2026-02-16 10:03:23 -07:00
/// A branch node in the tree that can contain child elements.
/// Supports path-based routing for multi-hop communication (pivoting).
2026-02-15 17:59:35 -07:00
pub struct Branch {
children: HashMap<String, Box<dyn TreeElement>>,
branch_type: &'static str,
}
2026-02-16 11:21:44 -07:00
impl Default for Branch {
fn default() -> Self {
Self::new("default")
}
}
impl std::fmt::Debug for Branch {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Branch")
.field("branch_type", &self.branch_type)
.field("children", &self.children.keys().collect::<Vec<_>>())
.finish()
}
}
2026-02-15 17:59:35 -07:00
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)
}
}