use a stream of futures for running the runloop
This commit is contained in:
parent
a543c177b2
commit
63403faf4d
3 changed files with 82 additions and 16 deletions
53
Cargo.lock
generated
53
Cargo.lock
generated
|
@ -302,6 +302,7 @@ checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"crossterm_winapi",
|
"crossterm_winapi",
|
||||||
|
"futures-core",
|
||||||
"mio",
|
"mio",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"rustix 0.38.44",
|
"rustix 0.38.44",
|
||||||
|
@ -519,6 +520,21 @@ version = "0.2.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d8866fac38f53fc87fa3ae1b09ddd723e0482f8fa74323518b4c59df2c55a00a"
|
checksum = "d8866fac38f53fc87fa3ae1b09ddd723e0482f8fa74323518b4c59df2c55a00a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures"
|
||||||
|
version = "0.3.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
|
||||||
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-executor",
|
||||||
|
"futures-io",
|
||||||
|
"futures-sink",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-channel"
|
name = "futures-channel"
|
||||||
version = "0.3.31"
|
version = "0.3.31"
|
||||||
|
@ -526,6 +542,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
|
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -534,6 +551,34 @@ version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-executor"
|
||||||
|
version = "0.3.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-io"
|
||||||
|
version = "0.3.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-macro"
|
||||||
|
version = "0.3.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.104",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-sink"
|
name = "futures-sink"
|
||||||
version = "0.3.31"
|
version = "0.3.31"
|
||||||
|
@ -552,10 +597,16 @@ version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-io",
|
||||||
|
"futures-macro",
|
||||||
|
"futures-sink",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
|
"memchr",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"pin-utils",
|
"pin-utils",
|
||||||
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -993,7 +1044,9 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"axum",
|
"axum",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"crossterm",
|
||||||
"figment",
|
"figment",
|
||||||
|
"futures",
|
||||||
"julid-rs",
|
"julid-rs",
|
||||||
"local-ip-address",
|
"local-ip-address",
|
||||||
"mime",
|
"mime",
|
||||||
|
|
|
@ -6,7 +6,9 @@ edition = "2024"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum = { version = "0.8", features = ["macros"] }
|
axum = { version = "0.8", features = ["macros"] }
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
|
crossterm = { version = "0.28", features = ["event-stream"] }
|
||||||
figment = { version = "0.10", features = ["toml", "test", "env"] }
|
figment = { version = "0.10", features = ["toml", "test", "env"] }
|
||||||
|
futures = "0.3.31"
|
||||||
julid-rs = { version = "1", default-features = false, features = ["serde"] }
|
julid-rs = { version = "1", default-features = false, features = ["serde"] }
|
||||||
local-ip-address = "0.6"
|
local-ip-address = "0.6"
|
||||||
mime = "0.3"
|
mime = "0.3"
|
||||||
|
|
43
src/main.rs
43
src/main.rs
|
@ -1,13 +1,14 @@
|
||||||
#![feature(slice_as_array)]
|
#![feature(slice_as_array)]
|
||||||
use std::{collections::BTreeMap, io, net::SocketAddr};
|
use std::{collections::BTreeMap, io, net::SocketAddr};
|
||||||
|
|
||||||
|
use futures::{FutureExt, StreamExt};
|
||||||
use joecalsend::{Config, JoecalState, error, models::Device};
|
use joecalsend::{Config, JoecalState, error, models::Device};
|
||||||
use local_ip_address::local_ip;
|
use local_ip_address::local_ip;
|
||||||
use network_interface::{Addr, NetworkInterface, NetworkInterfaceConfig, V4IfAddr};
|
use network_interface::{Addr, NetworkInterface, NetworkInterfaceConfig, V4IfAddr};
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
DefaultTerminal,
|
DefaultTerminal,
|
||||||
buffer::Buffer,
|
buffer::Buffer,
|
||||||
crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind},
|
crossterm::event::{Event, EventStream, KeyCode, KeyEvent, KeyEventKind},
|
||||||
layout::Rect,
|
layout::Rect,
|
||||||
style::Stylize,
|
style::Stylize,
|
||||||
symbols::border,
|
symbols::border,
|
||||||
|
@ -71,6 +72,7 @@ pub struct App {
|
||||||
screen: CurrentScreen,
|
screen: CurrentScreen,
|
||||||
// addr -> (alias, fingerprint)
|
// addr -> (alias, fingerprint)
|
||||||
peers: Peers,
|
peers: Peers,
|
||||||
|
events: EventStream,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
@ -87,6 +89,7 @@ impl App {
|
||||||
state,
|
state,
|
||||||
screen: CurrentScreen::Main,
|
screen: CurrentScreen::Main,
|
||||||
peers: Default::default(),
|
peers: Default::default(),
|
||||||
|
events: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,6 +99,7 @@ impl App {
|
||||||
self.handle_events().await?;
|
self.handle_events().await?;
|
||||||
|
|
||||||
if self.screen == CurrentScreen::Stopping {
|
if self.screen == CurrentScreen::Stopping {
|
||||||
|
self.state.stop().await;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,37 +117,44 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_events(&mut self) -> io::Result<()> {
|
async fn handle_events(&mut self) -> io::Result<()> {
|
||||||
match event::read()? {
|
tokio::select! {
|
||||||
// it's important to check that the event is a key press event as
|
event = self.events.next().fuse() => {
|
||||||
// crossterm also emits key release and repeat events on Windows.
|
if let Some(Ok(evt)) = event {
|
||||||
Event::Key(key_event) if key_event.kind == KeyEventKind::Press => {
|
match evt {
|
||||||
self.handle_key_event(key_event).await
|
Event::Key(key)
|
||||||
|
if key.kind == KeyEventKind::Press
|
||||||
|
=> self.handle_key_event(key),
|
||||||
|
Event::Mouse(_) => {}
|
||||||
|
Event::Resize(_, _) => {}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ = tokio::time::sleep(tokio::time::Duration::from_millis(100)) => {}
|
||||||
};
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_key_event(&mut self, key_event: KeyEvent) {
|
fn handle_key_event(&mut self, key_event: KeyEvent) {
|
||||||
match key_event.code {
|
match key_event.code {
|
||||||
KeyCode::Char('q') => self.exit().await,
|
KeyCode::Char('q') => self.exit(),
|
||||||
KeyCode::Char('s') => self.send().await,
|
KeyCode::Char('s') => self.send(),
|
||||||
KeyCode::Char('r') => self.recv().await,
|
KeyCode::Char('r') => self.recv(),
|
||||||
KeyCode::Char('d') => {}
|
KeyCode::Char('d') => {}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn exit(&mut self) {
|
fn exit(&mut self) {
|
||||||
self.state.stop().await;
|
|
||||||
self.screen = CurrentScreen::Stopping;
|
self.screen = CurrentScreen::Stopping;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send(&mut self) {
|
fn send(&mut self) {
|
||||||
self.screen = CurrentScreen::Sending;
|
self.screen = CurrentScreen::Sending;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn recv(&mut self) {
|
fn recv(&mut self) {
|
||||||
self.screen = CurrentScreen::Receiving;
|
self.screen = CurrentScreen::Receiving;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue