diff options
-rw-r--r-- | Cargo.lock | 132 | ||||
-rw-r--r-- | Cargo.toml | 3 | ||||
-rw-r--r-- | src/error.rs | 10 | ||||
-rw-r--r-- | src/macros.rs | 32 | ||||
-rw-r--r-- | src/main.rs | 30 | ||||
-rw-r--r-- | src/term.rs | 10 |
6 files changed, 208 insertions, 9 deletions
@@ -159,6 +159,66 @@ dependencies = [ ] [[package]] +name = "crossbeam" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e" +dependencies = [ + "cfg-if", + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cced8691919c02aac3cb0a1bc2e9b73d89e832bf9a06fc579d4e71b68a2da061" +dependencies = [ + "crossbeam-utils", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-deque" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "lazy_static", + "maybe-uninit", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-queue" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab6bffe714b6bb07e42f201352c34f51fefd355ace793f9e638ebd52d23f98d2" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] name = "crossbeam-utils" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -531,12 +591,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" [[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] name = "memchr" version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" [[package]] +name = "memoffset" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8" +dependencies = [ + "autocfg", +] + +[[package]] name = "mime" version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -553,6 +628,15 @@ dependencies = [ ] [[package]] +name = "minimad" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a208cf4e8311b21538dd3fd63218ffcb102bf1ef1ce6fabbfb44e2237763ce5" +dependencies = [ + "lazy_static", +] + +[[package]] name = "miniz_oxide" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -754,6 +838,17 @@ dependencies = [ ] [[package]] +name = "pulldown-cmark" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e142c3b8f49d2200605ee6ba0b1d757310e9e7a72afe78c36ee2ef67300ee00" +dependencies = [ + "bitflags", + "memchr", + "unicase", +] + +[[package]] name = "quote" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1016,10 +1111,14 @@ dependencies = [ "crossterm", "directories", "flate2", + "lazy_static", + "minimad", + "pulldown-cmark", "reqwest", "serde", "serde_json", "serde_yaml", + "termimad", ] [[package]] @@ -1066,6 +1165,19 @@ dependencies = [ ] [[package]] +name = "termimad" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d457a91d0c9fbc663c18961e78f541e61aa9446dc1c0cdd87109543f7289447f" +dependencies = [ + "crossbeam", + "crossterm", + "lazy_static", + "minimad", + "thiserror", +] + +[[package]] name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1075,6 +1187,26 @@ dependencies = [ ] [[package]] +name = "thiserror" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b13f926965ad00595dd129fa12823b04bbf866e9085ab0a5f2b05b850fbfc344" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "893582086c2f98cde18f906265a65b5030a074b1046c674ae898be6519a7f479" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] name = "time" version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -15,3 +15,6 @@ reqwest = { version = "0.10", features = ["blocking"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.8" +termimad = "0.8" +minimad = "0.6" +lazy_static = "1.4" diff --git a/src/error.rs b/src/error.rs index b6046af..b2afd60 100644 --- a/src/error.rs +++ b/src/error.rs @@ -15,6 +15,7 @@ pub enum ErrorKind { Panic, EmptySites, NoResults, + Termimad(termimad::Error), } impl From<&str> for Error { @@ -26,6 +27,15 @@ impl From<&str> for Error { } } +impl From<termimad::Error> for Error { + fn from(err: termimad::Error) -> Self { + Error { + kind: ErrorKind::Termimad(err), + error: String::from(""), + } + } +} + // TODO add others impl Error { pub fn malformed(path: &PathBuf) -> Self { diff --git a/src/macros.rs b/src/macros.rs index a41443c..2b1de62 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -13,3 +13,35 @@ macro_rules! printerr { ).ok(); }) } + +#[macro_export] +macro_rules! print_error { + ($skin: expr, $md: literal $(, $value: expr )* $(,)? ) => {{ + use lazy_static::lazy_static; + use minimad::mad_inline; + use crate::error::Error; + let err = &mut std::io::stderr(); + let p = $skin.paragraph.clone(); + $skin.paragraph.set_fg(crossterm::style::Color::Red); + termimad::mad_write_inline!(err, $skin, "✖ ").map_err(Error::from)?; + $skin.write_composite(err, mad_inline!($md $(, $value)*)).map_err(Error::from)?; + $skin.paragraph = p; + Ok::<(), Error>(()) + }}; +} + +#[macro_export] +macro_rules! print_notice { + ($skin: expr, $md: literal $(, $value: expr )* $(,)? ) => {{ + use lazy_static::lazy_static; + use minimad::mad_inline; + use crate::error::Error; + let err = &mut std::io::stderr(); + let p = $skin.paragraph.clone(); + $skin.paragraph.set_fg(crossterm::style::Color::Yellow); + termimad::mad_write_inline!(err, $skin, "✖ ").map_err(Error::from)?; + $skin.write_composite(err, mad_inline!($md $(, $value)*)).map_err(Error::from)?; + $skin.paragraph = p; + Ok::<(), Error>(()) + }}; +} diff --git a/src/main.rs b/src/main.rs index 0f390df..9c75662 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,10 +6,14 @@ mod stackexchange; mod term; use config::Config; +use crossterm::style::Color; use error::{Error, ErrorKind}; +use lazy_static::lazy_static; +use minimad::mad_inline; use stackexchange::{LocalStorage, StackExchange}; use std::io::stderr; -use term::ColoredOutput; +use term::{prefix_err, ColoredOutput}; +use termimad::MadSkin; fn main() { (|| { @@ -17,6 +21,10 @@ fn main() { let config = opts.config; let site = &config.site; let mut ls = LocalStorage::new()?; + // TODO style configuration + let mut skin = MadSkin::default(); + skin.inline_code.set_fg(Color::Cyan); + skin.code_block.set_fg(Color::Cyan); if opts.update_sites { ls.update_sites()?; @@ -27,6 +35,7 @@ fn main() { match sites.iter().map(|s| s.api_site_parameter.len()).max() { Some(max_w) => { for s in sites { + // TODO print as table! println!("{:>w$}: {}", s.api_site_parameter, s.site_url, w = max_w); } } @@ -43,14 +52,17 @@ fn main() { 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(); + print_error!(skin, "$0 is not a valid StackExchange site.\n\n", site)?; + // TODO what about using text wrapping feature? + 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(()); } Err(Error { diff --git a/src/term.rs b/src/term.rs index 7507d31..cd2db46 100644 --- a/src/term.rs +++ b/src/term.rs @@ -1,6 +1,16 @@ use crossterm::style::{Color, Print, ResetColor, SetForegroundColor}; use crossterm::QueueableCommand; +use lazy_static::lazy_static; +use minimad::mad_inline; use std::io::Write; +use termimad::{mad_write_inline, MadSkin}; + +pub fn prefix_err() -> Result<MadSkin, termimad::Error> { + let mut skin = MadSkin::default(); + skin.paragraph.set_fg(Color::Red); + mad_write_inline!(&mut std::io::stderr(), &skin, "✖ ")?; + Ok(skin) +} pub trait ColoredOutput { fn queue_general(&mut self, color: Color, prefix: &str, s: &str) -> &mut Self; |