use std::{future::Future, pin::Pin};
use async_trait::async_trait;
pub trait Discard {
fn discard(self);
}
impl<T, E> Discard for Result<T, E> {
fn discard(self) {
let _ = self;
drop(self);
}
}
impl<T> Discard for Option<T> {
fn discard(self) {
let _ = self;
drop(self);
}
}
#[async_trait]
pub trait AsyncMap<T, U, F>
where
F: FnOnce(T) -> Pin<Box<dyn Future<Output = U> + Send>> + Send,
{
type Output;
async fn async_map(self, map: F) -> Self::Output;
}
#[async_trait]
impl<T, U, F> AsyncMap<T, U, F> for Option<T>
where
T: Send,
U: Send,
F: 'static + FnOnce(T) -> Pin<Box<dyn Future<Output = U> + Send>> + Send,
{
type Output = Option<U>;
async fn async_map(self, map: F) -> Self::Output {
match self {
Some(t) => {
let u = map(t).await;
Some(u)
}
None => None,
}
}
}
#[async_trait]
impl<T, E, U, F> AsyncMap<T, U, F> for Result<T, E>
where
T: Send,
U: Send,
E: Send,
F: 'static + FnOnce(T) -> Pin<Box<dyn Future<Output = U> + Send>> + Send,
{
type Output = Result<U, E>;
async fn async_map(self, map: F) -> Self::Output {
match self {
Ok(t) => {
let u = map(t).await;
Ok(u)
}
Err(e) => Err(e),
}
}
}