feat: add async support
This commit is contained in:
3
CHANGELOG.md
Normal file
3
CHANGELOG.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# v0.2.0
|
||||
|
||||
* Added async client support behind a non-default cargo feature flag using tokio's `AsyncRead` and `AsyncWrite`.
|
||||
18
Cargo.lock
generated
18
Cargo.lock
generated
@@ -273,13 +273,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pamsock"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"clap",
|
||||
"pam",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
@@ -367,6 +374,15 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.49.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86"
|
||||
dependencies = [
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.24"
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
[package]
|
||||
name = "pamsock"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
edition = "2024"
|
||||
|
||||
[features]
|
||||
async = ["dep:tokio"]
|
||||
|
||||
[dependencies]
|
||||
anstyle = "1.0.13"
|
||||
clap = { version = "4.5.60", features = ["derive"] }
|
||||
pam = "0.8.0"
|
||||
|
||||
tokio = { version = "1.49.0", optional = true }
|
||||
|
||||
[lints.clippy]
|
||||
pedantic = { level = "deny", priority = -1 }
|
||||
nursery = { level = "deny", priority = -1 }
|
||||
|
||||
62
src/lib.rs
62
src/lib.rs
@@ -80,6 +80,19 @@ pub mod prot {
|
||||
ServerResponse::from_u8(ucom::read_u8(&mut stream)?)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[cfg(feature = "async")]
|
||||
pub async fn attempt_login_async(
|
||||
mut stream: impl tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin,
|
||||
user: &str,
|
||||
passwd: &str,
|
||||
) -> Option<ServerResponse> {
|
||||
ucom_async::write_str(&mut stream, user).await?;
|
||||
ucom_async::write_str(&mut stream, passwd).await?;
|
||||
|
||||
ServerResponse::from_u8(ucom_async::read_u8(&mut stream).await?)
|
||||
}
|
||||
|
||||
pub mod ucom {
|
||||
//! # µcom
|
||||
//!
|
||||
@@ -123,4 +136,53 @@ pub mod prot {
|
||||
into.write_all(&size_buf).ok()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
pub mod ucom_async {
|
||||
//! # µcom_async
|
||||
//!
|
||||
//! Analogous to [`super::ucom`] but asynchronous.
|
||||
|
||||
use tokio::io::{AsyncRead, AsyncWrite, AsyncReadExt, AsyncWriteExt};
|
||||
|
||||
pub async fn read_duple(from: &mut (impl AsyncRead + Unpin)) -> Option<(String, String)> {
|
||||
let user = read_str(from).await?;
|
||||
let pass = read_str(from).await?;
|
||||
Some((user, pass))
|
||||
}
|
||||
|
||||
pub async fn read_str(from: &mut (impl AsyncRead + Unpin)) -> Option<String> {
|
||||
let size = read_u8(from).await? as usize;
|
||||
let mut buf = vec![0; size];
|
||||
from.read_exact(&mut buf).await.ok()?;
|
||||
String::from_utf8(buf).ok()
|
||||
}
|
||||
|
||||
pub async fn read_u8(from: &mut (impl AsyncRead + Unpin)) -> Option<u8> {
|
||||
let mut size_buf = [0; 1];
|
||||
from.read_exact(&mut size_buf).await.ok()?;
|
||||
Some(u8::from_be_bytes(size_buf))
|
||||
}
|
||||
|
||||
pub async fn write_duple(
|
||||
into: &mut (impl AsyncWrite + Unpin),
|
||||
user: &str,
|
||||
pass: &str,
|
||||
) -> Option<()> {
|
||||
write_str(into, user).await?;
|
||||
write_str(into, pass).await?;
|
||||
Some(())
|
||||
}
|
||||
|
||||
pub async fn write_str(into: &mut (impl AsyncWrite + Unpin), str: &str) -> Option<()> {
|
||||
let buf = str.as_bytes();
|
||||
write_u8(into, buf.len().try_into().ok()?).await?;
|
||||
into.write_all(buf).await.ok()
|
||||
}
|
||||
|
||||
pub async fn write_u8(into: &mut (impl AsyncWrite + Unpin), u8: u8) -> Option<()> {
|
||||
let size_buf = u8.to_be_bytes();
|
||||
into.write_all(&size_buf).await.ok()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user