feat: Switch from smol runtime to tokio
This commit is contained in:
parent
4153f9f060
commit
dbfb3921ae
23 changed files with 242 additions and 235 deletions
|
|
@ -1,14 +1,14 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
// Copyright © 2021 System76
|
||||
|
||||
use futures::{AsyncBufReadExt, AsyncWriteExt, StreamExt};
|
||||
use futures::StreamExt;
|
||||
use pop_launcher::*;
|
||||
use regex::Regex;
|
||||
use smol::{
|
||||
process::{Command, Stdio},
|
||||
Unblock,
|
||||
use std::{borrow::Cow, io, process::Stdio};
|
||||
use tokio::{
|
||||
io::{AsyncBufReadExt, AsyncWriteExt},
|
||||
process::Command,
|
||||
};
|
||||
use std::{borrow::Cow, io};
|
||||
|
||||
pub async fn main() {
|
||||
let mut requests = json_input_stream(async_stdin());
|
||||
|
|
@ -37,7 +37,7 @@ pub async fn main() {
|
|||
|
||||
pub struct App {
|
||||
pub decimal_comma: bool,
|
||||
out: Unblock<io::Stdout>,
|
||||
out: tokio::io::Stdout,
|
||||
outcome: Option<String>,
|
||||
regex: Regex,
|
||||
}
|
||||
|
|
@ -158,14 +158,17 @@ async fn qcalc(regex: &mut Regex, expression: &str, decimal_comma: bool) -> Opti
|
|||
}
|
||||
};
|
||||
|
||||
let mut reader = futures::io::BufReader::new(stdout).lines().skip(2);
|
||||
let mut reader = tokio::io::BufReader::new(stdout).lines();
|
||||
let mut output = String::new();
|
||||
|
||||
let _ = reader.next_line().await;
|
||||
let _ = reader.next_line().await;
|
||||
|
||||
fn has_issue(line: &str) -> bool {
|
||||
line.starts_with("error") || line.starts_with("warning")
|
||||
}
|
||||
|
||||
while let Some(Ok(line)) = reader.next().await {
|
||||
while let Ok(Some(line)) = reader.next_line().await {
|
||||
let line = line.trim();
|
||||
|
||||
if line.is_empty() {
|
||||
|
|
@ -260,9 +263,9 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn approximate_result_formatting() {
|
||||
let task = smol::spawn(async {
|
||||
#[tokio::test]
|
||||
async fn approximate_result_formatting() {
|
||||
let task = tokio::spawn(async {
|
||||
let mut app = App {
|
||||
decimal_comma: false,
|
||||
..Default::default()
|
||||
|
|
@ -271,10 +274,8 @@ mod tests {
|
|||
app.outcome.take()
|
||||
});
|
||||
|
||||
smol::block_on(async {
|
||||
if let Some(result) = task.await {
|
||||
assert_eq!("≈ 2.333333333", result);
|
||||
}
|
||||
})
|
||||
if let Some(result) = task.await.unwrap() {
|
||||
assert_eq!("≈ 2.333333333", result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,12 @@ mod graphics;
|
|||
|
||||
use crate::*;
|
||||
use freedesktop_desktop_entry::{default_paths, DesktopEntry, Iter as DesktopIter, PathSource};
|
||||
use futures::{AsyncWrite, StreamExt};
|
||||
use futures::StreamExt;
|
||||
use pop_launcher::*;
|
||||
use std::borrow::Cow;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::path::PathBuf;
|
||||
use tokio::io::AsyncWrite;
|
||||
|
||||
#[derive(Debug, Eq)]
|
||||
struct Item {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@
|
|||
|
||||
use futures::prelude::*;
|
||||
use pop_launcher::*;
|
||||
use smol::Unblock;
|
||||
use std::{collections::BTreeMap, io, path::PathBuf};
|
||||
use std::{collections::BTreeMap, path::PathBuf};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Item {
|
||||
|
|
@ -38,7 +37,7 @@ pub async fn main() {
|
|||
pub struct App {
|
||||
entries: BTreeMap<PathBuf, Vec<Item>>,
|
||||
home: PathBuf,
|
||||
out: Unblock<io::Stdout>,
|
||||
out: tokio::io::Stdout,
|
||||
search_results: Vec<Item>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,13 @@
|
|||
|
||||
use futures::*;
|
||||
use pop_launcher::*;
|
||||
use smol::process::{Child, ChildStdout, Command, Stdio};
|
||||
use std::cell::Cell;
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Stdio;
|
||||
use std::rc::Rc;
|
||||
use tokio::io::AsyncBufReadExt;
|
||||
use tokio::process::{Child, ChildStdout, Command};
|
||||
|
||||
enum Event {
|
||||
Activate(u32),
|
||||
|
|
@ -37,12 +39,10 @@ pub async fn main() {
|
|||
Event::Activate(id) => {
|
||||
if let Some(selection) = app.search_results.get(id as usize) {
|
||||
let path = selection.clone();
|
||||
let handle = smol::spawn(async move {
|
||||
tokio::spawn(async move {
|
||||
crate::xdg_open(&path);
|
||||
});
|
||||
|
||||
handle.detach();
|
||||
|
||||
crate::send(&mut app.out, PluginResponse::Close).await;
|
||||
}
|
||||
}
|
||||
|
|
@ -114,7 +114,7 @@ pub async fn main() {
|
|||
struct SearchContext {
|
||||
pub active: Rc<Cell<bool>>,
|
||||
pub interrupt_rx: flume::Receiver<()>,
|
||||
pub out: smol::Unblock<io::Stdout>,
|
||||
pub out: tokio::io::Stdout,
|
||||
pub search_results: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
|
|
@ -148,7 +148,7 @@ impl SearchContext {
|
|||
tracing::debug!("searching for {}", search);
|
||||
|
||||
let (mut child, mut stdout) = match query(&search).await {
|
||||
Ok((child, stdout)) => (child, futures::io::BufReader::new(stdout).lines()),
|
||||
Ok((child, stdout)) => (child, tokio::io::BufReader::new(stdout).lines()),
|
||||
Err(why) => {
|
||||
tracing::error!("failed to spawn fdfind process: {}", why);
|
||||
|
||||
|
|
@ -176,19 +176,16 @@ impl SearchContext {
|
|||
'stream: loop {
|
||||
let interrupt = async {
|
||||
let _ = self.interrupt_rx.recv_async().await;
|
||||
None
|
||||
Ok(None)
|
||||
};
|
||||
|
||||
match crate::or(interrupt, stdout.next()).await {
|
||||
Some(result) => match result {
|
||||
Ok(line) => append = line,
|
||||
Err(why) => {
|
||||
tracing::error!("error on stdout line read: {}", why);
|
||||
break 'stream;
|
||||
}
|
||||
},
|
||||
|
||||
None => break 'stream,
|
||||
match crate::or(interrupt, stdout.next_line()).await {
|
||||
Ok(Some(line)) => append = line,
|
||||
Ok(None) => break 'stream,
|
||||
Err(why) => {
|
||||
tracing::error!("error on stdout line read: {}", why);
|
||||
break 'stream;
|
||||
}
|
||||
}
|
||||
|
||||
self.append(id, append).await;
|
||||
|
|
@ -201,7 +198,7 @@ impl SearchContext {
|
|||
}
|
||||
|
||||
let _ = child.kill();
|
||||
let _ = child.status().await;
|
||||
let _ = child.wait().await;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ pub mod scripts;
|
|||
pub mod terminal;
|
||||
pub mod web;
|
||||
|
||||
use futures::{AsyncWrite, AsyncWriteExt};
|
||||
use pop_launcher::PluginResponse;
|
||||
use std::{borrow::Cow, ffi::OsStr, future::Future, path::Path};
|
||||
use tokio::io::{AsyncWrite, AsyncWriteExt};
|
||||
|
||||
pub async fn send<W: AsyncWrite + Unpin>(tx: &mut W, response: PluginResponse) {
|
||||
if let Ok(mut bytes) = serde_json::to_string(&response) {
|
||||
|
|
@ -47,5 +47,5 @@ pub fn mime_from_path(path: &Path) -> Cow<'static, str> {
|
|||
|
||||
/// Launches a file with its default appplication via `xdg-open`.
|
||||
pub fn xdg_open<S: AsRef<OsStr>>(file: S) {
|
||||
let _ = smol::process::Command::new("xdg-open").arg(file).spawn();
|
||||
let _ = tokio::process::Command::new("xdg-open").arg(file).spawn();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,10 +3,11 @@
|
|||
|
||||
use crate::*;
|
||||
use freedesktop_desktop_entry as fde;
|
||||
use futures::{AsyncWrite, AsyncWriteExt, StreamExt};
|
||||
use futures::StreamExt;
|
||||
use pop_launcher::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{convert::TryFrom, fs, path::PathBuf, sync::Arc};
|
||||
use tokio::io::{AsyncWrite, AsyncWriteExt};
|
||||
use zbus::Connection;
|
||||
use zvariant::{Signature, Type};
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
use async_pidfd::AsyncPidFd;
|
||||
use futures::prelude::*;
|
||||
use pop_launcher::*;
|
||||
use smol::Unblock;
|
||||
use std::io;
|
||||
|
||||
struct Selection {
|
||||
|
|
@ -15,7 +14,7 @@ struct Selection {
|
|||
|
||||
pub struct App {
|
||||
selections: Vec<Selection>,
|
||||
out: Unblock<io::Stdout>,
|
||||
out: tokio::io::Stdout,
|
||||
}
|
||||
|
||||
impl Default for App {
|
||||
|
|
@ -77,7 +76,7 @@ impl App {
|
|||
let sinks = pactl_sinks();
|
||||
|
||||
while let Ok(id) = sinks.recv_async().await {
|
||||
handles.push(smol::spawn(async move {
|
||||
handles.push(tokio::spawn(async move {
|
||||
let args = &[arg1, id.as_str(), arg2];
|
||||
let _ = command_spawn(cmd, args).await;
|
||||
}));
|
||||
|
|
@ -136,25 +135,25 @@ async fn command_spawn(cmd: &str, args: &[&str]) -> io::Result<()> {
|
|||
fn pactl_sinks() -> flume::Receiver<String> {
|
||||
let (tx, rx) = flume::bounded(4);
|
||||
|
||||
smol::spawn(async move {
|
||||
let child = smol::process::Command::new("pactl")
|
||||
tokio::spawn(async move {
|
||||
let child = tokio::process::Command::new("pactl")
|
||||
.env("LANG", "C")
|
||||
.args(&["list", "sinks"])
|
||||
.stdout(smol::process::Stdio::piped())
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn();
|
||||
|
||||
if let Ok(mut child) = child {
|
||||
if let Some(stdout) = child.stdout.take() {
|
||||
let mut lines = futures::io::BufReader::new(stdout).lines();
|
||||
while let Some(Ok(line)) = lines.next().await {
|
||||
use tokio::io::AsyncBufReadExt;
|
||||
let mut lines = tokio::io::BufReader::new(stdout).lines();
|
||||
while let Ok(Some(line)) = lines.next_line().await {
|
||||
if let Some(stripped) = line.strip_prefix("Sink #") {
|
||||
let _ = tx.send_async(stripped.trim().to_owned()).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
});
|
||||
|
||||
rx
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,11 @@ use futures::prelude::*;
|
|||
use gtk::prelude::*;
|
||||
use pop_launcher::*;
|
||||
use slab::Slab;
|
||||
use smol::Unblock;
|
||||
use std::{borrow::Cow, io};
|
||||
use std::borrow::Cow;
|
||||
|
||||
pub struct App {
|
||||
manager: gtk::RecentManager,
|
||||
out: Unblock<io::Stdout>,
|
||||
out: tokio::io::Stdout,
|
||||
uris: Slab<String>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,13 +5,12 @@ use crate::*;
|
|||
use pop_launcher::*;
|
||||
|
||||
use flume::Sender;
|
||||
use futures::{AsyncBufReadExt, StreamExt};
|
||||
use smol::process::{Command, Stdio};
|
||||
use futures::StreamExt;
|
||||
use std::collections::VecDeque;
|
||||
use std::{
|
||||
io,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Stdio;
|
||||
use tokio::io::AsyncBufReadExt;
|
||||
use tokio::process::Command;
|
||||
|
||||
const LOCAL_PATH: &str = ".local/share/pop-launcher/scripts";
|
||||
const SYSTEM_ADMIN_PATH: &str = "/etc/pop-launcher/scripts";
|
||||
|
|
@ -42,7 +41,7 @@ pub async fn main() {
|
|||
|
||||
pub struct App {
|
||||
scripts: Vec<ScriptInfo>,
|
||||
out: smol::Unblock<io::Stdout>,
|
||||
out: tokio::io::Stdout,
|
||||
}
|
||||
|
||||
impl App {
|
||||
|
|
@ -156,9 +155,9 @@ async fn load_from(path: &Path, paths: &mut VecDeque<PathBuf>, tx: Sender<Script
|
|||
continue;
|
||||
}
|
||||
|
||||
smol::spawn(async move {
|
||||
let mut file = match smol::fs::File::open(&path).await {
|
||||
Ok(file) => futures::io::BufReader::new(file).lines(),
|
||||
tokio::spawn(async move {
|
||||
let mut file = match tokio::fs::File::open(&path).await {
|
||||
Ok(file) => tokio::io::BufReader::new(file).lines(),
|
||||
Err(why) => {
|
||||
tracing::error!("cannot open script at {}: {}", path.display(), why);
|
||||
return;
|
||||
|
|
@ -172,7 +171,7 @@ async fn load_from(path: &Path, paths: &mut VecDeque<PathBuf>, tx: Sender<Script
|
|||
|
||||
let mut first = true;
|
||||
|
||||
while let Some(Ok(line)) = file.next().await {
|
||||
while let Ok(Some(line)) = file.next_line().await {
|
||||
if !line.starts_with('#') {
|
||||
break;
|
||||
}
|
||||
|
|
@ -200,8 +199,7 @@ async fn load_from(path: &Path, paths: &mut VecDeque<PathBuf>, tx: Sender<Script
|
|||
}
|
||||
|
||||
let _ = tx.send_async(info).await;
|
||||
})
|
||||
.detach();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,12 +3,11 @@
|
|||
|
||||
use futures::prelude::*;
|
||||
use pop_launcher::*;
|
||||
use smol::Unblock;
|
||||
use std::{io, path::PathBuf};
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub struct App {
|
||||
last_query: Option<String>,
|
||||
out: Unblock<io::Stdout>,
|
||||
out: tokio::io::Stdout,
|
||||
shell_only: bool,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
// Copyright © 2021 System76
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::Duration;
|
||||
|
||||
|
|
@ -11,7 +10,6 @@ use futures::StreamExt;
|
|||
use isahc::config::{Configurable, RedirectPolicy};
|
||||
use isahc::http::header::CONTENT_TYPE;
|
||||
use isahc::{AsyncReadResponseExt, HttpClient};
|
||||
use smol::Unblock;
|
||||
use url::Url;
|
||||
|
||||
use pop_launcher::*;
|
||||
|
|
@ -42,7 +40,7 @@ pub async fn main() {
|
|||
pub struct App {
|
||||
config: Config,
|
||||
queries: Vec<String>,
|
||||
out: Unblock<io::Stdout>,
|
||||
out: tokio::io::Stdout,
|
||||
client: HttpClient,
|
||||
cache: PathBuf,
|
||||
}
|
||||
|
|
@ -145,7 +143,7 @@ impl App {
|
|||
|
||||
let favicon_path = favicon_path.to_path_buf();
|
||||
|
||||
smol::spawn(async move {
|
||||
tokio::spawn(async move {
|
||||
let favicon_url = favicon_url_from_page_source(&domain, &client)
|
||||
.await
|
||||
.unwrap_or_else(|| {
|
||||
|
|
@ -162,15 +160,14 @@ impl App {
|
|||
std::fs::create_dir_all(cache_dir).expect("error creating cache directory");
|
||||
}
|
||||
|
||||
let copy = smol::fs::write(&favicon_path, icon).await;
|
||||
let copy = tokio::fs::write(&favicon_path, icon).await;
|
||||
if let Err(err) = copy {
|
||||
tracing::error!("error writing favicon to {:?}: {}", &favicon_path, err);
|
||||
}
|
||||
}
|
||||
None => tracing::error!("no icon found for {}", domain),
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue