//! Extended external extensions to futures::FutureExt use std::marker::Unpin; use futures::{ Future, FutureExt, future::{select_ok, try_join, try_join_all, try_select}, }; pub trait BoolExt where Self: Future + Send, { fn and(self, b: B) -> impl Future + Send where B: Future + Send, Self: Sized; fn or(self, b: B) -> impl Future + Send where B: Future + Send + Unpin, Self: Sized + Unpin; } impl BoolExt for Fut where Fut: Future + Send, { #[inline] fn and(self, b: B) -> impl Future + Send where B: Future + Send, Self: Sized, { type Result = crate::Result<(), ()>; let a = self.map(|a| a.then_some(()).ok_or(Result::Err(()))); let b = b.map(|b| b.then_some(()).ok_or(Result::Err(()))); try_join(a, b).map(|result| result.is_ok()) } #[inline] fn or(self, b: B) -> impl Future + Send where B: Future + Send + Unpin, Self: Sized + Unpin, { type Result = crate::Result<(), ()>; let a = self.map(|a| a.then_some(()).ok_or(Result::Err(()))); let b = b.map(|b| b.then_some(()).ok_or(Result::Err(()))); try_select(a, b).map(|result| result.is_ok()) } } pub async fn and(args: I) -> impl Future + Send where I: Iterator + Send, F: Future + Send, { type Result = crate::Result<(), ()>; let args = args.map(|a| a.map(|a| a.then_some(()).ok_or(Result::Err(())))); try_join_all(args).map(|result| result.is_ok()) } pub async fn or(args: I) -> impl Future + Send where I: Iterator + Send, F: Future + Send + Unpin, { type Result = crate::Result<(), ()>; let args = args.map(|a| a.map(|a| a.then_some(()).ok_or(Result::Err(())))); select_ok(args).map(|result| result.is_ok()) }