use std::convert::Infallible;
use either::Either;
use super::DisabledTask;
use crate::{
cancellation_token::CancellationToken,
error::FetcherError,
maybe_send::{MaybeSend, MaybeSendSync},
};
pub trait OpaqueTask: MaybeSendSync {
fn run(&mut self) -> impl Future<Output = Result<(), FetcherError>> + MaybeSend;
fn set_cancel_token(&mut self, token: CancellationToken);
fn disable(self) -> DisabledTask<Self>
where
Self: Sized,
{
DisabledTask(self)
}
}
impl OpaqueTask for () {
async fn run(&mut self) -> Result<(), FetcherError> {
Ok(())
}
fn set_cancel_token(&mut self, _channel: CancellationToken) {}
}
impl OpaqueTask for Infallible {
async fn run(&mut self) -> Result<(), FetcherError> {
match *self {}
}
fn set_cancel_token(&mut self, _channel: CancellationToken) {
match *self {}
}
}
#[cfg(feature = "nightly")]
impl OpaqueTask for ! {
async fn run(&mut self) -> Result<(), FetcherError> {
match *self {}
}
fn set_cancel_token(&mut self, _channel: CancellationToken) {
match *self {}
}
}
impl<T> OpaqueTask for Option<T>
where
T: OpaqueTask,
{
async fn run(&mut self) -> Result<(), FetcherError> {
let Some(task) = self else {
return Ok(());
};
task.run().await
}
fn set_cancel_token(&mut self, channel: CancellationToken) {
let Some(task) = self else {
return;
};
task.set_cancel_token(channel);
}
}
impl<T> OpaqueTask for &mut T
where
T: OpaqueTask,
{
fn run(&mut self) -> impl Future<Output = Result<(), FetcherError>> + MaybeSend {
(*self).run()
}
fn set_cancel_token(&mut self, channel: CancellationToken) {
(*self).set_cancel_token(channel);
}
}
impl<A, B> OpaqueTask for Either<A, B>
where
A: OpaqueTask,
B: OpaqueTask,
{
async fn run(&mut self) -> Result<(), FetcherError> {
match self {
Either::Left(a) => a.run().await,
Either::Right(b) => b.run().await,
}
}
fn set_cancel_token(&mut self, token: CancellationToken) {
match self {
Either::Left(a) => a.set_cancel_token(token),
Either::Right(b) => b.set_cancel_token(token),
}
}
}