summaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
authorSam Tay <sam.chong.tay@gmail.com>2020-06-17 23:30:33 -0700
committerSam Tay <sam.chong.tay@gmail.com>2020-06-17 23:30:33 -0700
commitec92f930344d364e3be359a41aebea78f8205fa7 (patch)
treeb041fa1404d383d44be46c9e1f4e8e94ef75e254 /src/main.rs
parentd422c8424ae76fc85e0fdf55257e0cee7fa38271 (diff)
Use async http requests via tokio
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs131
1 files changed, 65 insertions, 66 deletions
diff --git a/src/main.rs b/src/main.rs
index 06cacd8..27c7109 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -14,76 +14,14 @@ use stackexchange::{LocalStorage, StackExchange};
use term::mk_print_error;
use termimad::{CompoundStyle, MadSkin};
-fn main() {
+#[tokio::main]
+async fn main() -> Result<(), Error> {
let mut skin = MadSkin::default();
// TODO style configuration
skin.inline_code = CompoundStyle::with_fg(Color::Cyan);
skin.code_block.set_fgbg(Color::Cyan, termimad::gray(20));
let mut print_error = mk_print_error(&skin);
- (|| {
- let opts = cli::get_opts()?;
- let config = opts.config;
- let site = &config.site;
- let lucky = config.lucky;
- 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()?;
- }
-
- if opts.list_sites {
- let sites = ls.sites()?;
- let mut md = String::new();
- md.push_str("|:-:|:-:|\n");
- md.push_str("|Site Code|Site URL|\n");
- md.push_str("|-:|:-|\n");
- for s in sites.iter() {
- md.push_str(&format!("|{}|{}\n", s.api_site_parameter, s.site_url));
- }
- md.push_str("|-\n");
- termimad::print_text(&md);
- return Ok(());
- }
-
- if !ls.validate_site(site)? {
- print_error!(skin, "$0 is not a valid StackExchange site.\n\n", site)?;
- // TODO should only use inline for single lines; use termimad::text stuff
- print_notice!(
- skin,
- "If you think this is incorrect, try running\n\
- ```\n\
- so --update-sites\n\
- ```\n\
- to update the cached site listing. You can also run `so --list-sites` \
- to list all available sites.",
- )?;
- return Ok(());
- }
-
- if let Some(q) = opts.query {
- let se = StackExchange::new(config);
- // TODO get the rest of the results in the background
- if lucky {
- // TODO this needs preprocessing; all the more reason to do it at SE level
- let md = se.search_lucky(&q)?;
- skin.print_text(&md);
- skin.print_text(
- "\nPress **[SPACE]** to see more results, or any other key to exit",
- );
- if !utils::wait_for_char(' ')? {
- return Ok(());
- }
- }
- let qs = se.search(&q)?;
- tui::run(qs)?;
- }
- Ok(())
- })()
- .or_else(|e: Error| {
+ run(&mut skin).await.or_else(|e: Error| {
print_error(&e.to_string())?;
match e {
Error::EmptySites => {
@@ -92,5 +30,66 @@ fn main() {
_ => Ok(()),
}
})
- .unwrap();
+}
+
+async fn run(skin: &mut MadSkin) -> Result<(), Error> {
+ let opts = cli::get_opts()?;
+ let config = opts.config;
+ let site = &config.site;
+ let lucky = config.lucky;
+ 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().await?;
+ }
+
+ if opts.list_sites {
+ let sites = ls.sites().await?;
+ let mut md = String::new();
+ md.push_str("|:-:|:-:|\n");
+ md.push_str("|Site Code|Site URL|\n");
+ md.push_str("|-:|:-|\n");
+ for s in sites.iter() {
+ md.push_str(&format!("|{}|{}\n", s.api_site_parameter, s.site_url));
+ }
+ md.push_str("|-\n");
+ termimad::print_text(&md);
+ return Ok(());
+ }
+
+ if !ls.validate_site(site).await? {
+ print_error!(skin, "$0 is not a valid StackExchange site.\n\n", site)?;
+ // TODO should only use inline for single lines; use termimad::text stuff
+ print_notice!(
+ skin,
+ "If you think this is incorrect, try running\n\
+ ```\n\
+ so --update-sites\n\
+ ```\n\
+ to update the cached site listing. You can also run `so --list-sites` \
+ to list all available sites.",
+ )?;
+ return Ok(());
+ }
+
+ if let Some(q) = opts.query {
+ let se = StackExchange::new(config);
+ // TODO get the rest of the results in the background
+ if lucky {
+ // TODO this needs preprocessing; all the more reason to do it at SE level
+ let md = se.search_lucky(&q).await?;
+ skin.print_text(&md);
+ skin.print_text("\nPress **[SPACE]** to see more results, or any other key to exit");
+ if !utils::wait_for_char(' ')? {
+ return Ok(());
+ }
+ }
+ let qs = se.search(&q).await?;
+ tui::run(qs)?;
+ }
+ Ok(())
}