use std::{
future::Future,
ops::{Deref, DerefMut},
};
use async_scoped::{Scope, TokioScope};
#[derive(Default)]
pub struct FuturesResults<T> {
inner: Vec<T>,
}
impl<T> FuturesResults<T> {
pub fn into_inner(self) -> Vec<T> {
self.inner
}
}
impl<'f, Fut> FromIterator<Fut> for FuturesResults<Fut::Output>
where
Fut: Future + Send + 'f,
Fut::Output: Send + 'static,
{
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = Fut>,
{
let (_, inner) = Scope::scope_and_block(|s: &mut TokioScope<'_, _>| {
iter.into_iter().for_each(|fut| {
s.spawn(fut);
});
});
Self {
inner: inner
.into_iter()
.map(|i| match i {
Ok(i) => i,
Err(err) => {
if err.is_panic() {
std::panic::resume_unwind(err.into_panic())
} else {
unreachable!("Error should be a panic {err}")
}
}
})
.collect(),
}
}
}
impl<T> Deref for FuturesResults<T> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T> DerefMut for FuturesResults<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}