summaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
authorSam Tay <sam.chong.tay@gmail.com>2020-06-06 19:55:23 -0700
committerSam Tay <sam.chong.tay@gmail.com>2020-06-07 02:21:54 -0700
commit799936479d3e80237c6e6595baade9737e137011 (patch)
treed74d5bad458d08cfd2f74f125c4c45fd3128d82c /src/main.rs
parent735fd480e43d6037f3ae7890c2795fdf0e431fd7 (diff)
Propagate errors throughout app
and add stdout styles via crossterm
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs117
1 files changed, 74 insertions, 43 deletions
diff --git a/src/main.rs b/src/main.rs
index e9f0d99..e48323d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,63 +1,94 @@
mod cli;
mod config;
+mod error;
+mod macros;
mod stackexchange;
+mod term;
use config::Config;
+use error::{Error, ErrorKind};
use stackexchange::{LocalStorage, StackExchange};
+use std::io::stderr;
+use term::ColoredOutput;
fn main() {
- // TODO wrap inner function with Result<(), ErrorMessage>, propagate, print to stderr at the top level.
- let opts = cli::get_opts();
- let config = opts.config;
- let site = &config.site;
- let mut ls = LocalStorage::new();
+ (|| {
+ let opts = cli::get_opts()?;
+ let config = opts.config;
+ let site = &config.site;
+ let mut ls = LocalStorage::new()?;
- if opts.update_sites {
- ls.update_sites();
- }
+ if opts.update_sites {
+ ls.update_sites()?;
+ }
- if opts.list_sites {
- let sites = ls.sites();
- match sites.into_iter().map(|s| s.api_site_parameter.len()).max() {
- Some(max_w) => {
- for s in ls.sites() {
- println!("{:>w$}: {}", s.api_site_parameter, s.site_url, w = max_w);
+ if opts.list_sites {
+ let sites = ls.sites()?;
+ match sites.into_iter().map(|s| s.api_site_parameter.len()).max() {
+ Some(max_w) => {
+ for s in sites {
+ println!("{:>w$}: {}", s.api_site_parameter, s.site_url, w = max_w);
+ }
+ }
+ None => {
+ stderr()
+ .queue_error("The site list is empty. Try running ")
+ .queue_code_inline("so --update-sites")
+ .unsafe_flush();
}
}
- None => {
- // TODO stderr
- println!("The site list is empty. Try running `so --update-sites`.");
+ return Ok(());
+ }
+
+ match ls.validate_site(site) {
+ Ok(true) => (),
+ Ok(false) => {
+ stderr()
+ .queue_error(&format!("{} is not a valid StackExchange site.\n\n", site)[..])
+ .queue_notice("If you think this is in error, try running\n\n")
+ .queue_code("so --update-sites\n\n")
+ .queue_notice_inline("to update the cached site listing. You can also run ")
+ .queue_code_inline("so --list-sites")
+ .queue_notice_inline(" to list all available sites.")
+ .unsafe_flush();
+ return Ok(());
}
+ Err(Error {
+ kind: ErrorKind::EmptySites,
+ ..
+ }) => {
+ stderr()
+ .queue_error("The cached site list is empty. This can likely be fixed by\n\n")
+ .queue_code("so --update-sites\n\n")
+ .unsafe_flush();
+ return Ok(());
+ }
+ Err(e) => return Err(e),
}
- return;
- }
- // TODO make this validation optional
- if !ls.validate_site(site) {
- // TODO tooling for printing to stderr with color, etc.
- println!(
- "{} is not a valid StackExchange site. If you think this
- is in error, try running `so --update-sites` to update
- the cached site listing. Run `so --list-sites` for all
- available sites.",
- site
- );
- return;
- }
+ let se = StackExchange::new(Config {
+ api_key: Some(String::from("8o9g7WcfwnwbB*Qp4VsGsw((")), // TODO remove when releasing
+ ..config
+ });
- let se = StackExchange::new(Config {
- api_key: Some(String::from("8o9g7WcfwnwbB*Qp4VsGsw((")), // TODO stash this
- ..config
- });
+ if let Some(q) = opts.query {
+ let que = se.search(&q)?;
+ let ans = que
+ .first()
+ .ok_or(Error::no_results())?
+ .answers
+ .first()
+ .ok_or(Error::from(
+ "StackExchange returned a question with no answers; this shouldn't be possible!",
+ ))?;
+ println!("{}", ans.body);
+ }
- let query = opts.query;
- (|| -> Option<_> {
- let q = query?;
- let que = se.search(&q).unwrap(); // TODO eventually be graceful
- let ans = que.first()?.answers.first()?;
- println!("{}", ans.body);
- Some(())
- })();
+ Ok(())
+ })()
+ .unwrap_or_else(|e| match e {
+ Error { error, .. } => printerr!(error),
+ })
}
#[cfg(test)]