diff --git a/src/error.rs b/src/error.rs index 7cb4dbd..1bfcdf6 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; +use std::fmt::format; use std::string::FromUtf8Error; use toml::Value; use colored::Colorize; @@ -46,7 +47,7 @@ fn parse_errors() -> HashMap{ panic!("category value exists in errors.toml on error obect with code {}, but is not a String", code) }; - let error = MizeError{code, message, category, extra_msg: None, caused_by_msg: None, code_location: None}; + let error = MizeError{code, message, category, extra_msg: Vec::new(), caused_by_msg: None, code_location: None}; map.insert(code, error); } @@ -63,7 +64,7 @@ pub struct MizeError { pub category: String, pub code: u32, pub message: String, - pub extra_msg: Option, + pub extra_msg: Vec, pub caused_by_msg: Option, pub code_location: Option, } @@ -104,15 +105,17 @@ impl MizeError { category: "error with error system".to_string(), code: 114, message: format!("The error with code {} was not found in the Errors that where imported from the errors.toml file at build time.", code), - extra_msg: None, + extra_msg: Vec::new(), caused_by_msg: None, code_location: Some(caller_location.into()), }; } } - pub fn extra_msg(mut self, msg: &str) -> MizeError { - self.extra_msg = Some(msg.to_string()); + pub fn extra_msg(mut self, msg: E) -> MizeError + where E: std::fmt::Display + { + self.extra_msg.push(format!("{}", msg)); return self; } @@ -145,6 +148,10 @@ impl MizeError { return self.send().add_to_err_item().write_to_stderr(); } + pub fn is_critical(self){ + panic!("Aborting because of a critical Error") + } + pub fn to_json(&self) -> JsonValue{ if let Ok(string) = serde_json::to_string(self) { if let Ok(json) = serde_json::from_str(&string) { @@ -174,6 +181,40 @@ impl MizeError { } } +pub trait MizeResultExtension { + fn extra_msg(self, msg: E) -> Result + where E: std::fmt::Display + ; + fn handle(self) -> Result; + + fn is_critical(self) -> T; +} + +impl MizeResultExtension for Result { + fn extra_msg(mut self, msg: E) -> Result + where E: std::fmt::Display + { + match self { + Err(ref mut e) => { + e.extra_msg.push(format!("{}", msg)); + return self; + }, + Ok(something) => Ok(something), + } + } + fn handle(self) -> Result { + match self { + Err(e) => { + Err(e.send().add_to_err_item().write_to_stderr()) + }, + Ok(something) => Ok(something) + } + } + fn is_critical(self) -> T { + self.expect("Aborting because of a critical Error") + } +} + impl From for MizeError { fn from(utf_err: FromUtf8Error) -> MizeError{ MizeError::new(109).extra_msg("std::string::FromUtf8Error while parsing something from the message") @@ -195,3 +236,4 @@ impl From for MizeError { + diff --git a/src/server.rs b/src/server.rs index efcdbe7..c6428bf 100644 --- a/src/server.rs +++ b/src/server.rs @@ -15,10 +15,12 @@ use crate::error::MizeError; use crate::error::ERRORS; use crate::server::proto::MizeMessage; use crate::server::proto::MizeId; +use crate::error::MizeResultExtension; use serde_json::Value as JsonValue; use serde::{Serialize, Deserialize}; -use uuid; +use uuid::Uuid; +use std::str::FromStr; use tokio::sync::mpsc::{Sender, channel, Receiver}; use tokio_stream::wrappers::ReceiverStream; @@ -103,7 +105,7 @@ impl Peer { #[derive(Clone, Debug)] pub struct Upstream { - id: uuid::Uuid, + id: Uuid, } #[derive(Clone, Debug)] @@ -175,7 +177,7 @@ pub struct Mutexes { //maybe a list of upstream servers?? itemstore: Arc>, mize_folder: String, - server_uuid: uuid::Uuid, + server_uuid: Uuid, } impl Mutexes { @@ -212,13 +214,9 @@ pub async fn run_server(args: Vec) { } } - //create the itemstore - let itemstore = crate::server::itemstore::Itemstore::new(mize_folder.clone() + "/db").await.expect("error creating itemstore"); - //create mize.toml with id inside in folder if net yet done - let server_uuid = uuid::Uuid::new_v4(); + let (server_uuid, itemstore, renders) = init_server(mize_folder.clone()).await.extra_msg("Could not init server").handle().is_critical(); - let renders = load_mr(mize_folder.clone()).expect("Error loading Modules and Renders"); // Collection of all the things, that most functions need let mutexes: Mutexes = Mutexes { @@ -544,5 +542,62 @@ fn load_mr(mize_folder: String) -> Result, MizeError> { return Ok((renders)); } +async fn init_server(mize_folder: String) -> Result<(Uuid, Itemstore, Vec), MizeError> { + + let server_uuid; + + //create mize.toml with id inside in folder if net yet done + match fs::read_to_string(format!("{}/mize.toml", mize_folder)) { + Err(err) => { + match err.kind() { + std::io::ErrorKind::NotFound => { + //create the file with new uuid + server_uuid = uuid::Uuid::new_v4(); + let mut toml_val = toml::Value::Table(toml::map::Map::new()); + toml_val.as_table_mut() + .ok_or(MizeError::new(11))? + .insert("uuid".to_owned(), toml::Value::String(server_uuid.to_string())); + + fs::write(format!("{}/mize.toml", mize_folder), toml::to_string(&toml_val) + .map_err(|e| MizeError::new(11).extra_msg(e))?) + .map_err(|e| MizeError::new(11).extra_msg(e))?; + + } + _ => { + server_uuid = uuid::Uuid::new_v4(); + Err(err) + .map_err(|e| MizeError::new(11).extra_msg(e)) + .extra_msg("Could not read /mize.toml file")?; + } + } + }, + Ok(toml_string) => { + let mut toml_val = toml_string.parse::().map_err(|e| MizeError::new(11).extra_msg(e))?; + + if let Some(uuid) = toml_val.get("uuid") { + server_uuid = Uuid::from_str(uuid.as_str().ok_or(MizeError::new(11))?) + .map_err(|e| MizeError::new(11).extra_msg(e))?; + } else { + //generate uuid and write that to toml file + server_uuid = uuid::Uuid::new_v4(); + toml_val.as_table_mut().ok_or(MizeError::new(11))?.insert("uuid".to_owned(), toml::Value::String(server_uuid.to_string())); + + fs::write(format!("{}/mize.toml", mize_folder), toml::to_string(&toml_val) + .map_err(|e| MizeError::new(11).extra_msg(e))?) + .map_err(|e| MizeError::new(11).extra_msg(e))?; + } + }, + }; + + //create the itemstore + let itemstore = crate::server::itemstore::Itemstore::new(mize_folder.clone() + "/rocksdb").await.expect("error creating itemstore"); + + let renders = load_mr(mize_folder.clone()) + .map_err(|e| MizeError::new(11)) + .extra_msg("Error loading Modules and Renders")?; + + return Ok((server_uuid, itemstore, renders)); +} +