summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Tay <samctay@pm.me>2022-08-22 18:02:16 -0700
committerSam Tay <samctay@pm.me>2022-08-22 18:20:50 -0700
commit29815c2fabc4e691fcf94fd26dea22a0ca81aaf4 (patch)
treec95b42d7f065759042aa887604075937688c70e0
parenta5c3a48b421dd75075531937e60e32008c3c3b97 (diff)
Dont block tokio task
-rw-r--r--Cargo.lock7
-rw-r--r--Cargo.toml1
-rw-r--r--src/error.rs3
-rw-r--r--src/main.rs2
-rw-r--r--src/term.rs40
5 files changed, 35 insertions, 18 deletions
diff --git a/Cargo.lock b/Cargo.lock
index df37c95..1ef3f72 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -29,6 +29,12 @@ dependencies = [
]
[[package]]
+name = "anyhow"
+version = "1.0.62"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305"
+
+[[package]]
name = "async-compression"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2026,6 +2032,7 @@ checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
name = "so"
version = "0.4.8"
dependencies = [
+ "anyhow",
"clap",
"criterion",
"crossterm",
diff --git a/Cargo.toml b/Cargo.toml
index 48eaae7..211d8a9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -30,6 +30,7 @@ path = "benches/md_parsing.rs"
harness = false
[dependencies]
+anyhow = "1.0"
clap = "2.33"
crossterm = { version = "0.23", features = ["event-stream"] }
directories = "2.0"
diff --git a/src/error.rs b/src/error.rs
index 2bcb899..cc15174 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -2,8 +2,11 @@ use std::path::PathBuf;
pub type Result<T, E = Error> = std::result::Result<T, E>;
+// TODO convert/remove this to just use anyhow
#[derive(thiserror::Error, Debug)]
pub enum Error {
+ #[error("{0}")]
+ Anyhow(#[from] anyhow::Error),
#[error("Termimad error: {0}")]
Termimad(#[from] termimad::Error),
#[error("Crossterm error: {0}")]
diff --git a/src/main.rs b/src/main.rs
index e732d5a..40a1e51 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -88,7 +88,7 @@ async fn run() -> Result<Option<tui::App>> {
// Kick off the rest of the search in the background
let app = task::spawn(async move { tui::App::from_search(search).await });
- if !Term::wait_for_char(' ')? {
+ if !Term::wait_for_char(' ').await? {
return Ok(None);
}
diff --git a/src/term.rs b/src/term.rs
index abb27c3..e986bf7 100644
--- a/src/term.rs
+++ b/src/term.rs
@@ -1,3 +1,4 @@
+use anyhow::Context;
use crossterm::event::{read, Event, KeyCode, KeyEvent};
use crossterm::style::{Color, Print};
use crossterm::terminal::ClearType;
@@ -83,26 +84,31 @@ impl Term {
Ok(())
}
- /// Blocks and waits for the user to press any key. Returns whether or not that key is the
+ /// Waits for the user to press any key. Returns whether or not that key is the
/// character key `c`.
- pub fn wait_for_char(c: char) -> Result<bool> {
- let mut pressed = false;
- terminal::enable_raw_mode()?;
- loop {
- match read()? {
- Event::Key(KeyEvent {
- code: KeyCode::Char(ch),
- ..
- }) if ch == c => {
- pressed = true;
- break;
+ pub async fn wait_for_char(c: char) -> Result<bool> {
+ let (tx, rx) = oneshot::channel();
+
+ tokio::task::spawn_blocking(move || {
+ let mut pressed = false;
+ terminal::enable_raw_mode().unwrap();
+ loop {
+ match read().unwrap() {
+ Event::Key(KeyEvent {
+ code: KeyCode::Char(ch),
+ ..
+ }) if ch == c => {
+ pressed = true;
+ break;
+ }
+ Event::Key(_) => break,
+ _ => (),
}
- Event::Key(_) => break,
- _ => (),
}
- }
- terminal::disable_raw_mode()?;
- Ok(pressed)
+ terminal::disable_raw_mode().unwrap();
+ tx.send(pressed).unwrap();
+ });
+ Ok(rx.await.context("failed to get key event")?)
}
/// As it sounds, takes a future and shows a CLI spinner until it's output is ready