diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cli.rs | 31 | ||||
-rw-r--r-- | src/config.rs | 29 | ||||
-rw-r--r-- | src/main.rs | 15 |
3 files changed, 39 insertions, 36 deletions
@@ -4,16 +4,12 @@ use crate::config; use crate::config::Config; use crate::error::Result; -// TODO maybe consts for these keywords? - -// TODO --set-api-key KEY -// TODO --update-sites -// TODO --install-filter-key --force // TODO --sites plural // TODO --add-site (in addition to defaults) pub struct Opts { pub list_sites: bool, pub update_sites: bool, + pub set_api_key: Option<String>, pub query: Option<String>, pub config: Config, } @@ -37,10 +33,17 @@ pub fn get_opts() -> Result<Opts> { .help("Update cache of StackExchange sites"), ) .arg( + Arg::with_name("set-api-key") + .long("set-api-key") + .number_of_values(1) + .takes_value(true) + .help("Set StackExchange API key"), + ) + .arg( Arg::with_name("site") .long("site") .short("s") - .multiple(true) + .multiple(false) // TODO sites plural .number_of_values(1) .takes_value(true) .default_value(&config.site) @@ -67,27 +70,27 @@ pub fn get_opts() -> Result<Opts> { Arg::with_name("query") .multiple(true) .index(1) - .required_unless_one(&["list-sites", "update-sites"]), + .required_unless_one(&["list-sites", "update-sites", "set-api-key"]), ) .get_matches(); Ok(Opts { list_sites: matches.is_present("list-sites"), update_sites: matches.is_present("update-sites"), + set_api_key: matches.value_of("set-api-key").map(String::from), query: matches .values_of("query") .map(|q| q.collect::<Vec<_>>().join(" ")), config: Config { // these unwraps are safe via clap default values & validators limit: matches.value_of("limit").unwrap().parse::<u16>().unwrap(), - site: matches.value_of("site").unwrap().to_string(), - // TODO if set_api_key passed, pass it here too - ..config + site: matches.value_of("site").unwrap().to_string(), // TODO values_of + api_key: matches + .value_of("set-api-key") + .map(String::from) + .or(config.api_key), }, }) } -#[cfg(test)] -mod tests { - // TODO how can I test this now that it depends on user dir? -} +// TODO how can I test this App given https://users.rust-lang.org/t/help-with-idiomatic-rust-and-ownership-semantics/43880 diff --git a/src/config.rs b/src/config.rs index cb77086..0f09699 100644 --- a/src/config.rs +++ b/src/config.rs @@ -2,6 +2,7 @@ use directories::ProjectDirs; use serde::{Deserialize, Serialize}; use std::fs; use std::fs::File; +use std::path::PathBuf; use crate::error::{Error, Result}; @@ -27,18 +28,27 @@ pub fn user_config() -> Result<Config> { let project = project_dir()?; let dir = project.config_dir(); fs::create_dir_all(&dir).map_err(|_| Error::create_dir(&dir.to_path_buf()))?; - let filename = dir.join("config.yml"); + let filename = config_file_name()?; match File::open(&filename) { Err(_) => { - let file = File::create(&filename).map_err(|_| Error::create_file(&filename))?; let def = Config::default(); - serde_yaml::to_writer(file, &def).map_err(|_| Error::write_file(&filename))?; + write_config(&def)?; Ok(def) } Ok(file) => serde_yaml::from_reader(file).map_err(|_| Error::malformed(&filename)), } } +fn write_config(config: &Config) -> Result<()> { + let filename = config_file_name()?; + let file = File::create(&filename).map_err(|_| Error::create_file(&filename))?; + serde_yaml::to_writer(file, config).map_err(|_| Error::write_file(&filename)) +} + +fn config_file_name() -> Result<PathBuf> { + Ok(project_dir()?.config_dir().join("config.yml")) +} + /// Get project directory pub fn project_dir() -> Result<ProjectDirs> { ProjectDirs::from("io", "Sam Tay", "so").ok_or_else(|| { @@ -49,13 +59,8 @@ pub fn project_dir() -> Result<ProjectDirs> { }) } -#[cfg(test)] -mod tests { - // TODO test malformed filter string - // TODO test malformed api key - // for both, detect situation and print helpful error message - #[test] - fn test_merge_configs() { - assert!(true) - } +pub fn set_api_key(key: String) -> Result<()> { + let mut cfg = user_config()?; + cfg.api_key = Some(key); + write_config(&cfg) } diff --git a/src/main.rs b/src/main.rs index 8ce16cc..57d561c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,6 +23,10 @@ fn main() { let site = &config.site; let mut ls = LocalStorage::new()?; + if let Some(key) = opts.set_api_key { + config::set_api_key(key)?; + } + if opts.update_sites { ls.update_sites()?; } @@ -88,7 +92,7 @@ fn main() { this shouldn't be possible!", ) })?; - // TODO eventually do this in the right place, e.g. abstract out md parser & do within threads + // TODO eventually do this in the right place, e.g. abstract out md parser, write benches, & do within threads let md = ans.body.replace("<kbd>", "**[").replace("</kbd>", "]**"); skin.print_text(&md); } @@ -104,12 +108,3 @@ fn main() { println!("panic! {}", e.error); }); } - -#[cfg(test)] -mod tests { - - #[test] - fn test_main() { - //TODO - } -} |