diff --git a/.vscode/launch.json b/.vscode/launch.json index 10efcb2..abb9e2b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,13 +4,17 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ - { - "type": "lldb", - "request": "launch", - "name": "Debug", - "program": "${workspaceFolder}/", - "args": [], - "cwd": "${workspaceFolder}" - } - ] -} \ No newline at end of file + { + "type": "lldb", + "request": "launch", + "name": "run meowy-cli", + "program": "${workspaceFolder}/target/debug/meowy-cli", + "args": ["print"], + "cwd": "${workspaceFolder}", + "sourceMap": {}, + "sourceLanguages": [ + "rust" + ], + } + ] +} diff --git a/Cargo.lock b/Cargo.lock index d7d739a..16629f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,7 +53,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -63,7 +63,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -253,9 +253,11 @@ name = "cli" version = "0.1.0" dependencies = [ "clap", + "log", "serde", "serde_json", "shared", + "simple_logger", ] [[package]] @@ -337,6 +339,27 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "directories" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + [[package]] name = "either" version = "1.8.1" @@ -366,7 +389,7 @@ checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -653,7 +676,7 @@ checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ "hermit-abi 0.3.1", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -665,7 +688,7 @@ dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -744,11 +767,13 @@ version = "0.1.0" dependencies = [ "askama", "askama_rocket", + "log", "rocket", "rust-embed", "serde", "serde_json", "shared", + "simple_logger", ] [[package]] @@ -790,7 +815,7 @@ checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "wasi", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -858,6 +883,12 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "overload" version = "0.1.1" @@ -882,7 +913,7 @@ checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.3.5", "smallvec", "windows-targets", ] @@ -995,6 +1026,15 @@ dependencies = [ "getrandom", ] +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "redox_syscall" version = "0.3.5" @@ -1004,6 +1044,17 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall 0.2.16", + "thiserror", +] + [[package]] name = "ref-cast" version = "1.0.16" @@ -1187,7 +1238,7 @@ dependencies = [ "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1287,6 +1338,8 @@ dependencies = [ name = "shared" version = "0.1.0" dependencies = [ + "directories", + "log", "serde", "serde_json", ] @@ -1300,6 +1353,16 @@ dependencies = [ "libc", ] +[[package]] +name = "simple_logger" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2230cd5c29b815c9b699fb610b49a5ed65588f3509d9f0108be3a885da629333" +dependencies = [ + "log", + "windows-sys 0.42.0", +] + [[package]] name = "slab" version = "0.4.8" @@ -1375,9 +1438,29 @@ dependencies = [ "autocfg", "cfg-if", "fastrand", - "redox_syscall", + "redox_syscall 0.3.5", "rustix", - "windows-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1432,7 +1515,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1707,6 +1790,21 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -1722,51 +1820,93 @@ version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index aa5abe7..40bebfb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,9 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[dependencies] +log = "0.4" + [dependencies.rocket] version = "=0.5.0-rc.3" default_features = false @@ -38,3 +41,7 @@ default-features = false [dependencies.shared] path = "./shared" + +[dependencies.simple_logger] +version = "4" +default-features = false diff --git a/cli/Cargo.toml b/cli/Cargo.toml index a79600c..58e580d 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] serde = "1.0" serde_json = "1.0" +log = "0.4" [dependencies.clap] version = "4" @@ -14,6 +15,10 @@ features = ["derive"] [dependencies.shared] path = "../shared" +[dependencies.simple_logger] +version = "4" +default-features = false + [[bin]] name = "meowy-cli" path = "src/main.rs" diff --git a/cli/src/arguments.rs b/cli/src/arguments.rs index 952da36..5175d19 100644 --- a/cli/src/arguments.rs +++ b/cli/src/arguments.rs @@ -3,8 +3,8 @@ use clap::{arg, command, Args, Parser, Subcommand}; #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] pub(crate) struct Arguments { - #[arg(help = "the path to the names.json file")] - pub(crate) path: String, + #[arg(help = "the path to the names.json file", long, short)] + pub(crate) path: Option, #[command(subcommand)] pub(crate) command: Commands, } @@ -13,8 +13,27 @@ pub(crate) struct Arguments { pub(crate) enum Commands { #[command(about = "print the current webring sites and their names")] Print { + #[arg(help = "url you want to filter to")] + filter: Option, #[command(flatten)] group: PrintGroup, + #[arg( + long, + short, + help = "a seperator character to seperate the url from the name. defaults to ,", + requires = "url", + requires = "name" + )] + seperator: Option, + #[arg( + long, + short, + conflicts_with = "url", + conflicts_with = "name", + conflicts_with = "seperator", + help = "print the data out as a json string" + )] + json: bool, }, #[command(about = "add a site to the webring")] Add { @@ -48,8 +67,8 @@ pub(crate) enum Commands { #[derive(Args, Debug)] #[group(required = false)] pub struct PrintGroup { - #[arg(long, short, action = clap::ArgAction::SetTrue, conflicts_with = "name", help = "print the url only")] + #[arg(long, short, action = clap::ArgAction::SetTrue, help = "print the url only")] pub(crate) url: bool, - #[arg(long, short, action = clap::ArgAction::SetTrue, conflicts_with = "url", help = "print the name only")] + #[arg(long, short, action = clap::ArgAction::SetTrue, help = "print the name only")] pub(crate) name: bool, } diff --git a/cli/src/commands.rs b/cli/src/commands.rs index e2cdebb..24f91c6 100644 --- a/cli/src/commands.rs +++ b/cli/src/commands.rs @@ -1,54 +1,141 @@ -use shared::{ - errors::{Error, ErrorStatus}, - names::Site, -}; +use std::path::Path; + +use shared::errors::ErrorStatus; +use shared::names; +use shared::{errors::Error, names::Site}; use crate::arguments::PrintGroup; -fn read_names(path: &String) -> Result, Error> { - match std::fs::read_to_string(path) { - Ok(names) => { - return shared::names::load_names(names); +fn group_printing(seperator: &Option, site: &Site, group: &PrintGroup) { + let mut string = String::new(); + let delimiter = seperator.unwrap_or(','); + + if group.url { + string += &site.url; + } + + if group.name { + if !string.is_empty() { + string += &format!( + "{}{}", + delimiter, + site.name.as_ref().unwrap_or(&"None".into()) + ) + } else { + string += &site.name.as_ref().unwrap_or(&"None".into()); + } + } + + log::info!("{}", string); +} + +fn json_printing(site: &Site) -> Result<(), Error> { + match serde_json::to_string(&site) { + Ok(json) => { + log::info!("{}", json); + Ok(()) } Err(err) => Err(Error { - status: ErrorStatus::IOError, + status: ErrorStatus::ParsingError, data: err.to_string(), }), } } -pub(crate) fn print(path: &String, group: &PrintGroup) -> Result<(), Error> { - let names = read_names(path)?; +fn filter_site( + site: &Site, + json: bool, + seperator: &Option, + group: &PrintGroup, +) -> Result<(), Error> { + if json { + json_printing(site)?; + return Ok(()); + } - Ok(for site in names { - if group.name { - println!("{}", site.name.unwrap_or_default()); - continue; - } - if group.url { - println!("{}", site.url); - continue; - } - println!("{:?}", site); - }) + if !group.url && !group.name { + log::info!("{:?}", site); + return Ok(()); + } + + return Ok(group_printing(seperator, site, group)); } -pub(crate) fn add(path: &String, url: &String, name: &Option) -> Result<(), Error> { - let mut names = read_names(path)?; +pub(crate) fn print( + path: &Path, + filter: &Option, + group: &PrintGroup, + seperator: &Option, + json: bool, +) -> Result<(), Error> { + let names_file = names::read_names_file(path)?; + let mut names = names::load_names(names_file)?; + + if let Some(filter) = filter { + names.retain(|f| &f.url == filter); + if names.len() == 0 { + return Err(Error { + status: ErrorStatus::NotFoundError, + data: "this url was not found in names.json".into(), + }); + } + return filter_site(&names[0], json, seperator, group); + } + + for site in names { + if json { + json_printing(&site)?; + continue; + } + + if !group.url && !group.name { + log::info!("{:?}", site); + continue; + } + + group_printing(seperator, &site, group); + } + + Ok(()) +} + +pub(crate) fn add(path: &Path, url: &String, name: &Option) -> Result<(), Error> { + let names_file = names::read_names_file(path)?; + let mut names = names::load_names(names_file)?; + + if names.iter().any(|site| site.url.contains(url)) { + return Err(Error { + status: ErrorStatus::AlreadyExistsError, + data: + "this url already exists in names.json. you can't have more then 1 of the same url." + .into(), + }); + } + let site = Site { url: url.to_string(), name: name.to_owned(), }; - names.push(site); + log::debug!("adding {:?} to {}", site, path.display()); + names.push(site.clone()); let json = serde_json::to_string(&names).unwrap(); std::fs::write(path, json).unwrap(); + log::info!("added {:?} to names.json", site); Ok(()) } -pub(crate) fn remove(path: &String, url: &String) -> Result<(), Error> { - let mut names = read_names(path)?; - names.retain(|site| &site.url != url); +pub(crate) fn remove(path: &Path, url: &String) -> Result<(), Error> { + let names_file = names::read_names_file(path)?; + let mut names = names::load_names(names_file)?; + + names.retain(|site| { + if &site.url == url { + log::info!("removing {:?} from names.json", site); + } + &site.url != url + }); let json = serde_json::to_string(&names).unwrap(); std::fs::write(path, json).unwrap(); + Ok(()) } diff --git a/cli/src/logging.rs b/cli/src/logging.rs new file mode 100644 index 0000000..112ccf6 --- /dev/null +++ b/cli/src/logging.rs @@ -0,0 +1,18 @@ +use log::LevelFilter; +use shared::errors::{Error, ErrorStatus}; +use simple_logger::SimpleLogger; + +pub fn initialize_logger() -> Result<(), Error> { + if let Err(err) = SimpleLogger::new() + .with_level(LevelFilter::Info) + .env() + .init() + { + return Err(Error { + status: ErrorStatus::LoggerInitializationError, + data: err.to_string(), + }); + } + + Ok(()) +} diff --git a/cli/src/main.rs b/cli/src/main.rs index 621e6b3..84d4e48 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,18 +1,28 @@ +use std::path::Path; use arguments::{Arguments, Commands}; use clap::Parser; use commands::{add, print, remove}; -use shared::errors::Error; +use shared::{directories, errors::Error}; mod arguments; mod commands; +mod logging; -fn main() -> Result<(), Error> { +fn main() -> Result<(), Error> { + logging::initialize_logger()?; + + let default_path = directories::get_names_path()?; let args = Arguments::parse(); + let path = match &args.path { + Some(path) => Path::new(path), + None => &default_path, + }; + match &args.command { - Commands::Print { group } => print(&args.path, &group)?, - Commands::Add { url, name } => add(&args.path, url, name)?, - Commands::Remove { url } => remove(&args.path, url)?, + Commands::Print { filter, group, seperator, json, } => print(path, filter, group, seperator, *json)?, + Commands::Add { url, name } => add(path, url, name)?, + Commands::Remove { url } => remove(path, url)?, }; Ok(()) diff --git a/shared/Cargo.toml b/shared/Cargo.toml index aa08613..aba26a9 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -5,6 +5,8 @@ edition = "2021" [dependencies] serde_json = "1.0" +directories = "5.0" +log = "0.4" [dependencies.serde] version = "1.0" diff --git a/shared/src/directories.rs b/shared/src/directories.rs new file mode 100644 index 0000000..8f56795 --- /dev/null +++ b/shared/src/directories.rs @@ -0,0 +1,40 @@ +use std::path::{Path, PathBuf}; + +use directories::ProjectDirs; + +use crate::errors::{Error, ErrorStatus, DIRECTORIES_ERROR_MESSAGE}; + +pub fn get_project_dir() -> Result { + match ProjectDirs::from("moe", "solarpunk", "meowy-webring") { + Some(project) => Ok(project), + None => Err(Error { + status: ErrorStatus::DirectoriesError, + data: DIRECTORIES_ERROR_MESSAGE.into(), + }), + } +} + +pub fn get_file_from_directory(path: &Path, filename: &str) -> Result { + if !path.exists() { + create_directory(path)?; + } + Ok(path.join(filename)) +} + +pub fn get_names_path() -> Result { + let directory = get_project_dir()?; + return get_file_from_directory(directory.data_dir(), "names.json"); +} + +fn create_directory(path: &Path) -> Result<(), Error> { + match std::fs::create_dir_all(path) { + Ok(_) => { + log::debug!("created the directory {}", path.display()); + Ok(()) + } + Err(err) => Err(Error { + status: ErrorStatus::IOError, + data: err.to_string(), + }), + } +} diff --git a/shared/src/errors.rs b/shared/src/errors.rs index 8a033d5..aa744fe 100644 --- a/shared/src/errors.rs +++ b/shared/src/errors.rs @@ -1,16 +1,26 @@ #[derive(Debug)] pub enum ErrorStatus { IOError, - ParsingError + ParsingError, + DirectoriesError, + LoggerInitializationError, + NotFoundError, + AlreadyExistsError } pub struct Error { pub status: ErrorStatus, - pub data: String + pub data: String, } +pub(crate) static DIRECTORIES_ERROR_MESSAGE: &str = "could not retreive a valid home path from the operating system. maybe try to define the HOME enviroment variable if you\'re on a unix or unix like operating system."; + impl core::fmt::Debug for Error { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "A {:?} error has occured.\nDetails: {}", self.status, self.data) - } + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "A {:?} error has occured.\nDetails: {}", + self.status, self.data + ) + } } diff --git a/shared/src/lib.rs b/shared/src/lib.rs index c986a43..cc9af96 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -1,2 +1,3 @@ pub mod names; pub mod errors; +pub mod directories; diff --git a/shared/src/names.rs b/shared/src/names.rs index 6408d6c..734587e 100644 --- a/shared/src/names.rs +++ b/shared/src/names.rs @@ -1,8 +1,8 @@ -use serde::{Deserialize, Serialize}; - use crate::errors::{Error, ErrorStatus}; +use serde::{Deserialize, Serialize}; +use std::path::Path; -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub struct Site { pub url: String, pub name: Option, @@ -10,10 +10,50 @@ pub struct Site { pub fn load_names(names: String) -> Result, Error> { match serde_json::from_str::>(&names) { - Ok(content) => Ok(content), + Ok(content) => { + log::debug!("successfully parsed names.json."); + Ok(content) + } Err(err) => Err(Error { status: ErrorStatus::ParsingError, data: err.to_string(), }), } } + +pub fn read_names_file(path: &Path) -> Result { + if !path.exists() { + log::debug!( + "the names.json file does not exist at {}. creating names.json", + path.display() + ); + create_names_file(path)? + } + + match std::fs::read_to_string(path) { + Ok(data) => { + log::debug!( + "successfully read the names.json file at {}", + path.display() + ); + Ok(data) + } + Err(err) => Err(Error { + status: ErrorStatus::IOError, + data: err.to_string(), + }), + } +} + +fn create_names_file(path: &Path) -> Result<(), Error> { + match std::fs::write(path, "[]") { + Ok(_) => { + log::debug!("created a names.json file at {}", path.display()); + Ok(()) + } + Err(err) => Err(Error { + status: ErrorStatus::IOError, + data: err.to_string(), + }), + } +} diff --git a/src/main.rs b/src/main.rs index ae43a88..505df51 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +use shared::{directories, names}; + #[macro_use] extern crate rocket; @@ -7,8 +9,11 @@ mod routes; #[launch] fn rocket() -> _ { - let names_file = std::fs::read_to_string("names.json").unwrap(); - let names = shared::names::load_names(names_file).unwrap(); + let names_path = directories::get_names_path().unwrap(); + println!("names.json path: {}", names_path.display()); + let names_file = names::read_names_file(&names_path).unwrap(); + let names = names::load_names(names_file).unwrap(); + rocket::build() .manage(names) .mount(