//! Extended external extensions to futures::FutureExt use std::marker::Unpin; use futures::{ Future, FutureExt, future::{ Either::{Left, Right}, select_ok, try_join, try_join_all, try_join3, try_join4, }, }; use crate::utils::BoolExt as _; pub trait BoolExt where Self: Future + Send, { type Result; fn or(self, b: B) -> impl Future + Send where B: Future + Send + Unpin, Self: Sized + Unpin; fn and(self, b: B) -> impl Future + Send where B: Future + Send, Self: Sized; fn and2(self, b: B, c: C) -> impl Future + Send where B: Future + Send, C: Future + Send, Self: Sized; fn and3(self, b: B, c: C, d: D) -> impl Future + Send where B: Future + Send, C: Future + Send, D: Future + Send, Self: Sized; } impl BoolExt for Fut where Fut: Future + Send, { type Result = crate::Result<(), ()>; fn or(self, b: B) -> impl Future + Send where B: Future + Send + Unpin, Self: Sized + Unpin, { let test = |test: bool| test.ok_or(Self::Result::Err(())); select_ok([Left(self.map(test)), Right(b.map(test))]).map(|res| res.is_ok()) } fn and(self, b: B) -> impl Future + Send where B: Future + Send, Self: Sized, { let test = |test: bool| test.ok_or(Self::Result::Err(())); try_join(self.map(test), b.map(test)).map(|res| res.is_ok()) } fn and2(self, b: B, c: C) -> impl Future + Send where B: Future + Send, C: Future + Send, Self: Sized, { let test = |test: bool| test.ok_or(Self::Result::Err(())); try_join3(self.map(test), b.map(test), c.map(test)).map(|res| res.is_ok()) } fn and3(self, b: B, c: C, d: D) -> impl Future + Send where B: Future + Send, C: Future + Send, D: Future + Send, Self: Sized, { let test = |test: bool| test.ok_or(Self::Result::Err(())); try_join4(self.map(test), b.map(test), c.map(test), d.map(test)).map(|res| res.is_ok()) } } pub 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.ok_or(Result::Err(())))); try_join_all(args).map(|res| res.is_ok()) } pub 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.ok_or(Result::Err(())))); select_ok(args).map(|res| res.is_ok()) }