pict-rs/src/bytes_stream.rs

79 lines
1.9 KiB
Rust
Raw Normal View History

2024-02-22 22:15:32 +00:00
use actix_web::web::Bytes;
2023-08-23 16:59:42 +00:00
use futures_core::Stream;
2024-03-10 04:53:46 +00:00
use std::collections::{vec_deque::IntoIter, VecDeque};
2024-02-22 22:02:33 +00:00
use streem::IntoStreamer;
#[derive(Clone, Debug)]
pub(crate) struct BytesStream {
inner: VecDeque<Bytes>,
total_len: usize,
}
impl BytesStream {
pub(crate) fn new() -> Self {
Self {
inner: VecDeque::new(),
total_len: 0,
}
}
2024-02-22 22:10:34 +00:00
#[tracing::instrument(skip(stream))]
2024-02-22 22:02:33 +00:00
pub(crate) async fn try_from_stream<S, E>(stream: S) -> Result<Self, E>
where
S: Stream<Item = Result<Bytes, E>>,
{
let stream = std::pin::pin!(stream);
let mut stream = stream.into_streamer();
let mut bs = Self::new();
while let Some(bytes) = stream.try_next().await? {
2024-02-22 22:10:34 +00:00
tracing::trace!("try_from_stream: looping");
2024-02-22 22:02:33 +00:00
bs.add_bytes(bytes);
2024-03-10 04:53:46 +00:00
crate::sync::cooperate().await;
2024-02-22 22:02:33 +00:00
}
tracing::debug!(
"BytesStream with {} chunks, avg length {}",
bs.chunks_len(),
bs.len() / bs.chunks_len().max(1)
);
2024-02-22 22:02:33 +00:00
Ok(bs)
}
pub(crate) fn chunks_len(&self) -> usize {
self.inner.len()
}
pub(crate) fn add_bytes(&mut self, bytes: Bytes) {
self.total_len += bytes.len();
self.inner.push_back(bytes);
}
pub(crate) fn len(&self) -> usize {
self.total_len
}
2024-02-22 22:02:33 +00:00
pub(crate) fn is_empty(&self) -> bool {
2024-02-22 23:09:03 +00:00
self.total_len == 0
2024-02-22 22:02:33 +00:00
}
2024-03-10 04:53:46 +00:00
pub(crate) fn into_io_stream(self) -> impl Stream<Item = std::io::Result<Bytes>> {
crate::stream::error_injector(streem::from_fn(move |yielder| async move {
2024-03-10 04:53:46 +00:00
for bytes in self {
crate::sync::cooperate().await;
yielder.yield_ok(bytes).await;
}
}))
2024-02-22 22:02:33 +00:00
}
}
impl IntoIterator for BytesStream {
type Item = Bytes;
type IntoIter = IntoIter<Bytes>;
fn into_iter(self) -> Self::IntoIter {
self.inner.into_iter()
}
}