summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Tay <sam.chong.tay@gmail.com>2020-06-04 23:04:02 -0700
committerSam Tay <sam.chong.tay@gmail.com>2020-06-04 23:04:02 -0700
commit6efe775ca619b9c08b260d709168694ef3bcf42b (patch)
treee0093af27a6b07eb4c8ae698f7f68b74a413fef0
parente95add7bf9d25b0623399fe689b0d692959b8553 (diff)
Move cli stuff into its own module
-rw-r--r--TODO.md1
-rw-r--r--src/cli.rs80
-rw-r--r--src/main.rs83
3 files changed, 86 insertions, 78 deletions
diff --git a/TODO.md b/TODO.md
index 93a79d8..dac2516 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,7 +1,6 @@
# TODO
### initial release
-0. move cli to cli module
0. Install sites when file not found
0. Implement --update-sites command
3. Parse markdown (`pulldown_cmark`)
diff --git a/src/cli.rs b/src/cli.rs
new file mode 100644
index 0000000..bc522f0
--- /dev/null
+++ b/src/cli.rs
@@ -0,0 +1,80 @@
+use clap::{App, AppSettings, Arg, ArgMatches};
+
+// TODO maybe consts for these keywords?
+
+// TODO pull defaults from config file
+// TODO --set-api-key KEY
+// TODO --update-sites
+// TODO --install-filter-key --force
+// TODO --sites plural
+// TODO --add-site (in addition to defaults)
+//?TODO --set-default-opt opt val # e.g. --set-default-opt sites site1;site2;site3
+pub fn mk_app<'a, 'b>() -> App<'a, 'b> {
+ App::new("so")
+ .setting(AppSettings::ColoredHelp)
+ .version(clap::crate_version!())
+ .author(clap::crate_authors!())
+ .about(clap::crate_description!())
+ .arg(
+ Arg::with_name("list-sites")
+ .long("list-sites")
+ .help("Print available StackExchange sites"),
+ )
+ .arg(
+ Arg::with_name("site")
+ .long("site")
+ .short("s")
+ .multiple(true)
+ .number_of_values(1)
+ .takes_value(true)
+ .default_value("stackoverflow")
+ .help("StackExchange site code to search"), // TODO sites plural
+ )
+ .arg(
+ Arg::with_name("limit")
+ .long("limit")
+ .short("l")
+ .number_of_values(1)
+ .takes_value(true)
+ .default_value("1")
+ .validator(|s| s.parse::<u32>().map_err(|e| e.to_string()).map(|_| ()))
+ .help("Question limit per site query")
+ .hidden(true), // TODO unhide once more than just --lucky
+ )
+ .arg(
+ Arg::with_name("lucky")
+ .long("lucky")
+ .help("Print the top-voted answer of the most relevant question")
+ .hidden(true), // TODO unhide
+ )
+ .arg(
+ Arg::with_name("query")
+ .multiple(true)
+ .index(1)
+ .required(true)
+ .required_unless("list-sites"),
+ )
+}
+
+pub fn get_query(matches: ArgMatches) -> Option<String> {
+ let q = matches
+ .values_of("query")?
+ .into_iter()
+ .collect::<Vec<_>>()
+ .join(" ");
+ Some(q)
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_cli() {
+ let m = mk_app().get_matches_from(vec![
+ "so", "--site", "meta", "how", "do", "I", "exit", "Vim",
+ ]);
+ assert_eq!(m.value_of("site"), Some("meta"));
+ assert_eq!(get_query(m).unwrap(), "how do I exit Vim");
+ }
+}
diff --git a/src/main.rs b/src/main.rs
index 083fca0..8dd0b59 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,86 +1,23 @@
-use clap::{App, AppSettings, Arg};
-
+mod cli;
mod config;
mod stackexchange;
use config::Config;
use stackexchange::StackExchange;
-// TODO maybe consts for these keywords?
-
-// TODO pull defaults from config file
-// TODO --set-api-key KEY
-// TODO --update-sites
-// TODO --install-filter-key --force
-// TODO --sites plural
-// TODO --add-site (in addition to defaults)
-//?TODO --set-default-opt opt val # e.g. --set-default-opt sites site1;site2;site3
-fn mk_app<'a, 'b>() -> App<'a, 'b> {
- App::new("so")
- .setting(AppSettings::ColoredHelp)
- .version(clap::crate_version!())
- .author(clap::crate_authors!())
- .about(clap::crate_description!())
- .arg(
- Arg::with_name("list-sites")
- .long("list-sites")
- .help("Print available StackExchange sites"),
- )
- .arg(
- Arg::with_name("site")
- .long("site")
- .short("s")
- .multiple(true)
- .number_of_values(1)
- .takes_value(true)
- .default_value("stackoverflow")
- .help("StackExchange site code to search"), // TODO sites plural
- )
- .arg(
- Arg::with_name("limit")
- .long("limit")
- .short("l")
- .number_of_values(1)
- .takes_value(true)
- .default_value("1")
- .validator(|s| s.parse::<u32>().map_err(|e| e.to_string()).map(|_| ()))
- .help("Question limit per site query")
- .hidden(true), // TODO unhide once more than just --lucky
- )
- .arg(
- Arg::with_name("lucky")
- .long("lucky")
- .help("Print the top-voted answer of the most relevant question")
- .hidden(true), // TODO unhide
- )
- .arg(
- Arg::with_name("query")
- .multiple(true)
- .index(1)
- .required(true)
- .required_unless("list-sites"),
- )
-}
-
fn main() {
- let matches = mk_app().get_matches();
+ let matches = cli::mk_app().get_matches();
// TODO merge config from ArgMatch
let se = StackExchange::new(Config {
api_key: String::from("8o9g7WcfwnwbB*Qp4VsGsw(("),
- filter: String::from("0euqgThy5XMKqGfXzPS_nVSuunbQUZLlX7OuNJSlfvlW4"),
limit: 1,
site: String::from("stackoverflow"),
});
(|| -> Option<_> {
- let q = matches
- .values_of("query")?
- .into_iter()
- .collect::<Vec<_>>()
- .join(" ");
- println!("{}", q);
- let que = se.search(&q).ok()?;
+ let q = cli::get_query(matches)?;
+ let que = se.search(&q).unwrap(); // TODO eventually be graceful
let ans = que.first()?.answers.first()?;
println!("{}", ans.body);
Some(())
@@ -89,17 +26,9 @@ fn main() {
#[cfg(test)]
mod tests {
- use super::*;
#[test]
- fn test_cli() {
- let m = mk_app().get_matches_from(vec![
- "so", "--site", "meta", "how", "do", "I", "exit", "Vim",
- ]);
- assert_eq!(m.value_of("site"), Some("meta"));
- assert_eq!(
- m.values_of("query").unwrap().collect::<Vec<_>>().join(" "),
- "how do I exit Vim"
- );
+ fn test_main() {
+ //TODO
}
}