diff --git a/src/tree/branch.rs b/src/tree/branch.rs new file mode 100644 index 0000000..26ed80c --- /dev/null +++ b/src/tree/branch.rs @@ -0,0 +1,105 @@ +use std::collections::HashMap; + +use serde_json::{json, Value}; + +use crate::tree::symbols; + +pub struct Branch { + children: HashMap>, + 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, child: Box) { + self.children.insert(name.into(), child); + } + + pub fn with_child(mut self, name: impl Into, child: Box) -> Self { + self.add_child(name, child); + self + } + + pub fn get_child(&mut self, name: &str) -> Option<&mut Box> { + self.children.get_mut(name) + } + + pub fn children(&self) -> &HashMap> { + &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::>(); + 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; diff --git a/src/tree/log.rs b/src/tree/log.rs index 99faaa1..b277882 100644 --- a/src/tree/log.rs +++ b/src/tree/log.rs @@ -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); diff --git a/src/tree/mod.rs b/src/tree/mod.rs index e563166..76b271b 100644 --- a/src/tree/mod.rs +++ b/src/tree/mod.rs @@ -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; 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::>(); - 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), } } } diff --git a/src/tree/symbols.rs b/src/tree/symbols.rs index 50ec788..8c83e24 100644 --- a/src/tree/symbols.rs +++ b/src/tree/symbols.rs @@ -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"); diff --git a/ush-payload/src/main.rs b/ush-payload/src/main.rs index ed57533..e37c2bd 100644 --- a/ush-payload/src/main.rs +++ b/ush-payload/src/main.rs @@ -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::(result) { - log(&result); - } - - is_null - - // println!("Logger: {}", result); -} - // use std::{any::Any, collections::HashMap, fs::File, io::Read}; // use static_init::dynamic;