RON database manager
at main 103 lines 3.1 kB view raw
1mod args; 2use args::{CLIArgs, Command}; 3use clap::Parser; 4use ron::error::Error; 5use ron::error::SpannedError; 6use ron::ser; 7use ron::ser::PrettyConfig; 8use std::{collections::HashMap, fs, io, path::PathBuf}; 9 10/* === Types === */ 11enum QueryError { 12 ParseError(String), 13 FileMissing(PathBuf), 14 KeyMissing(String), 15 IOError(io::Error), 16} 17 18impl From<SpannedError> for QueryError { 19 fn from(e: SpannedError) -> Self { 20 QueryError::ParseError(format!( 21 "Parse error at position: {}. In code: {}", 22 e.position, e.code 23 )) 24 } 25} 26 27impl From<Error> for QueryError { 28 fn from(e: Error) -> Self { 29 QueryError::ParseError(format!( 30 "Parse error: {}", 31 match e { 32 Error::Message(string) => string, 33 _ => "".to_string(), 34 } 35 )) 36 } 37} 38 39impl QueryError { 40 fn display(&self) { 41 match self { 42 QueryError::ParseError(string) => eprintln!("{string}"), 43 QueryError::FileMissing(path) => eprintln!("File missing: {}", path.display()), 44 QueryError::IOError(err) => eprintln!("{err}"), 45 QueryError::KeyMissing(key) => eprintln!("The following key was not found: {key}"), 46 } 47 } 48} 49 50type RonMap = HashMap<String, String>; 51 52/* === Functions === */ 53 54#[warn(clippy::pedantic, clippy::unwrap_used, clippy::perf)] 55pub fn handle_query(config: PathBuf) { 56 match check_config(config.clone()) { 57 Ok(ron_map) => match query_resources(ron_map, config) { 58 Ok(string) => println!("{string}"), 59 Err(e) => e.display(), 60 }, 61 Err(e) => e.display(), 62 } 63} 64 65#[warn(clippy::pedantic, clippy::unwrap_used, clippy::perf)] 66fn check_config(config: PathBuf) -> Result<RonMap, QueryError> { 67 match config.try_exists() { 68 Ok(exists) => { 69 if exists { 70 let contents = 71 fs::read_to_string(config).expect("Query exists and has proper permissions."); 72 Ok(ron::from_str(&contents)?) 73 } else { 74 Err(QueryError::FileMissing(config)) 75 } 76 } 77 Err(e) => Err(QueryError::IOError(e)), 78 } 79} 80 81#[warn(clippy::pedantic, clippy::unwrap_used, clippy::perf)] 82fn query_resources(mut map: RonMap, config: PathBuf) -> Result<String, QueryError> { 83 let args = CLIArgs::parse(); 84 85 match args.command { 86 Command::All => Ok(ser::to_string_pretty(&map, PrettyConfig::default())?), 87 Command::Get(key) => match map.get_key_value(&key.key) { 88 Some(entry) => Ok(entry.1.to_string()), 89 None => Err(QueryError::KeyMissing(key.key)), 90 }, 91 Command::Set(key_val) => { 92 let key = key_val.key; 93 let value = key_val.value; 94 map.insert(key.clone(), value.clone()); 95 let pretty = ser::to_string_pretty(&map, PrettyConfig::default())?; 96 97 match fs::write(config, pretty) { 98 Ok(()) => Ok(format!("\"{key}\": \"{value}\"")), 99 Err(e) => Err(QueryError::IOError(e)), 100 } 101 } 102 } 103}