RON database manager

refactored code to be more expressive

Sunglas 11fddac3 9d8f18ab

+467 -66
+1
.gitignore
··· 1 + target/
+335
Cargo.lock
··· 1 + # This file is automatically @generated by Cargo. 2 + # It is not intended for manual editing. 3 + version = 3 4 + 5 + [[package]] 6 + name = "anstream" 7 + version = "0.6.4" 8 + source = "registry+https://github.com/rust-lang/crates.io-index" 9 + checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" 10 + dependencies = [ 11 + "anstyle", 12 + "anstyle-parse", 13 + "anstyle-query", 14 + "anstyle-wincon", 15 + "colorchoice", 16 + "utf8parse", 17 + ] 18 + 19 + [[package]] 20 + name = "anstyle" 21 + version = "1.0.4" 22 + source = "registry+https://github.com/rust-lang/crates.io-index" 23 + checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" 24 + 25 + [[package]] 26 + name = "anstyle-parse" 27 + version = "0.2.2" 28 + source = "registry+https://github.com/rust-lang/crates.io-index" 29 + checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" 30 + dependencies = [ 31 + "utf8parse", 32 + ] 33 + 34 + [[package]] 35 + name = "anstyle-query" 36 + version = "1.0.0" 37 + source = "registry+https://github.com/rust-lang/crates.io-index" 38 + checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" 39 + dependencies = [ 40 + "windows-sys", 41 + ] 42 + 43 + [[package]] 44 + name = "anstyle-wincon" 45 + version = "3.0.1" 46 + source = "registry+https://github.com/rust-lang/crates.io-index" 47 + checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" 48 + dependencies = [ 49 + "anstyle", 50 + "windows-sys", 51 + ] 52 + 53 + [[package]] 54 + name = "base64" 55 + version = "0.21.5" 56 + source = "registry+https://github.com/rust-lang/crates.io-index" 57 + checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" 58 + 59 + [[package]] 60 + name = "bitflags" 61 + version = "1.3.2" 62 + source = "registry+https://github.com/rust-lang/crates.io-index" 63 + checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 64 + 65 + [[package]] 66 + name = "bitflags" 67 + version = "2.4.1" 68 + source = "registry+https://github.com/rust-lang/crates.io-index" 69 + checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" 70 + dependencies = [ 71 + "serde", 72 + ] 73 + 74 + [[package]] 75 + name = "cfg-if" 76 + version = "1.0.0" 77 + source = "registry+https://github.com/rust-lang/crates.io-index" 78 + checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 79 + 80 + [[package]] 81 + name = "clap" 82 + version = "4.4.7" 83 + source = "registry+https://github.com/rust-lang/crates.io-index" 84 + checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" 85 + dependencies = [ 86 + "clap_builder", 87 + "clap_derive", 88 + ] 89 + 90 + [[package]] 91 + name = "clap_builder" 92 + version = "4.4.7" 93 + source = "registry+https://github.com/rust-lang/crates.io-index" 94 + checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" 95 + dependencies = [ 96 + "anstream", 97 + "anstyle", 98 + "clap_lex", 99 + "strsim", 100 + ] 101 + 102 + [[package]] 103 + name = "clap_derive" 104 + version = "4.4.7" 105 + source = "registry+https://github.com/rust-lang/crates.io-index" 106 + checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" 107 + dependencies = [ 108 + "heck", 109 + "proc-macro2", 110 + "quote", 111 + "syn", 112 + ] 113 + 114 + [[package]] 115 + name = "clap_lex" 116 + version = "0.6.0" 117 + source = "registry+https://github.com/rust-lang/crates.io-index" 118 + checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" 119 + 120 + [[package]] 121 + name = "colorchoice" 122 + version = "1.0.0" 123 + source = "registry+https://github.com/rust-lang/crates.io-index" 124 + checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 125 + 126 + [[package]] 127 + name = "heck" 128 + version = "0.4.1" 129 + source = "registry+https://github.com/rust-lang/crates.io-index" 130 + checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 131 + 132 + [[package]] 133 + name = "libc" 134 + version = "0.2.150" 135 + source = "registry+https://github.com/rust-lang/crates.io-index" 136 + checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" 137 + 138 + [[package]] 139 + name = "nix" 140 + version = "0.26.4" 141 + source = "registry+https://github.com/rust-lang/crates.io-index" 142 + checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" 143 + dependencies = [ 144 + "bitflags 1.3.2", 145 + "cfg-if", 146 + "libc", 147 + ] 148 + 149 + [[package]] 150 + name = "proc-macro2" 151 + version = "1.0.69" 152 + source = "registry+https://github.com/rust-lang/crates.io-index" 153 + checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" 154 + dependencies = [ 155 + "unicode-ident", 156 + ] 157 + 158 + [[package]] 159 + name = "quote" 160 + version = "1.0.33" 161 + source = "registry+https://github.com/rust-lang/crates.io-index" 162 + checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 163 + dependencies = [ 164 + "proc-macro2", 165 + ] 166 + 167 + [[package]] 168 + name = "rdbm" 169 + version = "0.1.1" 170 + dependencies = [ 171 + "clap", 172 + "ron", 173 + "serde", 174 + "serde_derive", 175 + "xdg-home", 176 + ] 177 + 178 + [[package]] 179 + name = "ron" 180 + version = "0.8.1" 181 + source = "registry+https://github.com/rust-lang/crates.io-index" 182 + checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" 183 + dependencies = [ 184 + "base64", 185 + "bitflags 2.4.1", 186 + "serde", 187 + "serde_derive", 188 + ] 189 + 190 + [[package]] 191 + name = "serde" 192 + version = "1.0.190" 193 + source = "registry+https://github.com/rust-lang/crates.io-index" 194 + checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" 195 + dependencies = [ 196 + "serde_derive", 197 + ] 198 + 199 + [[package]] 200 + name = "serde_derive" 201 + version = "1.0.190" 202 + source = "registry+https://github.com/rust-lang/crates.io-index" 203 + checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" 204 + dependencies = [ 205 + "proc-macro2", 206 + "quote", 207 + "syn", 208 + ] 209 + 210 + [[package]] 211 + name = "strsim" 212 + version = "0.10.0" 213 + source = "registry+https://github.com/rust-lang/crates.io-index" 214 + checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 215 + 216 + [[package]] 217 + name = "syn" 218 + version = "2.0.38" 219 + source = "registry+https://github.com/rust-lang/crates.io-index" 220 + checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" 221 + dependencies = [ 222 + "proc-macro2", 223 + "quote", 224 + "unicode-ident", 225 + ] 226 + 227 + [[package]] 228 + name = "unicode-ident" 229 + version = "1.0.12" 230 + source = "registry+https://github.com/rust-lang/crates.io-index" 231 + checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 232 + 233 + [[package]] 234 + name = "utf8parse" 235 + version = "0.2.1" 236 + source = "registry+https://github.com/rust-lang/crates.io-index" 237 + checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 238 + 239 + [[package]] 240 + name = "winapi" 241 + version = "0.3.9" 242 + source = "registry+https://github.com/rust-lang/crates.io-index" 243 + checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 244 + dependencies = [ 245 + "winapi-i686-pc-windows-gnu", 246 + "winapi-x86_64-pc-windows-gnu", 247 + ] 248 + 249 + [[package]] 250 + name = "winapi-i686-pc-windows-gnu" 251 + version = "0.4.0" 252 + source = "registry+https://github.com/rust-lang/crates.io-index" 253 + checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 254 + 255 + [[package]] 256 + name = "winapi-x86_64-pc-windows-gnu" 257 + version = "0.4.0" 258 + source = "registry+https://github.com/rust-lang/crates.io-index" 259 + checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 260 + 261 + [[package]] 262 + name = "windows-sys" 263 + version = "0.48.0" 264 + source = "registry+https://github.com/rust-lang/crates.io-index" 265 + checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 266 + dependencies = [ 267 + "windows-targets", 268 + ] 269 + 270 + [[package]] 271 + name = "windows-targets" 272 + version = "0.48.5" 273 + source = "registry+https://github.com/rust-lang/crates.io-index" 274 + checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 275 + dependencies = [ 276 + "windows_aarch64_gnullvm", 277 + "windows_aarch64_msvc", 278 + "windows_i686_gnu", 279 + "windows_i686_msvc", 280 + "windows_x86_64_gnu", 281 + "windows_x86_64_gnullvm", 282 + "windows_x86_64_msvc", 283 + ] 284 + 285 + [[package]] 286 + name = "windows_aarch64_gnullvm" 287 + version = "0.48.5" 288 + source = "registry+https://github.com/rust-lang/crates.io-index" 289 + checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 290 + 291 + [[package]] 292 + name = "windows_aarch64_msvc" 293 + version = "0.48.5" 294 + source = "registry+https://github.com/rust-lang/crates.io-index" 295 + checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 296 + 297 + [[package]] 298 + name = "windows_i686_gnu" 299 + version = "0.48.5" 300 + source = "registry+https://github.com/rust-lang/crates.io-index" 301 + checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 302 + 303 + [[package]] 304 + name = "windows_i686_msvc" 305 + version = "0.48.5" 306 + source = "registry+https://github.com/rust-lang/crates.io-index" 307 + checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 308 + 309 + [[package]] 310 + name = "windows_x86_64_gnu" 311 + version = "0.48.5" 312 + source = "registry+https://github.com/rust-lang/crates.io-index" 313 + checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 314 + 315 + [[package]] 316 + name = "windows_x86_64_gnullvm" 317 + version = "0.48.5" 318 + source = "registry+https://github.com/rust-lang/crates.io-index" 319 + checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 320 + 321 + [[package]] 322 + name = "windows_x86_64_msvc" 323 + version = "0.48.5" 324 + source = "registry+https://github.com/rust-lang/crates.io-index" 325 + checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 326 + 327 + [[package]] 328 + name = "xdg-home" 329 + version = "1.0.0" 330 + source = "registry+https://github.com/rust-lang/crates.io-index" 331 + checksum = "2769203cd13a0c6015d515be729c526d041e9cf2c0cc478d57faee85f40c6dcd" 332 + dependencies = [ 333 + "nix", 334 + "winapi", 335 + ]
+1
Cargo.toml
··· 10 10 ron = "0.8" 11 11 serde = "1.0.136" 12 12 serde_derive = "1.0.136" 13 + xdg-home = "1.0.0"
+14 -14
src/args.rs src/dbm/args.rs
··· 1 1 use clap::{Args, Parser, Subcommand}; 2 2 3 + #[derive(Debug, Args)] 4 + pub struct Key { 5 + pub key: String, 6 + } 7 + 8 + #[derive(Debug, Args)] 9 + pub struct KeyVal { 10 + pub key: String, 11 + pub value: String, 12 + } 13 + 3 14 #[derive(Debug, Parser)] 4 15 #[clap(author, version, about)] 5 - pub struct ResArgs { 16 + pub struct CLIArgs { 6 17 #[clap(subcommand)] 7 18 /// this is a subcommand 8 - pub option: EntityType, 19 + pub command: Command, 9 20 } 10 21 11 22 #[derive(Debug, Subcommand)] 12 - pub enum EntityType { 23 + pub enum Command { 13 24 /// Retrieve the value associated with <KEY> from resource file 14 25 Get(Key), 15 26 /// Set a <VALUE> for a given <KEY> in the resource file (will print to stdout the associated ··· 18 29 /// Pretty print the entire resource file 19 30 All, 20 31 } 21 - 22 - #[derive(Debug, Args)] 23 - pub struct Key { 24 - pub key: String, 25 - } 26 - 27 - #[derive(Debug, Args)] 28 - pub struct KeyVal { 29 - pub key: String, 30 - pub value: String, 31 - }
+103
src/dbm.rs
··· 1 + mod args; 2 + use args::{CLIArgs, Command}; 3 + use clap::Parser; 4 + use ron::error::Error; 5 + use ron::error::SpannedError; 6 + use ron::ser; 7 + use ron::ser::PrettyConfig; 8 + use std::{collections::HashMap, fs, io, path::PathBuf}; 9 + 10 + /* === Types === */ 11 + enum QueryError { 12 + ParseError(String), 13 + FileMissing(PathBuf), 14 + KeyMissing(String), 15 + IOError(io::Error), 16 + } 17 + 18 + impl 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 + 27 + impl 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 + 39 + impl 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 + 50 + type RonMap = HashMap<String, String>; 51 + 52 + /* === Functions === */ 53 + 54 + #[warn(clippy::pedantic, clippy::unwrap_used, clippy::perf)] 55 + pub 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)] 66 + fn 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)] 82 + fn 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 + }
+13 -52
src/main.rs
··· 1 - mod args; 2 - use args::{EntityType, ResArgs}; 3 - use clap::Parser; 4 - use std::collections::HashMap; 5 - use std::fs; 6 - use std::process::exit; 1 + mod dbm; 2 + use dbm::handle_query; 3 + use std::{env, path::PathBuf}; 4 + use xdg_home::home_dir; 7 5 8 6 #[warn(clippy::pedantic, clippy::unwrap_used, clippy::perf)] 9 7 fn main() { 10 - const CONFIG_LOCATION: &str = "/home/sol/.config/resources.ron"; 11 - let Ok(contents) = fs::read_to_string(CONFIG_LOCATION) else { 12 - eprintln!("Could not read config at `{CONFIG_LOCATION}`."); 13 - exit(1) 14 - }; 15 - 16 - let mut data: HashMap<String, String> = if let Ok(map) = ron::from_str(&contents) { 17 - map 18 - } else { 19 - eprintln!("Could not parse config at `{CONFIG_LOCATION}`."); 20 - exit(1) 21 - }; 22 - 23 - let args = ResArgs::parse(); 8 + let config_path: PathBuf = match env::var("XDG_CONFIG_HOME") { 9 + Ok(path) => path.into(), 10 + Err(_) => match home_dir() { 11 + Some(path) => path, 12 + None => "".into(), 13 + }, 14 + } 15 + .join("resources.ron"); 24 16 25 - match args.option { 26 - EntityType::All => { 27 - println!("{data:#?}"); 28 - } 29 - 30 - EntityType::Get(user_key) => { 31 - let value = if let Some(entry) = data.get_key_value(&user_key.key) { 32 - entry.1 33 - } else { 34 - eprintln!("Could not find `{}` in config file.", user_key.key); 35 - exit(1) 36 - }; 37 - print!("{value}"); 38 - } 39 - 40 - EntityType::Set(user_keyval) => { 41 - let key = user_keyval.key; 42 - let value = user_keyval.value; 43 - data.insert(key.clone(), value.clone()); 44 - let Ok(pretty) = ron::ser::to_string_pretty(&data, ron::ser::PrettyConfig::default()) else { 45 - eprintln!("Could not parse map to string."); 46 - exit(1) 47 - }; 48 - 49 - if let Ok(()) = fs::write(CONFIG_LOCATION, pretty.clone()) { 50 - println!("\"{}\": \"{}\"", key, value); 51 - } else { 52 - eprintln!("Error writing file."); 53 - exit(1) 54 - }; 55 - } 56 - } 17 + handle_query(config_path); 57 18 }