From 5cecf46b1b32243ebef823590c71a7eb8521bb5d Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Sat, 20 Aug 2022 23:00:23 -0700 Subject: [PATCH 01/41] Add shortcut to copy contents to clipboard --- src/cli.rs | 5 ++- src/config.rs | 21 ++++++++++ src/main.rs | 13 ++++--- src/stackexchange/scraper.rs | 2 +- src/tui/app.rs | 74 ++++++++++++++++++++++++++++++++---- src/tui/views.rs | 49 +++++++++++++++++++++++- 6 files changed, 147 insertions(+), 17 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 707ed3e..18c1a3f 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -137,8 +137,7 @@ where sites: matches .values_of("site") .unwrap() - .map(|s| s.split(';')) - .flatten() + .flat_map(|s| s.split(';')) .map(String::from) .collect(), api_key: matches @@ -146,6 +145,7 @@ where .map(String::from) .or(config.api_key), lucky, + ..config }, }) } @@ -166,6 +166,7 @@ mod tests { String::from("yeah"), ], search_engine: SearchEngine::DuckDuckGo, + copy_cmd: Some(String::from("wl-copy")), } } diff --git a/src/config.rs b/src/config.rs index 99df1cc..f5e12b5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -4,6 +4,8 @@ use std::fmt; use std::fs; use std::io::Write; use std::path::PathBuf; +use std::process::Command; +use std::process::Stdio; use crate::error::{Error, Result}; use crate::utils; @@ -24,6 +26,7 @@ pub struct Config { pub lucky: bool, pub sites: Vec, pub search_engine: SearchEngine, + pub copy_cmd: Option, } impl fmt::Display for SearchEngine { @@ -52,6 +55,16 @@ impl Default for Config { lucky: true, sites: vec![String::from("stackoverflow")], search_engine: SearchEngine::default(), + copy_cmd: Some(String::from(if cfg!(target_os = "macos") { + "pbcopy" + } else if cfg!(target_os = "windows") { + "clip" + } else if cfg!(target_os = "linux") { + "xclip -sel clip" + } else { + // this default makes no sense but w/e + "wl-copy" + })), } } } @@ -115,4 +128,12 @@ impl Config { let file = utils::create_file(&filename)?; Ok(serde_yaml::to_writer(file, &self)?) } + + pub fn get_copy_cmd(&self) -> Option { + let copy_cmd_str = self.copy_cmd.as_ref()?; + let mut pieces = copy_cmd_str.split_whitespace(); + let mut cmd = Command::new(pieces.next()?); + cmd.args(pieces).stdin(Stdio::piped()); + Some(cmd) + } } diff --git a/src/main.rs b/src/main.rs index 3a07158..8f235af 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,7 +21,7 @@ fn main() -> Result<()> { .block_on(run()) .map(|qs| { // Run TUI - qs.map(tui::run); + qs.map(|(qs, cfg)| tui::run(qs, cfg)); }) .or_else(|e: Error| { // Handle errors @@ -31,7 +31,7 @@ fn main() -> Result<()> { /// Runs the CLI and, if the user wishes to enter the TUI, returns /// question/answer data -async fn run() -> Result>>> { +async fn run() -> Result>, Config)>> { // Get CLI opts let opts = cli::get_opts()?; let config = opts.config; @@ -78,7 +78,7 @@ async fn run() -> Result>>> { } if let Some(q) = opts.query { - let mut search = Search::new(config, ls, q); + let mut search = Search::new(config.clone(), ls, q); if lucky { // Show top answer let md = Term::wrap_spinner(search.search_lucky()).await??; @@ -92,9 +92,12 @@ async fn run() -> Result>>> { } // Get the rest of the questions - return Ok(Some(Term::wrap_spinner(qs).await?.unwrap()?)); + return Ok(Some((Term::wrap_spinner(qs).await?.unwrap()?, config))); } else { - return Ok(Some(Term::wrap_spinner(search.search_md()).await??)); + return Ok(Some(( + Term::wrap_spinner(search.search_md()).await??, + config, + ))); } } Ok(None) diff --git a/src/stackexchange/scraper.rs b/src/stackexchange/scraper.rs index b1354fa..156c68f 100644 --- a/src/stackexchange/scraper.rs +++ b/src/stackexchange/scraper.rs @@ -325,7 +325,7 @@ mod tests { ); match DuckDuckGo.parse(html, &sites, 2) { - Err(Error::Scraping(s)) if s == "DuckDuckGo blocked this request".to_string() => Ok(()), + Err(Error::Scraping(s)) if s == *"DuckDuckGo blocked this request" => Ok(()), _ => Err(String::from("Failed to detect DuckDuckGo blocker")), } } diff --git a/src/tui/app.rs b/src/tui/app.rs index 7160cce..0aa7840 100644 --- a/src/tui/app.rs +++ b/src/tui/app.rs @@ -1,27 +1,33 @@ -use cursive::event::Event; +use cursive::event::{Event, Key}; use cursive::theme::{BaseColor, Color, Effect, Style}; use cursive::traits::{Nameable, Scrollable}; use cursive::utils::markup::StyledString; use cursive::utils::span::SpannedString; -use cursive::views::{Dialog, TextView}; +use cursive::views::{Dialog, TextView, ViewRef}; use cursive::Cursive; use cursive::XY; use std::collections::HashMap; +use std::io; +use std::io::Write; use std::sync::Arc; use super::markdown; use super::markdown::Markdown; use super::views::{ - LayoutView, ListView, MdView, Name, Vimable, NAME_ANSWER_LIST, NAME_ANSWER_VIEW, - NAME_QUESTION_LIST, NAME_QUESTION_VIEW, + LayoutView, ListView, MdView, Name, TempView, Vimable, NAME_ANSWER_LIST, NAME_ANSWER_VIEW, + NAME_FULL_LAYOUT, NAME_QUESTION_LIST, NAME_QUESTION_VIEW, }; use crate::config::Config; use crate::error::Result; use crate::stackexchange::{Answer, Question}; pub const NAME_HELP_VIEW: &str = "help_view"; +pub const NAME_TEMP_MSG: &str = "tmp_msg_view"; -pub fn run(qs: Vec>) -> Result<()> { +// TODO an Arc app state that gets auto updated with new selections would +// be convenient + +pub fn run(qs: Vec>, cfg: Config) -> Result<()> { let mut siv = cursive::default(); siv.load_theme_file(Config::theme_file_path()?).unwrap(); // TODO dont unwrap @@ -31,8 +37,7 @@ pub fn run(qs: Vec>) -> Result<()> { let answer_map: HashMap> = qs .clone() .into_iter() - .map(|q| q.answers.into_iter().map(|a| (a.id, a))) - .flatten() + .flat_map(|q| q.answers.into_iter().map(|a| (a.id, a))) .collect(); let answer_map = Arc::new(answer_map); @@ -74,11 +79,51 @@ pub fn run(qs: Vec>) -> Result<()> { s.add_layer(help()); } }); + // Reload theme siv.add_global_callback(Event::CtrlChar('r'), |s| { s.load_theme_file(Config::theme_file_path().unwrap()) .unwrap() }); + + // Copy contents to sys clipboard + siv.add_global_callback('y', move |s| { + let mut v: ViewRef = s + .find_name(NAME_FULL_LAYOUT) + .expect("bug: layout view should exist"); + let md = v.get_focused_content(); + if let Some(mut copy_cmd) = cfg.get_copy_cmd() { + let res = (|| { + let mut child = copy_cmd.spawn().map_err(|e| { + if e.kind() == io::ErrorKind::NotFound { + io::Error::new( + io::ErrorKind::Other, + "couldn't exec copy cmd; you may need to configure it manually", + ) + } else { + e + } + })?; + let mut stdin = child.stdin.take().ok_or_else(|| { + io::Error::new(io::ErrorKind::Other, "couldn't get stdin of copy cmd") + })?; + stdin.write_all(md.source().as_bytes())?; + Ok("copied to clipboard!".to_string()) + })(); + temp_feedback_msg(s, res); + } + }); + + siv.add_global_callback(Event::Key(Key::Esc), |s| { + if let Some(pos) = s.screen_mut().find_layer_from_name(NAME_HELP_VIEW) { + s.screen_mut().remove_layer(pos); + } + if let Some(pos) = s.screen_mut().find_layer_from_name(NAME_TEMP_MSG) { + s.screen_mut().remove_layer(pos); + } + }); + + // Run the app siv.run(); Ok(()) } @@ -156,6 +201,7 @@ pub fn help() -> Dialog { **G**: Scroll To Bottom ## Misc +**y**: Copy current q/a to the clipboard **q, ZZ, Ctrl**: Exit **Ctrl**: Reload theme **?**: Toggle this help menu @@ -169,5 +215,19 @@ pub fn help() -> Dialog { .title("Help") } +pub fn temp_feedback_msg(siv: &mut Cursive, msg: io::Result) { + // TODO semaphore to close existing msg before displaying new one + let style = if msg.is_ok() { + Color::Light(BaseColor::Green) + } else { + Color::Light(BaseColor::Red) + }; + let content = msg.unwrap_or_else(|e| format!("error: {}", e)); + let styled_content = SpannedString::styled(content, style); + let layer = Dialog::around(TextView::new(styled_content)); + let temp = TempView::new(layer).with_name(NAME_TEMP_MSG); + siv.add_layer(temp); +} + // TODO see cursive/examples/src/bin/select_test.rs for how to test the interface! // maybe see if we can conditionally run when --nocapture is passed? diff --git a/src/tui/views.rs b/src/tui/views.rs index 5341630..af015ef 100644 --- a/src/tui/views.rs +++ b/src/tui/views.rs @@ -262,7 +262,15 @@ impl MdView { .call_on_name(&self.inner_name, |tv: &mut TextView| { tv.set_content(content.clone()) }) - .expect("unwrap failed in MdView.set_content") + .expect("couldn't find mdview") + } + + pub fn get_content(&mut self) -> Markdown { + self.view + .call_on_name(&self.inner_name, |tv: &mut TextView| { + tv.get_content().clone() + }) + .expect("couldn't find mdview") } pub fn show_title(&mut self) { @@ -372,6 +380,22 @@ impl LayoutView { .with_name(NAME_FULL_LAYOUT) } + // Get the name of the currently focused pane + pub fn get_focused_name(&self) -> &'static str { + Self::xy_to_name(self.get_focused_index()) + } + + // Get the question or answer markdown content, whichever side is focused + pub fn get_focused_content(&mut self) -> Markdown { + let name = match self.get_focused_name() { + NAME_QUESTION_VIEW | NAME_QUESTION_LIST => NAME_QUESTION_VIEW, + _ => NAME_ANSWER_VIEW, + }; + self.view + .call_on_name(name, |v: &mut MdView| v.get_content()) + .expect("call on md view failed") + } + fn get_constraints(&self, screen_size: Vec2) -> LayoutViewSizing { let heuristic = 1; let width = SizeConstraint::Fixed(screen_size.x / 2 - heuristic); @@ -438,7 +462,7 @@ impl LayoutView { } fn refocus(&mut self) { - let name = Self::xy_to_name(self.get_focused_index()); + let name = self.get_focused_name(); match self.layout { Layout::SingleColumn if name == NAME_QUESTION_LIST || name == NAME_QUESTION_VIEW => { self.view @@ -618,3 +642,24 @@ pub trait Vimable: View + Sized { } impl Vimable for T {} + +pub struct TempView { + view: T, +} + +// TODO figure out how to auto close this in 3-5s +impl ViewWrapper for TempView { + cursive::wrap_impl!(self.view: T); + + fn wrap_on_event(&mut self, _event: Event) -> EventResult { + EventResult::with_cb(|s| { + s.pop_layer(); + }) + } +} + +impl TempView { + pub fn new(view: T) -> Self { + Self { view } + } +} From 583046dcbf307792ae051263e4029c5d4086434f Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Sat, 20 Aug 2022 23:36:20 -0700 Subject: [PATCH 02/41] Auto close success/error message --- src/tui/app.rs | 14 +++++++------- src/tui/views.rs | 28 +++++++++++++++++++++------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/tui/app.rs b/src/tui/app.rs index 0aa7840..6658f16 100644 --- a/src/tui/app.rs +++ b/src/tui/app.rs @@ -1,3 +1,8 @@ +use std::collections::HashMap; +use std::io; +use std::io::Write; +use std::sync::Arc; + use cursive::event::{Event, Key}; use cursive::theme::{BaseColor, Color, Effect, Style}; use cursive::traits::{Nameable, Scrollable}; @@ -6,23 +11,18 @@ use cursive::utils::span::SpannedString; use cursive::views::{Dialog, TextView, ViewRef}; use cursive::Cursive; use cursive::XY; -use std::collections::HashMap; -use std::io; -use std::io::Write; -use std::sync::Arc; use super::markdown; use super::markdown::Markdown; use super::views::{ LayoutView, ListView, MdView, Name, TempView, Vimable, NAME_ANSWER_LIST, NAME_ANSWER_VIEW, - NAME_FULL_LAYOUT, NAME_QUESTION_LIST, NAME_QUESTION_VIEW, + NAME_FULL_LAYOUT, NAME_QUESTION_LIST, NAME_QUESTION_VIEW, NAME_TEMP_MSG, }; use crate::config::Config; use crate::error::Result; use crate::stackexchange::{Answer, Question}; pub const NAME_HELP_VIEW: &str = "help_view"; -pub const NAME_TEMP_MSG: &str = "tmp_msg_view"; // TODO an Arc app state that gets auto updated with new selections would // be convenient @@ -225,7 +225,7 @@ pub fn temp_feedback_msg(siv: &mut Cursive, msg: io::Result) { let content = msg.unwrap_or_else(|e| format!("error: {}", e)); let styled_content = SpannedString::styled(content, style); let layer = Dialog::around(TextView::new(styled_content)); - let temp = TempView::new(layer).with_name(NAME_TEMP_MSG); + let temp = TempView::new(layer, siv.cb_sink().clone()); siv.add_layer(temp); } diff --git a/src/tui/views.rs b/src/tui/views.rs index af015ef..0e7971d 100644 --- a/src/tui/views.rs +++ b/src/tui/views.rs @@ -1,3 +1,8 @@ +use std::fmt::Display; +use std::rc::Rc; +use std::time::Duration; +use std::{fmt, thread}; + use cursive::event::{Callback, Event, EventResult, Key}; use cursive::traits::{Finder, Nameable, Resizable, Scrollable}; use cursive::utils::markup::StyledString; @@ -6,10 +11,7 @@ use cursive::views::{ HideableView, LinearLayout, NamedView, PaddedView, Panel, ResizedView, ScrollView, SelectView, TextView, }; -use cursive::{Cursive, Vec2, XY}; -use std::fmt; -use std::fmt::Display; -use std::rc::Rc; +use cursive::{CbSink, Cursive, Vec2, XY}; use super::markdown::Markdown; @@ -18,6 +20,7 @@ pub const NAME_ANSWER_LIST: &str = "answer_list"; pub const NAME_QUESTION_VIEW: &str = "question_view"; pub const NAME_ANSWER_VIEW: &str = "answer_view"; pub const NAME_FULL_LAYOUT: &str = "full_layout"; +pub const NAME_TEMP_MSG: &str = "tmp_msg_view"; // TODO this seems pointless; probably should be removed pub enum Name { @@ -647,19 +650,30 @@ pub struct TempView { view: T, } -// TODO figure out how to auto close this in 3-5s impl ViewWrapper for TempView { cursive::wrap_impl!(self.view: T); fn wrap_on_event(&mut self, _event: Event) -> EventResult { + // close this view on any input EventResult::with_cb(|s| { s.pop_layer(); }) } } -impl TempView { - pub fn new(view: T) -> Self { +impl TempView> { + pub fn new(inner: V, cb_sink: CbSink) -> Self { + thread::spawn(move || { + thread::sleep(Duration::from_secs(2)); + cb_sink + .send(Box::new(|s| { + if let Some(pos) = s.screen_mut().find_layer_from_name(NAME_TEMP_MSG) { + s.screen_mut().remove_layer(pos); + } + })) + .expect("failed to send fn to cursive cb sink"); + }); + let view = inner.with_name(NAME_TEMP_MSG); Self { view } } } From bba9a0d70cbcf1608ad3748edfb608068898edd9 Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Sat, 20 Aug 2022 23:45:57 -0700 Subject: [PATCH 03/41] Build on main branch --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 374fb4e..e089e78 100644 --- a/.travis.yml +++ b/.travis.yml @@ -59,7 +59,7 @@ branches: only: # release tags - /^v\d+\.\d+\.\d+.*$/ - - master + - main - develop notifications: diff --git a/appveyor.yml b/appveyor.yml index d5eeeb6..37ce93b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -59,7 +59,7 @@ branches: only: # Release tags - /^v\d+\.\d+\.\d+.*$/ - - master + - main - develop notifications: From 8814a90ac85fb007aa394e34ac4290fd3fe1d2e2 Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Sat, 20 Aug 2022 23:53:26 -0700 Subject: [PATCH 04/41] Add docs for sys clipboard --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 972a475..95a7535 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,20 @@ In the same directory you'll find `colors.toml` which is self-documented. The default theme attempts to blend in with your default terminal theme, but you can change it as necessary. In particular, you may want to change the `highlight_text` if the current selection is difficult to read. There are some themes in the [themes](./themes) directory as well. +#### system clipboard integration +There's a very primitive integration in place to copy the contents of +the currently focused question or answer to the system clipboard. This requires +some command in your PATH that can accept stdin and pipe to the clipboard. +On mac & windows, this will work out of the box with the default set to `pbcopy` +& `clip` respectively. On Linux, I've made the assumption that `xclip` is likely +the most popular, but if you use something else (e.g. `wl-copy` on wayland), +you'll need to set the command directly: +```yaml +# config.yml +--- +copy_cmd: copy --option-to-take-stdin +``` + #### api keys If you want to use your own [StackExchange API Key](https://api.stackexchange.com/docs) you can set it via From e4d44be6537299f54abb36a517abb4c2845ff80e Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Sun, 21 Aug 2022 01:33:34 -0700 Subject: [PATCH 05/41] Create GH ci check --- .github/workflows/ci.yml | 41 ++++++++++++++++++++++++ .travis.yml | 67 ---------------------------------------- CHANGELOG.md | 7 +++++ README.md | 7 ++--- 4 files changed, 51 insertions(+), 71 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..9fdc4be --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,41 @@ +name: CI + +on: + push: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install minimal stable with clippy and rustfmt + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + components: rustfmt, clippy + + - uses: Swatinem/rust-cache@v2 + + - name: Check formatting + uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all --check + + - name: Build application + uses: actions-rs/cargo@v1 + with: + command: build + + - name: Run clippy linter + uses: actions-rs/cargo@v1 + with: + command: clippy + args: --all-targets -- --deny warnings + + - name: Run tests + uses: actions-rs/cargo@v1 + with: + command: test diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index e089e78..0000000 --- a/.travis.yml +++ /dev/null @@ -1,67 +0,0 @@ -# Based on the "trust" template v0.1.2 -# https://github.com/japaric/trust/tree/v0.1.2 - -dist: trusty -language: rust -services: docker - -env: - global: - - CRATE_NAME=so - -jobs: - include: - # Linux - - env: TARGET=x86_64-unknown-linux-musl - - env: TARGET=x86_64-unknown-linux-gnu - - # OSX - - env: TARGET=x86_64-apple-darwin - os: osx - - # TODO figure out how to get tls libraries working on *bsd targets - # BSD - # - env: TARGET=x86_64-unknown-freebsd DISABLE_TESTS=1 PKG_CONFIG_ALLOW_CROSS=1 - -before_install: - - set -e - - rustup self update - -install: - - sh ci/install.sh - - source ~/.cargo/env || true - -script: - - bash ci/script.sh - -after_script: set +e - -before_deploy: - - sh ci/before_deploy.sh - -deploy: - token: - secure: 1wWcYP/bJ3Poba8Y4D1BFV//8JFSJOL74ah9JP+QbOH7HmXtIX2xjaVUhzhZNU0rQHzibPzlbbe1lyr/SKqbCwzupowxxFlx6MOovQd8su8BWKsONpIaFtIMRDvkRVTIKo1/9Wp7tdjoFBVohY0ERnMuj2oV51tavYyl+hdEViZb6qQyGGuzotK1LzOaQslAqtCIjbs2mVXGkSURDuikYVJld8wyaO02zIeALDEs+czbQI0AUQ1l+dsy2vk+/pds2w5cgLGe7jtbFWLTgZU5eChV/3ArWSgeDxlZiNCDdUXfJ35TSLtrLzEexqVZNz3njlSfdOc5kueYGG1PhetNUJ+8WWDtoes3GnSYyh/lNv4UOjH34OZBrfazWllGHdDEE9yl/0Hu/QJ8uDUtDyImtfRCmJNRNZO7VkBturl/D8z6/Mq3mMF/fWkWfHlA4bDRtIA20ZYCzilmAT4DuMl8QQ89M6B65uJkBHN1EbnXMQTB/tzuvDRFbaRzCZ1WMudGoT9PyhgRcTzJEhGzfoEMRlUIbAffihnkiPyT7VRYcL2zSefnw2pvrnuZmykrkHF8/oyUPHvgYp1s/GMhBZexfrJ2moOWoxObYscoeI0gphLdycwHv5tJXR4U7eIoTD4SUYjNfwJf84G7rFbM62WfXUxO+gvJzQsHr3XxSZVoZ1c= - file_glob: true - file: $CRATE_NAME-$TRAVIS_TAG-$TARGET.* - on: - condition: $TRAVIS_RUST_VERSION = stable - tags: true - provider: releases - skip_cleanup: true - -cache: cargo -before_cache: - # Travis can't cache files that are not readable by "others" - - chmod -R a+r $HOME/.cargo - -branches: - only: - # release tags - - /^v\d+\.\d+\.\d+.*$/ - - main - - develop - -notifications: - email: - on_success: never diff --git a/CHANGELOG.md b/CHANGELOG.md index 56626d9..c16b28d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### [Unreleased] +#### Added +- Keybinding: Press `y` to yank to system clipboard +- New config field for specifying command to copy to system clipboard + +#### Changed +- Switch linux/mac builds from Travis to GitHub Actions. + ### [v0.4.6](https://github.com/samtay/so/compare/v0.4.5...v0.4.6) #### Changed diff --git a/README.md b/README.md index 95a7535..f8d2981 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,11 @@

-[![travis][s0]][l0] [![appveyor][s1]][l1] [![crates][s2]][l2] [![MIT][s3]][l3] [![Packaging status](https://repology.org/badge/tiny-repos/so.svg)](https://repology.org/project/so/versions) +[![CI][s0]][l0] [![appveyor][s1]][l1] [![crates][s2]][l2] [![MIT][s3]][l3] [![Packaging status](https://repology.org/badge/tiny-repos/so.svg)](https://repology.org/project/so/versions)

- -[s0]: https://travis-ci.org/samtay/so.svg?branch=master -[l0]: https://travis-ci.org/samtay/so +[s0]: https://github.com/samtay/so/actions/workflows/ci.yml/badge.svg +[l0]: https://github.com/samtay/so/actions/workflows/ci.yml [s1]: https://ci.appveyor.com/api/projects/status/pu7e63f2sqq6x1iq/branch/master?svg=true [l1]: https://ci.appveyor.com/project/samtay/so/branch/master [s2]: https://img.shields.io/crates/v/so.svg From ebb828cef629f8355f183c0307caa28c4d5c2f8e Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Sun, 21 Aug 2022 01:58:13 -0700 Subject: [PATCH 06/41] Fix clippy lints --- src/config.rs | 4 ++-- src/main.rs | 4 +++- src/stackexchange/scraper.rs | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/config.rs b/src/config.rs index f5e12b5..2c1500d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -10,7 +10,7 @@ use std::process::Stdio; use crate::error::{Error, Result}; use crate::utils; -#[derive(Deserialize, Serialize, Debug, Clone, PartialEq)] +#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum SearchEngine { DuckDuckGo, @@ -18,7 +18,7 @@ pub enum SearchEngine { StackExchange, } -#[derive(Deserialize, Serialize, Debug, Clone, PartialEq)] +#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)] #[serde(default)] pub struct Config { pub api_key: Option, diff --git a/src/main.rs b/src/main.rs index 8f235af..c2e8f51 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,8 @@ mod term; mod tui; mod utils; +use std::fmt::Write; + use tokio::runtime::Runtime; use tokio::task; @@ -57,7 +59,7 @@ async fn run() -> Result>, Config)>> { md.push_str("|Site Code|Site URL|\n"); md.push_str("|-:|:-|\n"); for s in ls.sites.iter() { - md.push_str(&format!("|{}|{}\n", s.api_site_parameter, s.site_url)); + writeln!(&mut md, "|{}|{}", s.api_site_parameter, s.site_url).ok(); } md.push_str("|-\n"); term.print(&md); diff --git a/src/stackexchange/scraper.rs b/src/stackexchange/scraper.rs index 156c68f..3cc0218 100644 --- a/src/stackexchange/scraper.rs +++ b/src/stackexchange/scraper.rs @@ -17,7 +17,7 @@ const GOOGLE_URL: &str = "https://google.com/search"; // If this is ever an issue, it wouldn't be too hard to account for this; just // keep track of site in the `ordering` field and also return site from the // spawned per-site tasks. -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub struct ScrapedData { /// Mapping of site code to question ids pub question_ids: HashMap>, @@ -182,7 +182,7 @@ fn question_url_to_id(site_url: &str, input: &str) -> Option { } else { input[0..].to_string() }; - if id.chars().all(|c| c.is_digit(10)) { + if id.chars().all(|c| c.is_ascii_digit()) { Some(id) } else { None From c490fb1d7cc4442c1c1f518781270becfe75d1d8 Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Sun, 21 Aug 2022 02:18:41 -0700 Subject: [PATCH 07/41] Bump version to 0.4.7 --- .github/workflows/release.yaml | 47 ++++++++++++++++++++++++++++++++++ CHANGELOG.md | 2 ++ Cargo.lock | 2 +- Cargo.toml | 2 +- 4 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/release.yaml diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..e53a8d7 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,47 @@ +name: Release + +permissions: + contents: write + +on: + push: + tags: + - v[0-9]+.* + +jobs: + + create-release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: taiki-e/create-gh-release-action@v1 + with: + changelog: CHANGELOG.md + branch: main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + upload-assets: + needs: create-release + strategy: + matrix: + include: + - target: aarch64-unknown-linux-gnu + os: ubuntu-latest + - target: aarch64-apple-darwin + os: macos-latest + - target: x86_64-unknown-linux-gnu + os: ubuntu-latest + - target: x86_64-unknown-linux-musl + os: ubuntu-latest + - target: x86_64-apple-darwin + os: macos-latest + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + - uses: taiki-e/upload-rust-binary-action@v1 + with: + bin: so + target: ${{ matrix.target }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index c16b28d..efa6dc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### [Unreleased] +### [v0.4.7](https://github.com/samtay/so/compare/v0.4.5...v0.4.7) + #### Added - Keybinding: Press `y` to yank to system clipboard - New config field for specifying command to copy to system clipboard diff --git a/Cargo.lock b/Cargo.lock index 6b0f194..3fd6520 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1926,7 +1926,7 @@ checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" [[package]] name = "so" -version = "0.4.6" +version = "0.4.7" dependencies = [ "clap", "criterion", diff --git a/Cargo.toml b/Cargo.toml index f425b31..d3bec91 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "so" -version = "0.4.6" +version = "0.4.7" license = "MIT" description = "A terminal interface for StackOverflow" readme = "README.md" From 421a6257e1fbda7d0723763f8e9737459e68f24f Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Sun, 21 Aug 2022 02:46:10 -0700 Subject: [PATCH 08/41] Reformat changelog To appease github action, hopefully --- CHANGELOG.md | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efa6dc7..65ace6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -### [Unreleased] +## [Unreleased] -### [v0.4.7](https://github.com/samtay/so/compare/v0.4.5...v0.4.7) +## [0.4.7] #### Added - Keybinding: Press `y` to yank to system clipboard @@ -15,12 +15,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 #### Changed - Switch linux/mac builds from Travis to GitHub Actions. -### [v0.4.6](https://github.com/samtay/so/compare/v0.4.5...v0.4.6) +## [0.4.6] #### Changed - Use Google as the default search engine, due to issues with DuckDuckGo. -### [v0.4.5](https://github.com/samtay/so/compare/v0.4.3...v0.4.5) +## [0.4.5] #### Added - NetBSD installation option. Thanks **voidpin**. @@ -29,7 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Google parser went out of date - Panic from termimad ([#5](https://github.com/samtay/so/issues/5)) -### [v0.4.3](https://github.com/samtay/so/compare/v0.4.1...v0.4.3) +## [0.4.3] #### Fixed - Build issue caused by syn dependency ([#13](https://github.com/samtay/so/issues/13)) @@ -40,15 +40,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [lukesampson/scoop-extras#4376](https://github.com/lukesampson/scoop-extras/pull/4376). Thanks [@laralex](https://github.com/laralex)! -### [v0.4.1](https://github.com/samtay/so/compare/v0.4.0...v0.4.1) (2020-07-10) +## [0.4.1] #### Added - GitHub Action to bump homebrew-core formula + #### Changed - Homebrew installation method: core [formula](https://formulae.brew.sh/formula/so) now available -### [v0.4.0](https://github.com/samtay/so/compare/v0.3.6...v0.4.0) (2020-07-07) +## [0.4.0] #### Added - *Keybinding*: Press `q` to quit ([#1](https://github.com/samtay/so/pull/1)). @@ -57,15 +58,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 and [so-git](https://aur.archlinux.org/packages/so-git/) - Homebrew installation option: [samtay/tui/so](https://github.com/samtay/homebrew-tui) - This changelog + #### Changed - Default `highlight_text` is now `black` -### [v0.3.6](https://github.com/samtay/so/compare/v0.3.5...v0.3.6) (2020-07-02) +## [0.3.6] #### Added - CLI spinner + #### Fixed - Fragmented highlighting styles -### [v0.3.5](https://github.com/samtay/so/compare/030cd70...v0.3.5) (2020-06-30) +## [0.3.5] - (Unofficial) initial passable release + +[Unreleased]: (https://github.com/samtay/so/compare/v0.4.6...HEAD) +[0.4.7]: (https://github.com/samtay/so/compare/v0.4.6...v0.4.7) +[0.4.6]: (https://github.com/samtay/so/compare/v0.4.5...v0.4.6) +[0.4.5]: (https://github.com/samtay/so/compare/v0.4.3...v0.4.5) +[0.4.3]: (https://github.com/samtay/so/compare/v0.4.1...v0.4.3) +[0.4.1]: (https://github.com/samtay/so/compare/v0.4.0...v0.4.1) +[0.4.0]: (https://github.com/samtay/so/compare/v0.3.6...v0.4.0) +[0.3.6]: (https://github.com/samtay/so/compare/v0.3.5...v0.3.6) +[0.3.5]: (https://github.com/samtay/so/compare/030cd70...v0.3.5) From b27d3f2fceca6e0b7bfd69c82be89628d29f767d Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Sun, 21 Aug 2022 03:01:39 -0700 Subject: [PATCH 09/41] Fix missing ssl dep --- .github/workflows/release.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index e53a8d7..67cb140 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -43,5 +43,6 @@ jobs: with: bin: so target: ${{ matrix.target }} + features: reqwest/native-tls-vendored env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From cc64aa64464d8dd0cc637d57bc86176e2066faeb Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Sun, 21 Aug 2022 03:08:21 -0700 Subject: [PATCH 10/41] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f8d2981..a97a8ed 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@

-[![CI][s0]][l0] [![appveyor][s1]][l1] [![crates][s2]][l2] [![MIT][s3]][l3] [![Packaging status](https://repology.org/badge/tiny-repos/so.svg)](https://repology.org/project/so/versions) - +[![ci][s0]][l0] [![appveyor][s1]][l1] [![crates][s2]][l2] [![MIT][s3]][l3] [![Packaging status](https://repology.org/badge/tiny-repos/so.svg)](https://repology.org/project/so/versions)

+ [s0]: https://github.com/samtay/so/actions/workflows/ci.yml/badge.svg [l0]: https://github.com/samtay/so/actions/workflows/ci.yml [s1]: https://ci.appveyor.com/api/projects/status/pu7e63f2sqq6x1iq/branch/master?svg=true From a5c702e7eaabc4327b4f6b539d24bc37a387b792 Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Sun, 21 Aug 2022 10:02:03 -0700 Subject: [PATCH 11/41] Fix install script --- ci/before_deploy.ps1 | 2 +- docs/install.sh | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ci/before_deploy.ps1 b/ci/before_deploy.ps1 index 5bc9388..583307c 100644 --- a/ci/before_deploy.ps1 +++ b/ci/before_deploy.ps1 @@ -8,7 +8,7 @@ Set-Location $env:TEMP New-Item -Type Directory -Name $STAGE Set-Location $STAGE -$ZIP = "$SRC_DIR\$($env:CRATE_NAME)-$($env:APPVEYOR_REPO_TAG_NAME)-$($env:TARGET).zip" +$ZIP = "$SRC_DIR\$($env:CRATE_NAME)-$($env:TARGET).zip" Copy-Item "$SRC_DIR\target\$($env:TARGET)\release\$($env:CRATE_NAME).exe" '.\' diff --git a/docs/install.sh b/docs/install.sh index 1ef1dca..1172e4b 100755 --- a/docs/install.sh +++ b/docs/install.sh @@ -99,10 +99,14 @@ if [ -z ${dest-} ]; then fi if [ -z ${tag-} ]; then - tag=$(curl -s "$releases/latest" | cut -d'"' -f2 | rev | cut -d'/' -f1 | rev) + tag=$( + curl --silent "https://api.github.com/repos/samtay/so/releases/latest" | + grep '"tag_name":' | + sed -E 's/.*"([^"]+)".*/\1/' + ) fi -archive="$releases/download/$tag/$crate-$tag-$target.tar.gz" +archive="$releases/download/$tag/$crate-$target.tar.gz" say_err "Repository: $url" say_err "Crate: $crate" From f006d0503298bd43ec32bbf3f547ec5d7c50c758 Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Sun, 21 Aug 2022 10:09:05 -0700 Subject: [PATCH 12/41] Try building armv7 Dont re-send this to homebrew --- .github/workflows/bump_brew_formula.yml | 1 + .github/workflows/release.yaml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.github/workflows/bump_brew_formula.yml b/.github/workflows/bump_brew_formula.yml index 902ecb2..a04cbe8 100644 --- a/.github/workflows/bump_brew_formula.yml +++ b/.github/workflows/bump_brew_formula.yml @@ -6,6 +6,7 @@ on: jobs: homebrew: + if: false name: Bump Homebrew formula runs-on: ubuntu-latest steps: diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 67cb140..0fa5568 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -26,6 +26,8 @@ jobs: strategy: matrix: include: + - target: armv7-unknown-linux-gnueabihf + os: ubuntu-latest - target: aarch64-unknown-linux-gnu os: ubuntu-latest - target: aarch64-apple-darwin From 1484f6763b9a7dd782a002764886c053477f2181 Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Sun, 21 Aug 2022 10:24:21 -0700 Subject: [PATCH 13/41] Re-enable homebrew bump action --- .github/workflows/bump_brew_formula.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/bump_brew_formula.yml b/.github/workflows/bump_brew_formula.yml index a04cbe8..902ecb2 100644 --- a/.github/workflows/bump_brew_formula.yml +++ b/.github/workflows/bump_brew_formula.yml @@ -6,7 +6,6 @@ on: jobs: homebrew: - if: false name: Bump Homebrew formula runs-on: ubuntu-latest steps: From 7377525de6cf78946b01dcb69aae7bb52a9bf74b Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Sun, 21 Aug 2022 17:57:55 -0700 Subject: [PATCH 14/41] Add key to open SE answer in browser --- CHANGELOG.md | 3 + Cargo.lock | 769 ++++++++++++++++++++++++------------ Cargo.toml | 28 +- src/main.rs | 20 +- src/stackexchange/api.rs | 20 +- src/stackexchange/mod.rs | 2 +- src/stackexchange/search.rs | 9 +- src/tui/app.rs | 286 ++++++++------ src/tui/mod.rs | 2 +- src/tui/views.rs | 21 + 10 files changed, 746 insertions(+), 414 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65ace6a..7efcbe7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +#### Added +- Keybinding: Press `o` to open the current answer in the default browser + ## [0.4.7] #### Added diff --git a/Cargo.lock b/Cargo.lock index 3fd6520..9c1792f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,7 +14,7 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.5", + "getrandom 0.2.7", "once_cell", "version_check", ] @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.3.12" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2bf394cfbbe876f0ac67b13b6ca819f9c9f2fb9ec67223cceb1555fbab1c31a" +checksum = "345fd392ab01f746c717b1357165b76f0b67a60192007b234058c9045fdcf695" dependencies = [ "flate2", "futures-core", @@ -84,9 +84,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.9.1" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" +checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" [[package]] name = "byteorder" @@ -96,9 +96,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" [[package]] name = "cast" @@ -109,12 +109,24 @@ dependencies = [ "rustc_version", ] +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + [[package]] name = "cc" version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[package]] name = "cfg-if" version = "0.1.10" @@ -142,6 +154,16 @@ dependencies = [ "vec_map", ] +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "convert_case" version = "0.4.0" @@ -180,7 +202,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23" dependencies = [ "atty", - "cast", + "cast 0.2.7", "clap", "criterion-plot", "csv", @@ -201,19 +223,19 @@ dependencies = [ [[package]] name = "criterion-plot" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57" +checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" dependencies = [ - "cast", + "cast 0.3.0", "itertools", ] [[package]] name = "crossbeam" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845" +checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" dependencies = [ "cfg-if 1.0.0", "crossbeam-channel", @@ -225,9 +247,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.2" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" dependencies = [ "cfg-if 1.0.0", "crossbeam-utils", @@ -235,9 +257,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" dependencies = [ "cfg-if 1.0.0", "crossbeam-epoch", @@ -246,22 +268,23 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.7" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9" +checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" dependencies = [ + "autocfg", "cfg-if 1.0.0", "crossbeam-utils", - "lazy_static", "memoffset", + "once_cell", "scopeguard", ] [[package]] name = "crossbeam-queue" -version = "0.3.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd435b205a4842da59efd07628f921c096bc1cc0a156835b4fa0bcb9a19bcce" +checksum = "1cd42583b04998a5363558e5f9291ee5a5ff6b49944332103f251e7479a82aa7" dependencies = [ "cfg-if 1.0.0", "crossbeam-utils", @@ -269,12 +292,12 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.7" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" +checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" dependencies = [ "cfg-if 1.0.0", - "lazy_static", + "once_cell", ] [[package]] @@ -403,9 +426,9 @@ dependencies = [ [[package]] name = "cursive_core" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e27fbda42833e46148ff28db338f6189a4407e4a38ba1f4105e2f623089e66a0" +checksum = "4f8332f2d1dc815a1c72aa95cba6a557198b8e875371a8f1951037f510d7e257" dependencies = [ "ahash", "crossbeam-channel", @@ -422,14 +445,38 @@ dependencies = [ "xi-unicode", ] +[[package]] +name = "darling" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +dependencies = [ + "darling_core 0.10.2", + "darling_macro 0.10.2", +] + [[package]] name = "darling" version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f2c43f534ea4b0b049015d00269734195e6d3f0f6635cb692251aca6f9f8b3c" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.12.4", + "darling_macro 0.12.4", +] + +[[package]] +name = "darling_core" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.9.3", + "syn", ] [[package]] @@ -446,13 +493,24 @@ dependencies = [ "syn", ] +[[package]] +name = "darling_macro" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +dependencies = [ + "darling_core 0.10.2", + "quote", + "syn", +] + [[package]] name = "darling_macro" version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29b5acf0dea37a7f66f7b25d2c5e93fd46f8f6968b1a5d7a3e02e97768afc95a" dependencies = [ - "darling_core", + "darling_core 0.12.4", "quote", "syn", ] @@ -482,9 +540,9 @@ dependencies = [ [[package]] name = "dirs-sys" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" dependencies = [ "libc", "redox_users", @@ -514,33 +572,33 @@ checksum = "3a68a4904193147e0a8dec3314640e6db742afd5f6e634f428a6af230d9b3591" [[package]] name = "either" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "encoding_rs" -version = "0.8.30" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" dependencies = [ "cfg-if 1.0.0", ] [[package]] name = "enum-map" -version = "2.0.2" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7848397e7221a27d81cb7f07498d563f09b23fcd52ce9f74a6a110ed28f7cd4f" +checksum = "f5a56d54c8dd9b3ad34752ed197a4eb2a6601bc010808eb097a04a58ae4c43e1" dependencies = [ "enum-map-derive", ] [[package]] name = "enum-map-derive" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a63b7a0ddec6f38dcec5e36257750b7a8fcaf4227e12ceb306e341d63634da05" +checksum = "a9045e2676cd5af83c3b167d917b0a5c90a4d8e266e2683d6631b235c457fc27" dependencies = [ "proc-macro2", "quote", @@ -562,7 +620,7 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e19c52f9ec503c8a68dc04daf71a04b07e690c32ab1a8b68e33897f255269d47" dependencies = [ - "darling", + "darling 0.12.4", "proc-macro2", "quote", "syn", @@ -570,22 +628,20 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" dependencies = [ "instant", ] [[package]] name = "flate2" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" dependencies = [ - "cfg-if 1.0.0", "crc32fast", - "libc", "miniz_oxide", ] @@ -632,9 +688,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +checksum = "ab30e97ab6aacfe635fad58f22c2bb06c8b685f7421eb1e064a729e2a5f481fa" dependencies = [ "futures-channel", "futures-core", @@ -647,9 +703,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "2bfc52cbddcfd745bf1740338492bb0bd83d76c67b445f91c5fb29fae29ecaa1" dependencies = [ "futures-core", "futures-sink", @@ -657,15 +713,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "d2acedae88d38235936c3922476b10fced7b2b68136f5e3c03c2d5be348a1115" [[package]] name = "futures-executor" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +checksum = "1d11aa21b5b587a64682c0094c2bdd4df0076c5324961a40cc3abd7f37930528" dependencies = [ "futures-core", "futures-task", @@ -674,15 +730,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "93a66fc6d035a26a3ae255a6d2bca35eda63ae4c5512bef54449113f7a1228e5" [[package]] name = "futures-macro" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +checksum = "0db9cce532b0eae2ccf2766ab246f114b56b9cf6d445e00c2549fbc100ca045d" dependencies = [ "proc-macro2", "quote", @@ -691,21 +747,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "ca0bae1fe9752cf7fd9b0064c674ae63f97b37bc714d745cbde0afb7ec4e6765" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "842fc63b931f4056a24d59de13fb1272134ce261816e063e634ad0c15cdc5306" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "f0828a5471e340229c11c77ca80017937ce3c58cb788a17e5f1c2d5c485a9577" dependencies = [ "futures-channel", "futures-core", @@ -750,20 +806,20 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] name = "h2" -version = "0.3.11" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9f1f717ddc7b2ba36df7e871fd88db79326551d3d6f1fc406fbfd28b582ff8e" +checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be" dependencies = [ "bytes", "fnv", @@ -786,9 +842,9 @@ checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hermit-abi" @@ -801,9 +857,9 @@ dependencies = [ [[package]] name = "html5ever" -version = "0.25.1" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafcf38a1a36118242d29b92e1b08ef84e67e4a5ed06e0a80be20e6a32bfed6b" +checksum = "e5c13fb08e5d4dfc151ee5e88bae63f7773d61852f3bdc73c9f4b9e1bde03148" dependencies = [ "log", "mac", @@ -815,20 +871,20 @@ dependencies = [ [[package]] name = "http" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ "bytes", "fnv", - "itoa 1.0.1", + "itoa 1.0.3", ] [[package]] name = "http-body" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", "http", @@ -837,9 +893,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.6.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9100414882e15fb7feccb4897e5f0ff0ff1ca7d1a86a23208ada4d7a18e6c6c4" +checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" [[package]] name = "httpdate" @@ -849,9 +905,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.17" +version = "0.14.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043f0e083e9901b6cc658a77d1eb86f4fc650bbb977a4337dd63192826aa85dd" +checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" dependencies = [ "bytes", "futures-channel", @@ -862,7 +918,7 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa 1.0.1", + "itoa 1.0.3", "pin-project-lite", "socket2", "tokio", @@ -903,9 +959,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.8.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg", "hashbrown", @@ -922,9 +978,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.3.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" +checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" [[package]] name = "itertools" @@ -943,9 +999,29 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" -version = "1.0.1" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" + +[[package]] +name = "jni" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" @@ -964,30 +1040,31 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.119" +version = "0.2.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" +checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" [[package]] name = "linked-hash-map" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "lock_api" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ + "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.14" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if 1.0.0", ] @@ -1026,9 +1103,9 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "memchr" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" @@ -1056,12 +1133,11 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.4.4" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" dependencies = [ "adler", - "autocfg", ] [[package]] @@ -1079,15 +1155,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.0" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba272f85fa0b41fc91872be579b3bbe0f56b792aa361a380eb669469f68dafb2" +checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" dependencies = [ "libc", "log", - "miow", - "ntapi", - "winapi", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys", ] [[package]] @@ -1101,9 +1176,9 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d" +checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" dependencies = [ "lazy_static", "libc", @@ -1128,6 +1203,59 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "ndk" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d64d6af06fde0e527b1ba5c7b79a6cc89cfc46325b0b2887dffe8f70197e0c3c" +dependencies = [ + "bitflags", + "jni-sys", + "ndk-sys", + "num_enum", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-glue" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3648f3609716eb7dbf5f5b5d4b84fcd67dd4c34efcdb12e4a6c0929c2ac48349" +dependencies = [ + "lazy_static", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-macro", + "ndk-sys", +] + +[[package]] +name = "ndk-macro" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d1c6307dc424d0f65b9b06e94f88248e6305726b14729fd67a5e47b2dc481d" +dependencies = [ + "darling 0.10.2", + "proc-macro-crate 0.1.5", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ndk-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1bcdd74c20ad5d95aacd60ef9ba40fdf77f767051040541df557b7a9b2a2121" + [[package]] name = "new_debug_unreachable" version = "1.0.4" @@ -1164,18 +1292,18 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085" +checksum = "7ae39348c8bc5fbd7f40c727a9925f03517afd2ab27d46702108b6a7e5414c19" dependencies = [ "num-traits", ] [[package]] name = "num-integer" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ "autocfg", "num-traits", @@ -1183,9 +1311,9 @@ dependencies = [ [[package]] name = "num-iter" -version = "0.1.42" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" dependencies = [ "autocfg", "num-integer", @@ -1194,9 +1322,9 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" dependencies = [ "autocfg", "num-integer", @@ -1205,9 +1333,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", ] @@ -1222,11 +1350,32 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" +dependencies = [ + "proc-macro-crate 1.2.1", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "num_threads" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ba99ba6393e2c3734791401b66902d981cb03bf190af674ca69949b6d5fb15" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" dependencies = [ "libc", ] @@ -1239,9 +1388,9 @@ checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" [[package]] name = "once_cell" -version = "1.9.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" +checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" [[package]] name = "oorandom" @@ -1251,18 +1400,30 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "openssl" -version = "0.10.38" +version = "0.10.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" +checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0" dependencies = [ "bitflags", "cfg-if 1.0.0", "foreign-types", "libc", "once_cell", + "openssl-macros", "openssl-sys", ] +[[package]] +name = "openssl-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "openssl-probe" version = "0.1.5" @@ -1271,9 +1432,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.72" +version = "0.9.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" +checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f" dependencies = [ "autocfg", "cc", @@ -1317,12 +1478,12 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.1", + "parking_lot_core 0.9.3", ] [[package]] @@ -1341,9 +1502,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28141e0cc4143da2443301914478dc976a61ffdb3f043058310c70df2fed8954" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" dependencies = [ "cfg-if 1.0.0", "libc", @@ -1385,7 +1546,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" dependencies = [ - "phf_generator", + "phf_generator 0.8.0", "phf_shared 0.8.0", ] @@ -1396,7 +1557,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" dependencies = [ "phf_shared 0.8.0", - "rand", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.5", ] [[package]] @@ -1405,7 +1576,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" dependencies = [ - "phf_generator", + "phf_generator 0.8.0", "phf_shared 0.8.0", "proc-macro-hack", "proc-macro2", @@ -1433,9 +1604,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "pin-utils" @@ -1445,9 +1616,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "plotters" @@ -1464,15 +1635,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c" +checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" [[package]] name = "plotters-svg" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9" +checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" dependencies = [ "plotters-backend", ] @@ -1489,6 +1660,26 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9" +dependencies = [ + "once_cell", + "thiserror", + "toml", +] + [[package]] name = "proc-macro-hack" version = "0.5.19" @@ -1497,11 +1688,11 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] @@ -1517,9 +1708,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.15" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] @@ -1532,12 +1723,23 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ "getrandom 0.1.16", "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.2.2", + "rand_core 0.5.1", "rand_hc", "rand_pcg", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -1545,7 +1747,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", ] [[package]] @@ -1557,13 +1769,22 @@ dependencies = [ "getrandom 0.1.16", ] +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.7", +] + [[package]] name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core", + "rand_core 0.5.1", ] [[package]] @@ -1572,14 +1793,14 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" dependencies = [ - "rand_core", + "rand_core 0.5.1", ] [[package]] name = "rayon" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" dependencies = [ "autocfg", "crossbeam-deque", @@ -1589,22 +1810,21 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" dependencies = [ "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "lazy_static", "num_cpus", ] [[package]] name = "redox_syscall" -version = "0.2.10" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] @@ -1620,19 +1840,20 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.4.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.5", + "getrandom 0.2.7", "redox_syscall", + "thiserror", ] [[package]] name = "regex" -version = "1.5.6" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" dependencies = [ "regex-syntax", ] @@ -1645,9 +1866,9 @@ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" [[package]] name = "regex-syntax" -version = "0.6.26" +version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" [[package]] name = "remove_dir_all" @@ -1660,9 +1881,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.9" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f242f1488a539a79bac6dbe7c8609ae43b7914b7736210f239a37cccb32525" +checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92" dependencies = [ "async-compression", "base64", @@ -1689,11 +1910,12 @@ dependencies = [ "tokio", "tokio-native-tls", "tokio-util", + "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg 0.7.0", + "winreg 0.10.1", ] [[package]] @@ -1707,9 +1929,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "same-file" @@ -1722,12 +1944,12 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" dependencies = [ "lazy_static", - "winapi", + "windows-sys", ] [[package]] @@ -1754,9 +1976,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.6.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" dependencies = [ "bitflags", "core-foundation", @@ -1797,9 +2019,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.6" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d" +checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711" [[package]] name = "serde" @@ -1833,11 +2055,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" dependencies = [ - "itoa 1.0.1", + "itoa 1.0.3", "ryu", "serde", ] @@ -1849,16 +2071,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 1.0.1", + "itoa 1.0.3", "ryu", "serde", ] [[package]] name = "serde_yaml" -version = "0.8.23" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a521f2940385c165a24ee286aa8599633d162077a54bdcae2a6fd5a7bfa7a0" +checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" dependencies = [ "indexmap", "ryu", @@ -1878,9 +2100,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d" +checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" dependencies = [ "libc", "signal-hook-registry", @@ -1888,9 +2110,9 @@ dependencies = [ [[package]] name = "signal-hook-mio" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29fd5867f1c4f2c5be079aee7a2adf1152ebb04a4bc4d341f504b7dece607ed4" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" dependencies = [ "libc", "mio 0.7.14", @@ -1908,21 +2130,24 @@ dependencies = [ [[package]] name = "siphasher" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a86232ab60fa71287d7f2ddae4a7073f6b7aac33631c3015abb556f08c6d0a3e" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" [[package]] name = "slab" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] [[package]] name = "smallvec" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" [[package]] name = "so" @@ -1948,6 +2173,7 @@ dependencies = [ "termimad", "thiserror", "tokio", + "webbrowser", ] [[package]] @@ -1968,13 +2194,13 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "string_cache" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33994d0838dc2d152d17a62adf608a869b5e846b65b389af7f3dbc1de45c5b26" +checksum = "213494b7a2b503146286049378ce02b482200519accc31872ee8be91fa820a08" dependencies = [ - "lazy_static", "new_debug_unreachable", - "parking_lot 0.11.2", + "once_cell", + "parking_lot 0.12.1", "phf_shared 0.10.0", "precomputed-hash", "serde", @@ -1982,12 +2208,12 @@ dependencies = [ [[package]] name = "string_cache_codegen" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97" +checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" dependencies = [ - "phf_generator", - "phf_shared 0.8.0", + "phf_generator 0.10.0", + "phf_shared 0.10.0", "proc-macro2", "quote", ] @@ -1998,6 +2224,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +[[package]] +name = "strsim" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" + [[package]] name = "strsim" version = "0.10.0" @@ -2031,9 +2263,9 @@ dependencies = [ [[package]] name = "tendril" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9ef557cb397a4f0a5a3a628f06515f78563f2209e64d47055d9dc6052bf5e33" +checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" dependencies = [ "futf", "mac", @@ -2092,18 +2324,18 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21" dependencies = [ "proc-macro2", "quote", @@ -2112,11 +2344,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.7" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "004cbc98f30fa233c61a38bc77e96a9106e65c88f2d3bef182ae952027e5753d" +checksum = "db76ff9fa4b1458b3c7f077f3ff9887394058460d21e634355b273aaf11eea45" dependencies = [ - "itoa 1.0.1", + "itoa 1.0.3", "libc", "num_threads", ] @@ -2133,9 +2365,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ "tinyvec_macros", ] @@ -2148,17 +2380,18 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.17.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee" +checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581" dependencies = [ + "autocfg", "bytes", "libc", "memchr", - "mio 0.8.0", + "mio 0.8.4", "num_cpus", "once_cell", - "parking_lot 0.12.0", + "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", "socket2", @@ -2168,9 +2401,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" +checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" dependencies = [ "proc-macro2", "quote", @@ -2189,38 +2422,38 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.6.9" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" +checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" dependencies = [ "bytes", "futures-core", "futures-sink", - "log", "pin-project-lite", "tokio", + "tracing", ] [[package]] name = "toml" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" dependencies = [ "serde", ] [[package]] name = "tower-service" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.31" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6c650a8ef0cd2dd93736f033d21cbd1224c5a967aa0c258d00fcf7dafef9b9f" +checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" dependencies = [ "cfg-if 1.0.0", "pin-project-lite", @@ -2229,11 +2462,11 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.22" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03cfcb51380632a72d3111cb8d3447a8d908e577d31beeac006f836383d29a23" +checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" dependencies = [ - "lazy_static", + "once_cell", ] [[package]] @@ -2253,15 +2486,21 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.7" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" + +[[package]] +name = "unicode-ident" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" +checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" [[package]] name = "unicode-normalization" -version = "0.1.19" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" dependencies = [ "tinyvec", ] @@ -2280,9 +2519,9 @@ checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "unicode-xid" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" [[package]] name = "url" @@ -2349,9 +2588,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" @@ -2429,6 +2668,26 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webbrowser" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a3cffdb686fbb24d9fb8f03a213803277ed2300f11026a3afe1f108dc021b" +dependencies = [ + "jni", + "ndk-glue", + "url", + "web-sys", + "widestring", + "winapi", +] + +[[package]] +name = "widestring" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" + [[package]] name = "winapi" version = "0.3.9" @@ -2462,9 +2721,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.32.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ "windows_aarch64_msvc", "windows_i686_gnu", @@ -2475,33 +2734,33 @@ dependencies = [ [[package]] name = "windows_aarch64_msvc" -version = "0.32.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" [[package]] name = "windows_i686_gnu" -version = "0.32.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" [[package]] name = "windows_i686_msvc" -version = "0.32.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" [[package]] name = "windows_x86_64_gnu" -version = "0.32.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" [[package]] name = "windows_x86_64_msvc" -version = "0.32.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" [[package]] name = "winreg" @@ -2514,9 +2773,9 @@ dependencies = [ [[package]] name = "winreg" -version = "0.7.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ "winapi", ] diff --git a/Cargo.toml b/Cargo.toml index d3bec91..fa6c702 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,30 +30,26 @@ path = "benches/md_parsing.rs" harness = false [dependencies] -thiserror = "1.0" clap = "2.33" +crossterm = { version = "0.20", features = ["event-stream"] } directories = "2.0" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -serde_yaml = "0.8" - -reqwest = { version = "0.11", features = ["gzip", "json"] } -tokio = { version = "1.7", features = ["full"] } futures = "0.3" -rayon = "1.5" - -percent-encoding = "2.1" -scraper = "0.12" - lazy_static = "1.4" minimad = "0.8" -termimad = "0.13" - -crossterm = { version = "0.20", features = ["event-stream"] } +percent-encoding = "2.1" pulldown-cmark = { version = "0.8", default-features = false } - +rayon = "1.5" +reqwest = { version = "0.11", features = ["gzip", "json"] } +scraper = "0.12" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +serde_yaml = "0.8" # temporary to fix https://github.com/Lymia/enumset/issues/17 syn = "=1.0.57" +termimad = "0.13" +thiserror = "1.0" +tokio = { version = "1.7", features = ["full"] } +webbrowser = "0.7" [dependencies.cursive] version = "0.17" diff --git a/src/main.rs b/src/main.rs index c2e8f51..e732d5a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,17 +13,16 @@ use tokio::task; use config::Config; use error::{Error, Result}; -use stackexchange::{LocalStorage, Question, Search}; +use stackexchange::{LocalStorage, Search}; use term::Term; -use tui::markdown::Markdown; fn main() -> Result<()> { // Tokio runtime Runtime::new()? .block_on(run()) - .map(|qs| { + .map(|app| { // Run TUI - qs.map(|(qs, cfg)| tui::run(qs, cfg)); + app.map(tui::App::run); }) .or_else(|e: Error| { // Handle errors @@ -33,7 +32,7 @@ fn main() -> Result<()> { /// Runs the CLI and, if the user wishes to enter the TUI, returns /// question/answer data -async fn run() -> Result>, Config)>> { +async fn run() -> Result> { // Get CLI opts let opts = cli::get_opts()?; let config = opts.config; @@ -88,18 +87,17 @@ async fn run() -> Result>, Config)>> { term.print("\nPress **[SPACE]** to see more results, or any other key to exit"); // Kick off the rest of the search in the background - let qs = task::spawn(async move { search.search_md().await }); + let app = task::spawn(async move { tui::App::from_search(search).await }); if !Term::wait_for_char(' ')? { return Ok(None); } // Get the rest of the questions - return Ok(Some((Term::wrap_spinner(qs).await?.unwrap()?, config))); + return Ok(Some(Term::wrap_spinner(app).await?.unwrap()?)); } else { - return Ok(Some(( - Term::wrap_spinner(search.search_md()).await??, - config, - ))); + return Ok(Some( + Term::wrap_spinner(tui::App::from_search(search)).await??, + )); } } Ok(None) diff --git a/src/stackexchange/api.rs b/src/stackexchange/api.rs index cf326f2..57f8f88 100644 --- a/src/stackexchange/api.rs +++ b/src/stackexchange/api.rs @@ -21,12 +21,14 @@ const SE_FILTER: &str = ".DND5X2VHHUH8HyJzpjo)5NvdHI3w6auG"; /// Pagesize when fetching all SE sites. Should be good for many years... const SE_SITES_PAGESIZE: u16 = 10000; +pub type Id = u32; + /// Represents a StackExchange answer with a custom selection of fields from /// the [StackExchange docs](https://api.stackexchange.com/docs/types/answer) #[derive(Clone, Deserialize, Debug)] pub struct Answer { #[serde(rename = "answer_id")] - pub id: u32, + pub id: Id, pub score: i32, #[serde(rename = "body_markdown")] pub body: S, @@ -35,19 +37,21 @@ pub struct Answer { /// Represents a StackExchange question with a custom selection of fields from /// the [StackExchange docs](https://api.stackexchange.com/docs/types/question) -// TODO container over answers should be generic iterator #[derive(Clone, Deserialize, Debug)] pub struct Question { #[serde(rename = "question_id")] - pub id: u32, + pub id: Id, pub score: i32, - #[serde(default = "Vec::new")] // N.B. empty vector default needed because questions endpoint cannot filter // answers >= 1 + #[serde(default = "Vec::new")] pub answers: Vec>, pub title: String, #[serde(rename = "body_markdown")] pub body: S, + // This is the only field that doesn't actually come back from SE; we add + // this site code to which the question belongs + pub site: Option, } /// Internal struct that represents the boilerplate response wrapper from SE API. @@ -98,7 +102,7 @@ impl Api { .into_iter() .filter(|q| !q.answers.is_empty()) .collect(); - Ok(Self::preprocess(qs)) + Ok(Self::preprocess(site, qs)) } /// Search against the SE site's /search/advanced endpoint with a given query. @@ -126,7 +130,7 @@ impl Api { .json::>>() .await? .items; - Ok(Self::preprocess(qs)) + Ok(Self::preprocess(site, qs)) } pub async fn sites(&self) -> Result> { @@ -159,9 +163,10 @@ impl Api { } /// Sorts answers by score + /// Add the site code to which the question belongs /// Preprocess SE markdown to "cmark" markdown (or something closer to it) /// This markdown preprocess _always_ happens. - fn preprocess(qs: Vec>) -> Vec> { + fn preprocess(site: &str, qs: Vec>) -> Vec> { qs.into_par_iter() .map(|q| { let mut answers = q.answers; @@ -175,6 +180,7 @@ impl Api { .collect(); Question { answers, + site: Some(site.to_string()), body: markdown::preprocess(q.body), ..q } diff --git a/src/stackexchange/mod.rs b/src/stackexchange/mod.rs index b0e1345..387ae54 100644 --- a/src/stackexchange/mod.rs +++ b/src/stackexchange/mod.rs @@ -4,6 +4,6 @@ mod search; // Exposed for benchmarking pub mod scraper; -pub use api::{Answer, Question}; +pub use api::{Answer, Id, Question}; pub use local_storage::LocalStorage; pub use search::Search; diff --git a/src/stackexchange/search.rs b/src/stackexchange/search.rs index 1357c80..d705867 100644 --- a/src/stackexchange/search.rs +++ b/src/stackexchange/search.rs @@ -26,10 +26,10 @@ const USER_AGENT: &str = // TODO this really needs a better name... #[derive(Clone)] pub struct Search { - api: Api, - config: Config, - query: String, - sites: HashMap, + pub api: Api, + pub config: Config, + pub query: String, + pub sites: HashMap, } impl Search { @@ -190,6 +190,7 @@ fn parse_markdown(qs: Vec>) -> Vec> { id: q.id, score: q.score, title: q.title, + site: q.site, } }) .collect::>() diff --git a/src/tui/app.rs b/src/tui/app.rs index 6658f16..3c2fedf 100644 --- a/src/tui/app.rs +++ b/src/tui/app.rs @@ -20,134 +20,181 @@ use super::views::{ }; use crate::config::Config; use crate::error::Result; -use crate::stackexchange::{Answer, Question}; +use crate::stackexchange::{Answer, Id, Question, Search}; pub const NAME_HELP_VIEW: &str = "help_view"; -// TODO an Arc app state that gets auto updated with new selections would -// be convenient - -pub fn run(qs: Vec>, cfg: Config) -> Result<()> { - let mut siv = cursive::default(); - siv.load_theme_file(Config::theme_file_path()?).unwrap(); // TODO dont unwrap - - let question_map: HashMap> = - qs.clone().into_iter().map(|q| (q.id, q)).collect(); - let question_map = Arc::new(question_map); - let answer_map: HashMap> = qs - .clone() - .into_iter() - .flat_map(|q| q.answers.into_iter().map(|a| (a.id, a))) - .collect(); - let answer_map = Arc::new(answer_map); - - let question_view = MdView::new(Name::QuestionView); - let answer_view = MdView::new(Name::AnswerView); - - let question_list_view = ListView::new_with_items( - Name::QuestionList, - qs.into_iter().map(|q| (preview_question(&q), q.id)), - move |s, qid| question_selected_callback(question_map.clone(), s, *qid), - ); - - let answer_list_view = ListView::new(Name::AnswerList, move |s, aid| { - let a = answer_map.get(aid).unwrap(); - s.call_on_name(NAME_ANSWER_VIEW, |v: &mut MdView| v.set_content(&a.body)); - }); - - siv.add_layer( - LayoutView::new( - 1, - question_list_view, - question_view, - answer_list_view, - answer_view, - ) - .add_vim_bindings(), - ); - - let cb = siv.call_on_name(NAME_QUESTION_LIST, |v: &mut ListView| v.select(0)); - if let Some(cb) = cb { - cb(&mut siv) +pub struct App { + questions: HashMap>, + answers: HashMap>, + config: Config, + sites: HashMap, +} + +impl App { + pub async fn from_search(search: Search) -> Result { + let qs = search.search_md().await?; + let questions: HashMap> = + qs.clone().into_iter().map(|q| (q.id, q)).collect(); + let answers: HashMap> = qs + .into_iter() + .flat_map(|q| q.answers.into_iter().map(|a| (a.id, a))) + .collect(); + Ok(Self { + config: search.config, + sites: search.sites, + questions, + answers, + }) } - // Help / View keymappings - siv.add_global_callback('?', |s| { - if let Some(pos) = s.screen_mut().find_layer_from_name(NAME_HELP_VIEW) { - s.screen_mut().remove_layer(pos); - } else { - s.add_layer(help()); - } - }); - - // Reload theme - siv.add_global_callback(Event::CtrlChar('r'), |s| { - s.load_theme_file(Config::theme_file_path().unwrap()) - .unwrap() - }); - - // Copy contents to sys clipboard - siv.add_global_callback('y', move |s| { - let mut v: ViewRef = s - .find_name(NAME_FULL_LAYOUT) - .expect("bug: layout view should exist"); - let md = v.get_focused_content(); - if let Some(mut copy_cmd) = cfg.get_copy_cmd() { - let res = (|| { - let mut child = copy_cmd.spawn().map_err(|e| { - if e.kind() == io::ErrorKind::NotFound { - io::Error::new( - io::ErrorKind::Other, - "couldn't exec copy cmd; you may need to configure it manually", - ) - } else { - e - } - })?; - let mut stdin = child.stdin.take().ok_or_else(|| { - io::Error::new(io::ErrorKind::Other, "couldn't get stdin of copy cmd") - })?; - stdin.write_all(md.source().as_bytes())?; - Ok("copied to clipboard!".to_string()) - })(); - temp_feedback_msg(s, res); - } - }); + // TODO a app field that gets auto updated with new selections would be convenient + pub fn run(self) -> Result<()> { + // The underlying fields of self are just static data that we + // borrow from various places and callbacks; wrap in Arc to just have + // one allocation that gets referenced from wherever. + let arc = Arc::new(self); - siv.add_global_callback(Event::Key(Key::Esc), |s| { - if let Some(pos) = s.screen_mut().find_layer_from_name(NAME_HELP_VIEW) { - s.screen_mut().remove_layer(pos); - } - if let Some(pos) = s.screen_mut().find_layer_from_name(NAME_TEMP_MSG) { - s.screen_mut().remove_layer(pos); + let mut siv = cursive::default(); + siv.load_theme_file(Config::theme_file_path()?).unwrap(); // TODO dont unwrap + + let question_view = MdView::new(Name::QuestionView); + let answer_view = MdView::new(Name::AnswerView); + + let arc2 = arc.clone(); + let question_list_view = ListView::new_with_items( + Name::QuestionList, + arc.questions + .clone() + .into_values() + .map(|q| (preview_question(&q), q.id)), + move |s, qid| arc2.question_selected_callback(s, *qid), + ); + + let arc2 = arc.clone(); + let answer_list_view = ListView::new(Name::AnswerList, move |s, aid| { + let a = arc2.answers.get(aid).unwrap(); + s.call_on_name(NAME_ANSWER_VIEW, |v: &mut MdView| v.set_content(&a.body)); + }); + + siv.add_layer( + LayoutView::new( + 1, + question_list_view, + question_view, + answer_list_view, + answer_view, + ) + .add_vim_bindings(), + ); + + let cb = siv.call_on_name(NAME_QUESTION_LIST, |v: &mut ListView| v.select(0)); + if let Some(cb) = cb { + cb(&mut siv) } - }); - // Run the app - siv.run(); - Ok(()) -} + // Help / View keymappings + siv.add_global_callback('?', |s| { + if let Some(pos) = s.screen_mut().find_layer_from_name(NAME_HELP_VIEW) { + s.screen_mut().remove_layer(pos); + } else { + s.add_layer(help()); + } + }); + + // Reload theme + siv.add_global_callback(Event::CtrlChar('r'), |s| { + s.load_theme_file(Config::theme_file_path().unwrap()) + .unwrap() + }); + + // Copy contents to sys clipboard + let arc2 = arc.clone(); + siv.add_global_callback('y', move |s| { + let mut v: ViewRef = s + .find_name(NAME_FULL_LAYOUT) + .expect("bug: layout view should exist"); + let md = v.get_focused_content(); + if let Some(mut copy_cmd) = arc2.config.get_copy_cmd() { + let res = (|| { + let mut child = copy_cmd.spawn().map_err(|e| { + if e.kind() == io::ErrorKind::NotFound { + io::Error::new( + io::ErrorKind::Other, + "couldn't exec copy cmd; you may need to configure it manually", + ) + } else { + e + } + })?; + let mut stdin = child.stdin.take().ok_or_else(|| { + io::Error::new(io::ErrorKind::Other, "couldn't get stdin of copy cmd") + })?; + stdin.write_all(md.source().as_bytes())?; + Ok("copied to clipboard!".to_string()) + })(); + temp_feedback_msg(s, res); + } + }); + + // Open in browser + let arc2 = arc; + siv.add_global_callback('o', move |s| { + let mut v: ViewRef = s + .find_name(NAME_FULL_LAYOUT) + .expect("bug: layout view should exist"); + if let Some((qid, aid)) = v.get_focused_ids() { + let res = webbrowser::open(&arc2.mk_url("stackoverflow".to_string(), qid, aid)) + .map(|_| "opened stackexchange in the browser!".to_string()); + dbg!(&res); + temp_feedback_msg(s, res); + } + }); + + siv.add_global_callback(Event::Key(Key::Esc), |s| { + if let Some(pos) = s.screen_mut().find_layer_from_name(NAME_HELP_VIEW) { + s.screen_mut().remove_layer(pos); + } + if let Some(pos) = s.screen_mut().find_layer_from_name(NAME_TEMP_MSG) { + s.screen_mut().remove_layer(pos); + } + }); -fn question_selected_callback( - question_map: Arc>>, - s: &mut Cursive, - qid: u32, -) { - let q = question_map.get(&qid).unwrap(); - let body = &q.body; - let XY { x, y: _y } = s.screen_size(); - // Update question view - s.call_on_name(NAME_QUESTION_VIEW, |v: &mut MdView| { - v.set_content(body); - }) - .expect("Panic: setting question view content failed"); - // Update answer list view - let cb = s - .call_on_name(NAME_ANSWER_LIST, |v: &mut ListView| { - v.reset_with_all(q.answers.iter().map(|a| (preview_answer(x, a), a.id))) + // Run the app + siv.run(); + Ok(()) + } + + fn mk_url(&self, site: String, question_id: Id, answer_id_opt: Option) -> String { + // answer link actually doesn't need question id + let site_url = self + .sites + .get(&site) + .expect("we lost track of a site?!") + .to_string(); + match answer_id_opt { + Some(answer_id) => format!("https://{site_url}/a/{answer_id}"), + None => format!("https://{site_url}/a/{question_id}"), + } + } + + pub fn question_selected_callback(&self, s: &mut Cursive, qid: u32) { + let q = self.questions.get(&qid).unwrap(); + let body = &q.body; + let XY { x, y: _y } = s.screen_size(); + // Update question view + s.call_on_name(NAME_QUESTION_VIEW, |v: &mut MdView| { + v.set_content(body); }) - .expect("Panic: setting answer list content failed"); - cb(s) + .expect("Panic: setting question view content failed"); + // Update answer list view + let cb = s + .call_on_name(NAME_ANSWER_LIST, |v: &mut ListView| { + v.reset_with_all(q.answers.iter().map(|a| (preview_answer(x, a), a.id))) + }) + .expect("Panic: setting answer list content failed"); + cb(s) + } } fn preview_question(q: &Question) -> StyledString { @@ -201,6 +248,7 @@ pub fn help() -> Dialog { **G**: Scroll To Bottom ## Misc +**o**: Open current q/a in the browser **y**: Copy current q/a to the clipboard **q, ZZ, Ctrl**: Exit **Ctrl**: Reload theme @@ -216,7 +264,7 @@ pub fn help() -> Dialog { } pub fn temp_feedback_msg(siv: &mut Cursive, msg: io::Result) { - // TODO semaphore to close existing msg before displaying new one + // TODO semaphore to close existing msg before displaying new one? let style = if msg.is_ok() { Color::Light(BaseColor::Green) } else { diff --git a/src/tui/mod.rs b/src/tui/mod.rs index 9bdd9da..07b8421 100644 --- a/src/tui/mod.rs +++ b/src/tui/mod.rs @@ -2,4 +2,4 @@ mod app; pub mod markdown; mod views; -pub use app::run; +pub use app::App; diff --git a/src/tui/views.rs b/src/tui/views.rs index 0e7971d..ef96a6a 100644 --- a/src/tui/views.rs +++ b/src/tui/views.rs @@ -155,6 +155,10 @@ impl ListView { view.with_name(name) } + pub fn get_current_selection(&mut self) -> Option { + self.call_on_inner(|sv| sv.selection().as_deref().copied()) + } + pub fn reset_with_all(&mut self, iter: I) -> Callback where S: Into, @@ -399,6 +403,23 @@ impl LayoutView { .expect("call on md view failed") } + // There may be no questions and there may be no answers? There should be answers but w/e + pub fn get_focused_ids(&mut self) -> Option<(u32, Option)> { + let curr_question = self + .view + .call_on_name(NAME_QUESTION_LIST, |v: &mut ListView| { + v.get_current_selection() + }) + .flatten()?; + let curr_answer = self + .view + .call_on_name(NAME_ANSWER_LIST, |v: &mut ListView| { + v.get_current_selection() + }) + .flatten(); + Some((curr_question, curr_answer)) + } + fn get_constraints(&self, screen_size: Vec2) -> LayoutViewSizing { let heuristic = 1; let width = SizeConstraint::Fixed(screen_size.x / 2 - heuristic); From c28bb74f8e10cb80143fdaccdd8b52dafae646e6 Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Sun, 21 Aug 2022 19:05:25 -0700 Subject: [PATCH 15/41] Bump version to 0.4.8 --- CHANGELOG.md | 5 ++++- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7efcbe7..c44c66a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.4.8] + #### Added - Keybinding: Press `o` to open the current answer in the default browser @@ -76,7 +78,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.3.5] - (Unofficial) initial passable release -[Unreleased]: (https://github.com/samtay/so/compare/v0.4.6...HEAD) +[Unreleased]: (https://github.com/samtay/so/compare/v0.4.8...HEAD) +[0.4.8]: (https://github.com/samtay/so/compare/v0.4.7...v0.4.8) [0.4.7]: (https://github.com/samtay/so/compare/v0.4.6...v0.4.7) [0.4.6]: (https://github.com/samtay/so/compare/v0.4.5...v0.4.6) [0.4.5]: (https://github.com/samtay/so/compare/v0.4.3...v0.4.5) diff --git a/Cargo.lock b/Cargo.lock index 9c1792f..91eac65 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2151,7 +2151,7 @@ checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" [[package]] name = "so" -version = "0.4.7" +version = "0.4.8" dependencies = [ "clap", "criterion", diff --git a/Cargo.toml b/Cargo.toml index fa6c702..8e606df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "so" -version = "0.4.7" +version = "0.4.8" license = "MIT" description = "A terminal interface for StackOverflow" readme = "README.md" From a5c3a48b421dd75075531937e60e32008c3c3b97 Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Mon, 22 Aug 2022 17:26:41 -0700 Subject: [PATCH 16/41] Bump deps --- Cargo.lock | 338 +++++++++++++------------------------------- Cargo.toml | 18 +-- src/term.rs | 2 +- src/tui/markdown.rs | 16 +-- 4 files changed, 114 insertions(+), 260 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 91eac65..df37c95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -100,15 +100,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" -[[package]] -name = "cast" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a" -dependencies = [ - "rustc_version", -] - [[package]] name = "cast" version = "0.3.0" @@ -170,6 +161,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[package]] +name = "coolor" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af4d7a805ca0d92f8c61a31c809d4323fdaa939b0b440e544d21db7797c5aaad" +dependencies = [ + "crossterm", +] + [[package]] name = "core-foundation" version = "0.9.3" @@ -197,12 +197,12 @@ dependencies = [ [[package]] name = "criterion" -version = "0.3.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23" +checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" dependencies = [ "atty", - "cast 0.2.7", + "cast", "clap", "criterion-plot", "csv", @@ -227,7 +227,7 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" dependencies = [ - "cast 0.3.0", + "cast", "itertools", ] @@ -302,46 +302,21 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.20.0" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ebde6a9dd5e331cd6c6f48253254d117642c31653baa475e394657c59c1f7d" +checksum = "a2102ea4f781910f8a5b98dd061f4c2023f479ce7bb1236330099ceb5a93cf17" dependencies = [ "bitflags", - "crossterm_winapi 0.8.0", + "crossterm_winapi", "futures-core", "libc", - "mio 0.7.14", - "parking_lot 0.11.2", - "signal-hook", - "signal-hook-mio", - "winapi", -] - -[[package]] -name = "crossterm" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85525306c4291d1b73ce93c8acf9c339f9b213aef6c1d85c3830cbf1c16325c" -dependencies = [ - "bitflags", - "crossterm_winapi 0.9.0", - "libc", - "mio 0.7.14", - "parking_lot 0.11.2", + "mio", + "parking_lot", "signal-hook", "signal-hook-mio", "winapi", ] -[[package]] -name = "crossterm_winapi" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a6966607622438301997d3dac0d2f6e9a90c68bb6bc1785ea98456ab93c0507" -dependencies = [ - "winapi", -] - [[package]] name = "crossterm_winapi" version = "0.9.0" @@ -402,14 +377,14 @@ dependencies = [ [[package]] name = "cursive" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca536d245342f6c005e7547ab640e444a3dc2fc0319a92124c8c1cbff025e775" +checksum = "cfaeae1b6ebac028126197b63a4df82d70833ea724f279e236eaf94d28edcd9c" dependencies = [ "ahash", "cfg-if 1.0.0", "crossbeam-channel", - "crossterm 0.22.1", + "crossterm", "cursive_core", "lazy_static", "libc", @@ -447,43 +422,19 @@ dependencies = [ [[package]] name = "darling" -version = "0.10.2" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" dependencies = [ - "darling_core 0.10.2", - "darling_macro 0.10.2", -] - -[[package]] -name = "darling" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f2c43f534ea4b0b049015d00269734195e6d3f0f6635cb692251aca6f9f8b3c" -dependencies = [ - "darling_core 0.12.4", - "darling_macro 0.12.4", -] - -[[package]] -name = "darling_core" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.9.3", - "syn", + "darling_core", + "darling_macro", ] [[package]] name = "darling_core" -version = "0.12.4" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e91455b86830a1c21799d94524df0845183fa55bafd9aa137b01c7d1065fa36" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" dependencies = [ "fnv", "ident_case", @@ -495,22 +446,11 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.10.2" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ - "darling_core 0.10.2", - "quote", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29b5acf0dea37a7f66f7b25d2c5e93fd46f8f6968b1a5d7a3e02e97768afc95a" -dependencies = [ - "darling_core 0.12.4", + "darling_core", "quote", "syn", ] @@ -607,20 +547,20 @@ dependencies = [ [[package]] name = "enumset" -version = "1.0.6" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbd795df6708a599abf1ee10eacc72efd052b7a5f70fdf0715e4d5151a6db9c3" +checksum = "4799cdb24d48f1f8a7a98d06b7fde65a85a2d1e42b25a889f5406aa1fbefe074" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e19c52f9ec503c8a68dc04daf71a04b07e690c32ab1a8b68e33897f255269d47" +checksum = "ea83a3fbdc1d999ccfbcbee717eab36f8edf2d71693a23ce0d7cca19e085304c" dependencies = [ - "darling 0.12.4", + "darling", "proc-macro2", "quote", "syn", @@ -1025,9 +965,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.49" +version = "0.3.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc15e39392125075f60c95ba416f5381ff6c3a948ff02ab12464715adf56c821" +checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" dependencies = [ "wasm-bindgen", ] @@ -1044,12 +984,6 @@ version = "0.2.132" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - [[package]] name = "lock_api" version = "0.4.7" @@ -1124,9 +1058,9 @@ checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" [[package]] name = "minimad" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8957f240ecb82a4e699bcf4db189fe8a7f5aa68b9e6d5abf829c62a9ee4630ed" +checksum = "cd37b2e65fbd459544194d8f52ed84027e031684335a062c708774c09d172b0b" dependencies = [ "once_cell", ] @@ -1140,19 +1074,6 @@ dependencies = [ "adler", ] -[[package]] -name = "mio" -version = "0.7.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" -dependencies = [ - "libc", - "log", - "miow", - "ntapi", - "winapi", -] - [[package]] name = "mio" version = "0.8.4" @@ -1165,15 +1086,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", -] - [[package]] name = "native-tls" version = "0.2.10" @@ -1205,9 +1117,9 @@ dependencies = [ [[package]] name = "ndk" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d64d6af06fde0e527b1ba5c7b79a6cc89cfc46325b0b2887dffe8f70197e0c3c" +checksum = "2032c77e030ddee34a6787a64166008da93f6a352b629261d0fee232b8742dd4" dependencies = [ "bitflags", "jni-sys", @@ -1224,9 +1136,9 @@ checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" [[package]] name = "ndk-glue" -version = "0.4.2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3648f3609716eb7dbf5f5b5d4b84fcd67dd4c34efcdb12e4a6c0929c2ac48349" +checksum = "0d0c4a7b83860226e6b4183edac21851f05d5a51756e97a1144b7f5a6b63e65f" dependencies = [ "lazy_static", "libc", @@ -1239,12 +1151,12 @@ dependencies = [ [[package]] name = "ndk-macro" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d1c6307dc424d0f65b9b06e94f88248e6305726b14729fd67a5e47b2dc481d" +checksum = "0df7ac00c4672f9d5aece54ee3347520b7e20f158656c7db2e6de01902eb7a6c" dependencies = [ - "darling 0.10.2", - "proc-macro-crate 0.1.5", + "darling", + "proc-macro-crate", "proc-macro2", "quote", "syn", @@ -1252,9 +1164,12 @@ dependencies = [ [[package]] name = "ndk-sys" -version = "0.2.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1bcdd74c20ad5d95aacd60ef9ba40fdf77f767051040541df557b7a9b2a2121" +checksum = "6e5a6ae77c8ee183dcbbba6150e2e6b9f3f4196a7666c02a715a95692ec1fa97" +dependencies = [ + "jni-sys", +] [[package]] name = "new_debug_unreachable" @@ -1268,15 +1183,6 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" -[[package]] -name = "ntapi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" -dependencies = [ - "winapi", -] - [[package]] name = "num" version = "0.4.0" @@ -1365,7 +1271,7 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" dependencies = [ - "proc-macro-crate 1.2.1", + "proc-macro-crate", "proc-macro2", "quote", "syn", @@ -1465,17 +1371,6 @@ dependencies = [ "winreg 0.5.1", ] -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.5", -] - [[package]] name = "parking_lot" version = "0.12.1" @@ -1483,21 +1378,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.3", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" -dependencies = [ - "cfg-if 1.0.0", - "instant", - "libc", - "redox_syscall", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -1622,9 +1503,9 @@ checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "plotters" -version = "0.3.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45ca0ae5f169d0917a7c7f5a9c1a3d3d9598f18f529dd2b8373ed988efea307a" +checksum = "716b4eeb6c4a1d3ecc956f75b43ec2e8e8ba80026413e70a3f41fd3313d3492b" dependencies = [ "num-traits", "plotters-backend", @@ -1660,15 +1541,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" -[[package]] -name = "proc-macro-crate" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" -dependencies = [ - "toml", -] - [[package]] name = "proc-macro-crate" version = "1.2.1" @@ -1697,9 +1569,9 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.8.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffade02495f22453cd593159ea2f59827aae7f53fa8323f756799b670881dcf8" +checksum = "2d9cc634bc78768157b5cbfe988ffcd1dcba95cd2b2f03a88316c08c6d00ed63" dependencies = [ "bitflags", "memchr", @@ -2025,9 +1897,9 @@ checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711" [[package]] name = "serde" -version = "1.0.118" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" +checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" dependencies = [ "serde_derive", ] @@ -2044,9 +1916,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.118" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" +checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" dependencies = [ "proc-macro2", "quote", @@ -2055,9 +1927,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.83" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" +checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" dependencies = [ "itoa 1.0.3", "ryu", @@ -2078,14 +1950,15 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.8.26" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" +checksum = "7a09f551ccc8210268ef848f0bab37b306e87b85b2e017b899e7fb815f5aed62" dependencies = [ "indexmap", + "itoa 1.0.3", "ryu", "serde", - "yaml-rust", + "unsafe-libyaml", ] [[package]] @@ -2115,7 +1988,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" dependencies = [ "libc", - "mio 0.7.14", + "mio", "signal-hook", ] @@ -2155,7 +2028,7 @@ version = "0.4.8" dependencies = [ "clap", "criterion", - "crossterm 0.20.0", + "crossterm", "cursive", "directories", "futures", @@ -2169,7 +2042,6 @@ dependencies = [ "serde", "serde_json", "serde_yaml", - "syn", "termimad", "thiserror", "tokio", @@ -2200,7 +2072,7 @@ checksum = "213494b7a2b503146286049378ce02b482200519accc31872ee8be91fa820a08" dependencies = [ "new_debug_unreachable", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "phf_shared 0.10.0", "precomputed-hash", "serde", @@ -2224,12 +2096,6 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" -[[package]] -name = "strsim" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" - [[package]] name = "strsim" version = "0.10.0" @@ -2238,13 +2104,13 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.57" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4211ce9909eb971f111059df92c45640aad50a619cf55cd76476be803c4c68e6" +checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -2284,12 +2150,13 @@ dependencies = [ [[package]] name = "termimad" -version = "0.13.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a09f249613ba31188fd902030fcbc94bbdebb5e881fe7fcb58be16fb50e0d77a" +checksum = "c8a16d7de8d4c97a4149cc3b9d3681c5dba36011c303745bb1af19636e89ba39" dependencies = [ + "coolor", "crossbeam", - "crossterm 0.20.0", + "crossterm", "minimad", "thiserror", "unicode-width", @@ -2388,10 +2255,10 @@ dependencies = [ "bytes", "libc", "memchr", - "mio 0.8.4", + "mio", "num_cpus", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", @@ -2518,10 +2385,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] -name = "unicode-xid" -version = "0.2.3" +name = "unsafe-libyaml" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" +checksum = "931179334a56395bcf64ba5e0ff56781381c1a5832178280c7d7f91d1679aeb0" [[package]] name = "url" @@ -2594,9 +2461,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.72" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fe8f61dba8e5d645a4d8132dc7a0a66861ed5e1045d2c0ed940fab33bac0fbe" +checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -2604,13 +2471,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.72" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046ceba58ff062da072c7cb4ba5b22a37f00a302483f7e2a6cdc18fedbdc1fd3" +checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" dependencies = [ "bumpalo", - "lazy_static", "log", + "once_cell", "proc-macro2", "quote", "syn", @@ -2619,9 +2486,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.22" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73157efb9af26fb564bb59a009afd1c7c334a44db171d280690d0c3faaec3468" +checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -2631,9 +2498,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.72" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef9aa01d36cda046f797c57959ff5f3c615c9cc63997a8d545831ec7976819b" +checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2641,9 +2508,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.72" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96eb45c1b2ee33545a813a92dbb53856418bf7eb54ab34f7f7ff1448a5b3735d" +checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" dependencies = [ "proc-macro2", "quote", @@ -2654,15 +2521,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.72" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7148f4696fb4960a346eaa60bbfb42a1ac4ebba21f750f75fc1375b098d5ffa" +checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" [[package]] name = "web-sys" -version = "0.3.49" +version = "0.3.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fe19d70f5dacc03f6e46777213facae5ac3801575d56ca6cbd4c93dcd12310" +checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" dependencies = [ "js-sys", "wasm-bindgen", @@ -2785,12 +2652,3 @@ name = "xi-unicode" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a67300977d3dc3f8034dae89778f502b6ba20b269527b3223ba59c0cf393bb8a" - -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] diff --git a/Cargo.toml b/Cargo.toml index 8e606df..48eaae7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,35 +31,31 @@ harness = false [dependencies] clap = "2.33" -crossterm = { version = "0.20", features = ["event-stream"] } +crossterm = { version = "0.23", features = ["event-stream"] } directories = "2.0" futures = "0.3" lazy_static = "1.4" -minimad = "0.8" +minimad = "0.9" percent-encoding = "2.1" -pulldown-cmark = { version = "0.8", default-features = false } +pulldown-cmark = { version = "0.9", default-features = false } rayon = "1.5" reqwest = { version = "0.11", features = ["gzip", "json"] } scraper = "0.12" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -serde_yaml = "0.8" -# temporary to fix https://github.com/Lymia/enumset/issues/17 -syn = "=1.0.57" -termimad = "0.13" +serde_yaml = "0.9" +termimad = "0.20" thiserror = "1.0" -tokio = { version = "1.7", features = ["full"] } +tokio = { version = "1.20", features = ["full"] } webbrowser = "0.7" [dependencies.cursive] -version = "0.17" +version = "0.18" default-features = false features = ["toml"] [features] default = ["cursive/termion-backend"] -windows = ["cursive/crossterm-backend"] -termion-backend = ["cursive/termion-backend"] ncurses-backend = ["cursive/ncurses-backend"] pancurses-backend = ["cursive/pancurses-backend"] crossterm-backend = ["cursive/crossterm-backend"] diff --git a/src/term.rs b/src/term.rs index 44544aa..abb27c3 100644 --- a/src/term.rs +++ b/src/term.rs @@ -153,7 +153,7 @@ impl Spinner { while let Err(TryRecvError::Empty) = rx.try_recv() { execute!( stderr(), - cursor::MoveToColumn(0), + cursor::MoveToColumn(1), terminal::Clear(ClearType::CurrentLine), Print(dots.next().unwrap()) )?; diff --git a/src/tui/markdown.rs b/src/tui/markdown.rs index 9b03dde..dd38992 100644 --- a/src/tui/markdown.rs +++ b/src/tui/markdown.rs @@ -10,7 +10,7 @@ use cursive::theme::{Effect, PaletteColor, Style}; use cursive::utils::markup::{StyledIndexedSpan, StyledString}; use cursive::utils::span::{IndexedCow, IndexedSpan}; -use pulldown_cmark::{self, CowStr, Event, Options, Tag}; +use pulldown_cmark::{self, CowStr, Event, HeadingLevel, Options, Tag}; pub type Markdown = StyledString; @@ -79,16 +79,16 @@ fn parse_spans(input: &str) -> Vec { } /// Iterator that parse a markdown text and outputs styled spans. -pub struct Parser<'a> { +pub struct Parser<'a, 'b> { first: bool, item: Option, in_list: bool, after_code_block: bool, stack: Vec