use async_stream::stream;
use futures::stream::Stream;
pub use futures::{pin_mut, StreamExt};
use super::Index;
#[async_trait::async_trait]
pub trait StorageVecBase<T: Send> {
async fn is_empty(&self) -> bool;
async fn len(&self) -> Index;
async fn get(&self, index: Index) -> T;
async fn get_many(&self, indices: &[Index]) -> Vec<T>;
#[inline]
async fn get_all(&self) -> Vec<T> {
let all_indices = (0..self.len().await).collect::<Vec<_>>();
self.get_many(&all_indices).await
}
async fn set(&mut self, index: Index, value: T);
async fn set_many(&mut self, key_vals: impl IntoIterator<Item = (Index, T)> + Send);
#[inline]
async fn set_first_n(&mut self, vals: impl IntoIterator<Item = T> + Send) {
self.set_many((0..).zip(vals).collect::<Vec<_>>()).await;
}
#[inline]
async fn set_all(
&mut self,
vals: impl IntoIterator<IntoIter = impl ExactSizeIterator<Item = T> + Send> + Send,
) {
let iter = vals.into_iter();
assert!(
iter.len() as Index == self.len().await,
"size-mismatch. input has {} elements and target has {} elements.",
iter.len(),
self.len().await,
);
self.set_first_n(iter).await;
}
async fn pop(&mut self) -> Option<T>;
async fn push(&mut self, value: T);
async fn clear(&mut self);
}
#[expect(async_fn_in_trait)]
pub trait StorageVecStream<T: Send>: StorageVecBase<T> {
#[inline]
async fn stream<'a>(&'a self) -> impl Stream<Item = (Index, T)> + 'a
where
T: 'a,
{
self.stream_many(0..self.len().await)
}
#[inline]
async fn stream_values<'a>(&'a self) -> impl Stream<Item = T> + 'a
where
T: 'a,
{
self.stream_many_values(0..self.len().await)
}
fn stream_many<'a>(
&'a self,
indices: impl IntoIterator<Item = Index> + 'a,
) -> impl Stream<Item = (Index, T)> + 'a
where
T: 'a,
{
stream! {
for i in indices {
yield (i, self.get(i).await)
}
}
}
fn stream_many_values<'a>(
&'a self,
indices: impl IntoIterator<Item = Index> + 'a,
) -> impl Stream<Item = T> + 'a
where
T: 'a,
{
stream! {
for i in indices {
yield self.get(i).await
}
}
}
}
pub trait StorageVec<T: Send>: StorageVecBase<T> + StorageVecStream<T> {}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
pub(in super::super) mod tests {
use super::*;
pub mod streams {
use futures::pin_mut;
use futures::StreamExt;
use super::*;
pub async fn prepare_streams_test_vec(vec: &mut impl StorageVecBase<u64>) {
vec.clear().await;
for i in 0..4 {
vec.push(i * 10).await;
}
}
pub async fn stream(mut vec: impl StorageVecStream<u64>) {
prepare_streams_test_vec(&mut vec).await;
{
let mut vals = vec![];
let stream = vec.stream().await;
pin_mut!(stream); while let Some(value) = stream.next().await {
vals.push(value);
}
assert_eq!(vals, vec![(0, 0), (1, 10), (2, 20), (3, 30)]);
}
vec.clear().await;
{
let mut vals = vec![];
let stream = vec.stream().await;
pin_mut!(stream); while let Some(value) = stream.next().await {
vals.push(value);
}
assert_eq!(vals, vec![]);
}
}
pub async fn stream_many(mut vec: impl StorageVecStream<u64>) {
prepare_streams_test_vec(&mut vec).await;
{
let mut vals = vec![];
let stream = vec.stream_many([0, 1, 2, 3]);
pin_mut!(stream); while let Some(value) = stream.next().await {
vals.push(value);
}
assert_eq!(vals, vec![(0, 0), (1, 10), (2, 20), (3, 30)]);
}
{
let mut vals = vec![];
let stream = vec.stream_many([1, 2]);
pin_mut!(stream); while let Some(value) = stream.next().await {
vals.push(value);
}
assert_eq!(vals, vec![(1, 10), (2, 20)]);
}
}
}
}