From 11c0f7e00eec82057810206e8b8af9cb0060f556 Mon Sep 17 00:00:00 2001 From: Sebastian Moser Date: Sat, 8 Jun 2024 13:54:50 +0200 Subject: [PATCH] some bug fixes of not the most clean code + random things --- src/core/error.rs | 1 + src/core/instance/mod.rs | 14 +++++--- src/core/instance/store.rs | 2 +- src/core/item.rs | 67 ++++++++++++++++++++++-------------- src/core/memstore.rs | 70 +++++++++++++++++++++++++++++--------- src/platform/os/cli/get.rs | 8 ++++- src/platform/os/main.rs | 4 +++ src/platform/os/mod.rs | 14 ++++---- 8 files changed, 125 insertions(+), 55 deletions(-) diff --git a/src/core/error.rs b/src/core/error.rs index cb6c318..a154f78 100644 --- a/src/core/error.rs +++ b/src/core/error.rs @@ -14,6 +14,7 @@ pub type MizeResult = Result; pub trait MizeResultTrait { fn critical(self) -> T; } + pub trait IntoMizeResult { fn mize_result(self) -> MizeResult; fn mize_result_msg(self, msg: S) -> MizeResult where S: std::fmt::Display ; diff --git a/src/core/instance/mod.rs b/src/core/instance/mod.rs index 4a389cf..ba07242 100644 --- a/src/core/instance/mod.rs +++ b/src/core/instance/mod.rs @@ -79,6 +79,8 @@ impl Instance { } pub fn with_config(config: ItemData) -> MizeResult> { + trace!("[ {} ] Instance::with_config()", "CALL".yellow()); + trace!("config: {}", config); let mut instance = Instance::empty(); instance.set("0", config.clone()); instance.init()?; @@ -87,7 +89,8 @@ impl Instance { debug!("overwriting instance config again with the one passed to Instance::with_config()"); instance.set("0", config); - debug!("instance inited with conifg: {}", instance.get("0/config")?.as_data_full()?); + //debug!("instance inited with conifg: {}", instance.get("0/config")?); + debug!("instance inited with conifg: no"); Ok(instance) } @@ -96,17 +99,20 @@ impl Instance { impl Instance { pub fn new_item(&self) -> MizeResult> { let id = self.id_from_string(self.store.new_id()?); - return Ok(Item {id, instance: self}); + return Ok(Item::new(id, &self)); } pub fn get>(&self, id: I) -> MizeResult> { let id = id.to_mize_id(self); - return Ok(Item {id: id.to_mize_id(self), instance: self}); + return Ok(Item::new(id, &self)); } pub fn set, V: Into>(&mut self, id: I, value: V) -> MizeResult<()> { let id = id.to_mize_id(self); - self.store.set(id, value) + let item_data = value.into(); + let mut item = self.get(id.clone())?; + item.merge(item_data)?; + Ok(()) } pub fn new_id>(&self, value: T) -> MizeId { diff --git a/src/core/instance/store.rs b/src/core/instance/store.rs index cf5568e..6ce202d 100644 --- a/src/core/instance/store.rs +++ b/src/core/instance/store.rs @@ -9,7 +9,7 @@ pub trait Store { // is implemented, so that there can be a multithreaded implementation //fn get(self, id: MizeId) -> MizeResult> where Self: Sized; - fn set>(&mut self, id: MizeId, data: T) -> MizeResult<()>; + fn set>(&self, id: MizeId, data: T) -> MizeResult<()>; // in the future should implement transactions, .... diff --git a/src/core/item.rs b/src/core/item.rs index 63867de..52ddb17 100644 --- a/src/core/item.rs +++ b/src/core/item.rs @@ -19,7 +19,7 @@ use ciborium::Value as CborValue; // a item always has to do with a Instance, which takes care of how it is updated #[derive(Debug)] pub struct Item<'a, S: Store + Sized> { - pub id: MizeId, + id: MizeId, pub instance: &'a Instance } @@ -33,6 +33,10 @@ impl Item<'_, S> { self.id.clone() } + pub fn new(id: MizeId, instance: &Instance) -> Item { + Item { id, instance } + } + pub fn value_raw(&self) -> MizeResult> { // this will call from the instance which gets the value from the store self.instance.store.get_value_raw(self.id()) @@ -40,17 +44,21 @@ impl Item<'_, S> { pub fn as_data_full(&self) -> MizeResult { self.instance.store.get_value_data_full(self.id()) } + pub fn merge>(&mut self, mut value: V) -> MizeResult<()> { + //trace!("[ {} ] Item.merge()", "CALL".yellow()); + let mut old_data = self.instance.store.get_value_data_full(self.id())?; + //trace!("old_data: {:?}", old_data); + old_data.merge(value.into()); + //trace!("new_data: {:?}", old_data); + self.instance.store.set(self.id(), old_data)?; + Ok(()) + } } impl Display for Item<'_, S> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self.value_raw() { - Ok(value) => match String::from_utf8(value.to_owned()) { - Ok(string) => write!(f, "{}", string), - Err(_) => write!(f, "{:?}", self.value_raw()), - } - Err(err) => {err.log(); Ok(())}, - }; + let item_data = self.as_data_full().map_err(|_| std::fmt::Error)?; + write!(f, "{}", item_data); return Ok(()); } } @@ -83,7 +91,7 @@ impl ItemData { } pub fn set_path(&mut self, path: P, value: D) -> MizeResult<()> { - trace!("[ {} ] ItemData::set_path()", "CALL".yellow()); + //trace!("[ {} ] ItemData::set_path()", "CALL".yellow()); let path = path.into_path(); let value = value.into_item_data(); @@ -103,6 +111,7 @@ fn item_data_get_path(data: &CborValue, path: Vec) -> MizeResult<&CborVa Some(val) => val, None => return Ok(data), // our base case }; + let mut sub_data = &CborValue::Null; match data { CborValue::Map(ref map) => { @@ -120,22 +129,21 @@ fn item_data_get_path(data: &CborValue, path: Vec) -> MizeResult<&CborVa .msg(format!("{:?} is: {:?}", path_el, val))); }, }; - path_iter.next(); item_data_get_path(sub_data, path_iter.collect()) } -fn item_data_set_path(data: &mut CborValue, path: Vec, new_data: &CborValue) -> MizeResult<()> { - trace!("[ {} ] item_data_set_path", "CALL".yellow()); - trace!("[ {} ] data: {}", "ARG".yellow(), data.clone().into_item_data()); - trace!("[ {} ] path: {:?}", "ARG".yellow(), path); - trace!("[ {} ] new_data: {}", "ARG".yellow(), new_data.clone().into_item_data()); +fn item_data_set_path(data: &mut CborValue, path: Vec, data_to_set: &CborValue) -> MizeResult<()> { + //trace!("[ {} ] item_data_set_path()", "CALL".yellow()); + //trace!("[ {} ] data: {}", "ARG".yellow(), data.clone().into_item_data()); + //trace!("[ {} ] path: {:?}", "ARG".yellow(), path); + //trace!("[ {} ] data_to_set: {}", "ARG".yellow(), data_to_set.clone().into_item_data()); let mut path_iter = path.clone().into_iter(); let path_el = match path_iter.nth(0) { Some(val) => val, None => { // our base case - *data = new_data.to_owned(); + *data = data_to_set.to_owned(); return Ok(()); }, }; @@ -145,15 +153,19 @@ fn item_data_set_path(data: &mut CborValue, path: Vec, new_data: &CborVa if let CborValue::Text(key_str) = key { if key_str == &path_el { path_iter.next(); - return item_data_set_path(val, path_iter.collect(), new_data) + return item_data_set_path(val, path_iter.collect(), data_to_set); } } } }, CborValue::Null => { - let map_vec = vec![(CborValue::Text(path_el), CborValue::Null)]; + let mut inner_value = CborValue::Null; + item_data_set_path(&mut inner_value, path_iter.collect(), data_to_set); + + let map_vec = vec![(CborValue::Text(path_el), inner_value)]; *data = CborValue::Map(map_vec); - return item_data_set_path(data, path, new_data); + + return Ok(()); }, val => { return Err(MizeError::new() @@ -165,15 +177,14 @@ fn item_data_set_path(data: &mut CborValue, path: Vec, new_data: &CborVa } fn item_data_merge(first: &mut ItemData, other: ItemData){ + //trace!("[ {} ] item_data_merge()", "CALL".yellow()); + //trace!("[ {} ] first: {}", "ARG".yellow(), first.clone().into_item_data()); + //trace!("[ {} ] other: {}", "ARG".yellow(), other.clone().into_item_data()); + match first.0 { - _ => { - *first = other; - }, CborValue::Map(ref mut map) => { + //trace!("data is a map: {:?}", map); match other.0 { - _ => { - *first = other; - } CborValue::Map(mut other_map) => { let mut to_add = Vec::new(); for (other_key, other_val) in other_map.clone() { @@ -190,8 +201,14 @@ fn item_data_merge(first: &mut ItemData, other: ItemData){ } other_map.extend(to_add); }, + _ => { + *first = other; + } } }, + _ => { + *first = other; + }, } } diff --git a/src/core/memstore.rs b/src/core/memstore.rs index 87f4aee..1ee45c5 100644 --- a/src/core/memstore.rs +++ b/src/core/memstore.rs @@ -4,6 +4,7 @@ use std::iter::Map; use std::sync::{Arc, Mutex}; use ciborium::Value as CborValue; use log::trace; +use colored::Colorize; use crate::id::MizeId; use crate::instance::store::Store; @@ -24,10 +25,9 @@ struct MemStoreInner { } impl Store for MemStore { - fn set>(&mut self, id: MizeId, data: T) -> MizeResult<()> { + fn set>(&self, id: MizeId, data: T) -> MizeResult<()> { let mut inner = self.inner.lock()?; - inner.map.insert(id_to_u64(id)?, data.into()); return Ok(()) } @@ -65,8 +65,19 @@ impl Store for MemStore { fn get_value_data_full(&self, id: MizeId) -> MizeResult { let inner = self.inner.lock()?; - inner.map.get(&id_to_u64(id.clone())?) - .ok_or(MizeError::new().msg(format!("Item wich id '{}' has not data stored in this MemStore", id.clone()))).cloned() + + let data = match inner.map.get(&id_to_u64(id.clone())?) { + Some(val) => val.to_owned(), + None => ItemData::new(), + }; + + let tmp = id.path(); + let mut path_iter = tmp.into_iter(); + path_iter.next(); + let new_path: Vec = path_iter.map(|v| v.to_owned()).collect(); + let ret_data = data.get_path(new_path)?; + + return Ok(ret_data); } } @@ -84,31 +95,56 @@ fn id_to_u64(id: MizeId) -> MizeResult { } fn get_raw_from_cbor<'a>(value: &'a CborValue, path: Vec<&String>) -> MizeResult<&'a [u8]> { + trace!("[ {} ] get_raw_from_cbor()", "CALL".yellow()); + trace!("[ {} ] value: {:?}", "ARG".yellow(), value); + trace!("[ {} ] path: {:?}", "ARG".yellow(), path); + + let mut path_iter = path.clone().into_iter(); + let path_el = match path_iter.nth(0) { + Some(val) => val, + None => { + // our base case + return Err(MizeError::new().msg("path is empty")); + }, + }; + trace!("hoooooooo: {:?}", path_el); + match value { - CborValue::Bytes(vec) => Ok(&vec[..]), - CborValue::Text(string) => Ok(string.as_bytes()), + CborValue::Bytes(vec) => { + trace!("[ {} ] ret value: {:?}", "RET".yellow(), &vec[..]); + return Ok(&vec[..]); + }, + CborValue::Text(string) => { + trace!("[ {} ] ret value: {:?}", "RET".yellow(), string.as_bytes()); + return Ok(string.as_bytes()); + }, CborValue::Map(map) => { let mut inner_val: &CborValue = &CborValue::Null; - for (key, val) in map.into_iter() { - let first_path_string = *path.iter().nth(0) - .ok_or(MizeError::new() - .msg("get_raw_from_cbor: path is empty"))?; + let mut inner_val_found = false; + // find the inner_val at path + for (key, val) in map.into_iter() { if let CborValue::Text(key_text) = key { - if key_text == first_path_string { - inner_val = val + if key_text == path_el { + inner_val = val; + inner_val_found = true; } } } - if inner_val == &CborValue::Null { + + // if there is no value at that path + if inner_val_found == false { return Err(MizeError::new() // jesus christ, this is a pfusch... - .msg(format!("get_raw_from_cbor: Path {} not Found", path.clone().into_iter().map(|v| v.to_owned()).collect::>().join("/")))) + .msg(format!("get_raw_from_cbor: Path '{}' not Found", path.clone().into_iter().map(|v| v.to_owned()).collect::>().join("/")))) } - let mut path_iter = path.into_iter(); - path_iter.next(); + + //path_iter.next(); let inner_path = path_iter.collect(); - get_raw_from_cbor(inner_val, inner_path) + trace!("hiiiiii: {:?}", inner_path); + let ret_value = get_raw_from_cbor(inner_val, inner_path); + trace!("[ {} ] ret value: {:?}", "RET".yellow(), ret_value); + return ret_value; }, _ => Err(MizeError::new().msg("get_raw_from_cbor: value is not Bytes, Text or Map")), } diff --git a/src/platform/os/cli/get.rs b/src/platform/os/cli/get.rs index 41219e4..afda78c 100644 --- a/src/platform/os/cli/get.rs +++ b/src/platform/os/cli/get.rs @@ -18,7 +18,13 @@ pub fn get(sub_matches: &ArgMatches) -> MizeResult<()> { let item = instance.get(id)?; - println!("{}", item); + let recurse_count = sub_matches.get_count("recurse"); + if recurse_count > 0 { + println!("{}", item.id()); + println!("{}", item.as_data_full()?); + } else { + println!("{}", item); + }; return Ok(()); } diff --git a/src/platform/os/main.rs b/src/platform/os/main.rs index 1ba76f5..a079f58 100644 --- a/src/platform/os/main.rs +++ b/src/platform/os/main.rs @@ -318,6 +318,10 @@ fn cli_matches() -> clap::ArgMatches { Command::new("get") .aliases(["g"]) .arg(Arg::new("id").help("The id or path to get")) + .arg(Arg::new("recurse") + .short('r') + .action(ArgAction::Count) + ) ) .subcommand( Command::new("set") diff --git a/src/platform/os/mod.rs b/src/platform/os/mod.rs index 6a6210f..d1b3c5b 100644 --- a/src/platform/os/mod.rs +++ b/src/platform/os/mod.rs @@ -15,14 +15,13 @@ use crate::item::{ItemData, IntoItemData}; pub fn os_instance_init(instance: &mut Instance) -> MizeResult<()> { // this is the code, that runs to initialize an Instance on a system with an os present. - let mut config = ItemData::new(); - ////// load MIZE_CONFIG_FILE as the instance, which is item 0 match std::env::var("MIZE_CONFIG_FILE") { Ok(config_file_path) => { - config.merge(config_from_file(config_file_path)?); + let config = config_from_file(config_file_path)?; debug!("env var MIZE_CONFIG_FILE present"); - trace!("config after MIZE_CONFIG_FILE env var: {}", config); + instance.set("0", config)?; + trace!("config after MIZE_CONFIG_FILE env var: {}", instance.get("0/config")?); } Err(var_err) => match var_err { VarError::NotPresent => { @@ -37,9 +36,10 @@ pub fn os_instance_init(instance: &mut Instance) -> MizeResult<()> ////// load config from MIZE_CONFIG env var match std::env::var("MIZE_CONFIG") { Ok(config_string) => { - config.merge(config_from_string(config_string)?); + let config = config_from_string(config_string)?; debug!("env var MIZE_CONFIG present"); - trace!("config after MIZE_CONFIG env var: {}", config); + instance.set("0", config)?; + trace!("config after MIZE_CONFIG env var: {}", instance.get("0/config")?); } Err(var_err) => match var_err { VarError::NotPresent => { @@ -52,7 +52,6 @@ pub fn os_instance_init(instance: &mut Instance) -> MizeResult<()> }; - instance.set("0", config)?; return Ok(()); } @@ -99,6 +98,7 @@ fn config_from_string(config_string: String) -> MizeResult { .ok_or(MizeError::new().msg(format!("Failed to parse Option: option '{}' has an empty value (thing after =)", option)))?; let mut path_vec = vec!["config"]; path_vec.extend(path.split(".")); + println!("path_vec: {:?}", path_vec); config.set_path(path_vec, ItemData::parse(value))?; }