From 3de343ede2a1e200f416812616821a6c1925fc17 Mon Sep 17 00:00:00 2001 From: panicbit Date: Tue, 20 Aug 2024 01:00:33 +0200 Subject: [PATCH] asyncify read/write package --- rust-toolchain.toml | 2 ++ src/lib.rs | 11 +++++++---- src/protocol.rs | 32 +++++++++++++++++--------------- 3 files changed, 26 insertions(+), 19 deletions(-) create mode 100644 rust-toolchain.toml diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..5566676 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly-2024-08-19" diff --git a/src/lib.rs b/src/lib.rs index 4336813..d57d961 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,15 +1,17 @@ +#![feature(async_closure)] + pub mod cli; pub mod config; pub mod output; pub mod protocol; -use tokio::io::{AsyncWriteExt}; -use std::net::{ToSocketAddrs}; +use std::net::ToSocketAddrs; +use tokio::io::AsyncWriteExt; use anyhow::{Context, Result}; -use tokio::net::TcpStream; pub use cli::Cli; pub use config::Config; +use tokio::net::TcpStream; use protocol::StatusResponse; @@ -17,7 +19,8 @@ const APP_NAME: &str = "mc_status"; pub async fn get_server_status(host: &str, port: u16) -> Result { let addr = &(host, port).to_socket_addrs()?.next().unwrap(); - let stream= &mut TcpStream::connect(addr).await + let stream = &mut TcpStream::connect(addr) + .await .context("failed to connect")?; let protocol_version = -1; diff --git a/src/protocol.rs b/src/protocol.rs index 96e5940..a0a3850 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -1,8 +1,7 @@ -use std::future::Future; -use std::io::{Cursor}; +use std::io::Cursor; use anyhow::{ensure, Result}; -use tokio::io::{AsyncRead, AsyncWrite, AsyncReadExt, AsyncWriteExt}; +use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; pub mod status_response; pub mod varint; @@ -16,35 +15,36 @@ pub async fn write_handshake( port: u16, next_state: i32, ) -> Result<()> { - write_packet(w, 0x00, move |w|async move{ + write_packet(w, 0x00, async |w| { varint::write(w, protocol_version).await?; write_string(w, host).await?; write_unsigned_short(w, port).await?; varint::write(w, next_state).await?; Ok(()) - }).await + }) + .await } pub async fn write_status_request(w: &mut W) -> Result<()> { - write_packet(w, 0x00, |_|async {Ok(())}).await + write_packet(w, 0x00, async |_| Ok(())).await } pub async fn read_status_response(r: &mut R) -> Result { - read_packet(r, move|id, r|async move { + read_packet(r, async |id, r| { ensure!(id == 0x00); let status_response = read_string(r).await?; let status_response = serde_json::from_str::(&status_response)?; Ok(status_response) - }).await + }) + .await } -pub async fn write_packet<'a, W, F, Fut>(w: &'a mut W, id: i32, f: F) -> Result<()> +pub async fn write_packet(w: &mut W, id: i32, f: F) -> Result<()> where W: AsyncWrite + Unpin, - F: FnOnce(&'a mut (dyn AsyncWrite + Unpin)) -> Fut, - Fut: Future> + 'a, + F: async FnOnce(&mut Vec) -> Result<()>, { let buf = &mut Vec::new(); @@ -57,11 +57,10 @@ where Ok(()) } -pub async fn read_packet(r: &mut R, f: F) -> Result +pub async fn read_packet(r: &mut R, f: F) -> Result where R: AsyncRead + Unpin, - F: FnOnce(i32, &mut (dyn AsyncRead + Unpin)) -> Fut, - Fut: Future>, + F: async FnOnce(i32, &mut (dyn AsyncRead + Unpin)) -> Result, { let len = varint::read(r).await? as usize; let mut data = vec![0; len]; @@ -74,7 +73,10 @@ where Ok(value) } -pub async fn write_unsigned_short(w: &mut W, value: u16) -> Result<()> { +pub async fn write_unsigned_short( + w: &mut W, + value: u16, +) -> Result<()> { w.write_all(&value.to_be_bytes()).await?; Ok(()) }