Phased out async-stream in pursuit of compile performance

This commit is contained in:
2025-09-04 15:01:53 +02:00
parent 088cb6a247
commit e339350505
26 changed files with 359 additions and 342 deletions

View File

@@ -6,8 +6,8 @@ edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
async-stream = "0.3.6"
futures = { version = "0.3.31", features = ["std"] }
async-fn-stream = { version = "0.1.0", path = "../async-fn-stream" }
futures = { version = "0.3.31", features = ["std"], default-features = false }
itertools = "0.14.0"
never = "0.1.0"
ordered-float = "5.0.0"

View File

@@ -7,7 +7,7 @@ use std::pin::Pin;
use std::rc::Rc;
use std::sync::Arc;
use async_stream::stream;
use async_fn_stream::stream;
use futures::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, StreamExt};
use never::Never;
use ordered_float::NotNan;
@@ -133,7 +133,13 @@ impl Encode for str {
impl<T: Decode> Decode for Vec<T> {
async fn decode<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>) -> Self {
let len = u64::decode(read.as_mut()).await.try_into().unwrap();
stream! { loop { yield T::decode(read.as_mut()).await } }.take(len).collect().await
stream(async |mut cx| {
for _ in 0..len {
cx.emit(T::decode(read.as_mut()).await).await
}
})
.collect()
.await
}
}
impl<T: Encode> Encode for Vec<T> {
@@ -186,7 +192,13 @@ impl<T: Encode, E: Encode> Encode for Result<T, E> {
impl<K: Decode + Eq + Hash, V: Decode> Decode for HashMap<K, V> {
async fn decode<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>) -> Self {
let len = u64::decode(read.as_mut()).await.try_into().unwrap();
stream! { loop { yield <(K, V)>::decode(read.as_mut()).await } }.take(len).collect().await
stream(async |mut cx| {
for _ in 0..len {
cx.emit(<(K, V)>::decode(read.as_mut()).await).await
}
})
.collect()
.await
}
}
impl<K: Encode + Eq + Hash, V: Encode> Encode for HashMap<K, V> {
@@ -259,8 +271,13 @@ impl Encode for bool {
impl<T: Decode, const N: usize> Decode for [T; N] {
async fn decode<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>) -> Self {
// TODO: figure out how to do this in safe rust on the stack
let v =
stream! { loop { yield T::decode(read.as_mut()).await } }.take(N).collect::<Vec<_>>().await;
let v = stream(async |mut cx| {
for _ in 0..N {
cx.emit(T::decode(read.as_mut()).await).await
}
})
.collect::<Vec<_>>()
.await;
v.try_into().unwrap_or_else(|_| unreachable!("The length of this stream is statically known"))
}
}