use crate::disk::*; use serde::{Deserialize, Serialize}; //---------------------------------------------------------------------------------------------------- [Node] Impl impl Node { pub fn localhost() -> Self { Self { ip: "localhost".to_string(), rpc: "18081".to_string(), zmq: "18083".to_string(), } } pub fn new_vec() -> Vec<(String, Self)> { vec![("Local Monero Node".to_string(), Self::localhost())] } pub fn new_tuple() -> (String, Self) { ("Local Monero Node".to_string(), Self::localhost()) } // Convert [String] to [Node] Vec pub fn from_str_to_vec(string: &str) -> Result, TomlError> { let nodes: toml::map::Map = match toml::de::from_str(string) { Ok(map) => { info!("Node | Parse ... OK"); map } Err(err) => { error!("Node | String parse ... FAIL ... {}", err); return Err(TomlError::Deserialize(err)); } }; let size = nodes.keys().len(); let mut vec = Vec::with_capacity(size); for (key, values) in nodes.iter() { let ip = match values.get("ip") { Some(ip) => match ip.as_str() { Some(ip) => ip.to_string(), None => { error!("Node | [None] at [ip] parse"); return Err(TomlError::Parse("[None] at [ip] parse")); } }, None => { error!("Node | [None] at [ip] parse"); return Err(TomlError::Parse("[None] at [ip] parse")); } }; let rpc = match values.get("rpc") { Some(rpc) => match rpc.as_str() { Some(rpc) => rpc.to_string(), None => { error!("Node | [None] at [rpc] parse"); return Err(TomlError::Parse("[None] at [rpc] parse")); } }, None => { error!("Node | [None] at [rpc] parse"); return Err(TomlError::Parse("[None] at [rpc] parse")); } }; let zmq = match values.get("zmq") { Some(zmq) => match zmq.as_str() { Some(zmq) => zmq.to_string(), None => { error!("Node | [None] at [zmq] parse"); return Err(TomlError::Parse("[None] at [zmq] parse")); } }, None => { error!("Node | [None] at [zmq] parse"); return Err(TomlError::Parse("[None] at [zmq] parse")); } }; let node = Node { ip, rpc, zmq }; vec.push((key.clone(), node)); } Ok(vec) } // Convert [Vec<(String, Self)>] into [String] // that can be written as a proper TOML file pub fn to_string(vec: &[(String, Self)]) -> Result { let mut toml = String::new(); for (key, value) in vec.iter() { write!( toml, "[\'{}\']\nip = {:#?}\nrpc = {:#?}\nzmq = {:#?}\n\n", key, value.ip, value.rpc, value.zmq, )?; } Ok(toml) } // Combination of multiple functions: // 1. Attempt to read file from path into [String] // |_ Create a default file if not found // 2. Deserialize [String] into a proper [Struct] // |_ Attempt to merge if deserialization fails pub fn get(path: &PathBuf) -> Result, TomlError> { // Read let file = File::Node; let string = match read_to_string(file, path) { Ok(string) => string, // Create _ => { Self::create_new(path)?; read_to_string(file, path)? } }; // Deserialize, attempt merge if failed Self::from_str_to_vec(&string) } // Completely overwrite current [node.toml] // with a new default version, and return [Vec]. pub fn create_new(path: &PathBuf) -> Result, TomlError> { info!("Node | Creating new default..."); let new = Self::new_vec(); let string = Self::to_string(&Self::new_vec())?; fs::write(path, string)?; info!("Node | Write ... OK"); Ok(new) } // Save [Node] onto disk file [node.toml] pub fn save(vec: &[(String, Self)], path: &PathBuf) -> Result<(), TomlError> { info!("Node | Saving to disk ... [{}]", path.display()); let string = Self::to_string(vec)?; match fs::write(path, string) { Ok(_) => { info!("Node | Save ... OK"); Ok(()) } Err(err) => { error!("Node | Couldn't overwrite file"); Err(TomlError::Io(err)) } } } // pub fn merge(old: &String) -> Result { // info!("Node | Starting TOML merge..."); // let default = match toml::ser::to_string(&Self::new()) { // Ok(string) => { info!("Node | Default TOML parse ... OK"); string }, // Err(err) => { error!("Node | Couldn't parse default TOML into string"); return Err(TomlError::Serialize(err)) }, // }; // let mut new: Self = match Figment::new().merge(Toml::string(&old)).merge(Toml::string(&default)).extract() { // Ok(new) => { info!("Node | TOML merge ... OK"); new }, // Err(err) => { error!("Node | Couldn't merge default + old TOML"); return Err(TomlError::Merge(err)) }, // }; // // Attempt save // Self::save(&mut new)?; // Ok(new) // } } //---------------------------------------------------------------------------------------------------- [Node] Struct #[derive(Clone, Eq, PartialEq, Debug, Deserialize, Serialize)] pub struct Node { pub ip: String, pub rpc: String, pub zmq: String, }