use crate::*;
use std::fmt::Debug;
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum ResultError
{
Taken,
TaskFailure,
}
#[derive(Debug)]
pub struct PendingResult<R>
{
result_receiver: Option<Box<dyn ResultReceiver<Result = R> + Send + Sync>>,
}
impl<R: Debug + Send + Sync + 'static> PendingResult<R>
{
pub fn new(receiver: impl ResultReceiver<Result = R> + Send + Sync + 'static) -> Self
{
Self{ result_receiver: Some(Box::new(receiver)) }
}
pub fn make_ready(result: R) -> Self
{
Self{ result_receiver: Some(Box::new(ImmedateResultReceiver::new(result))) }
}
pub fn has_result(&self) -> bool
{
match &self.result_receiver
{
Some(receiver) => receiver.done(),
None => false
}
}
pub fn done(&self) -> bool
{
if self.has_result() || self.result_receiver.is_none() { return true; }
false
}
pub fn try_extract(&mut self) -> Option<Result<R, ResultError>>
{
if !self.has_result() && self.result_receiver.is_some() { return None; }
match &mut self.result_receiver
{
Some(receiver) => receiver.try_get(),
None => Some(Err(ResultError::Taken)),
}
}
pub async fn extract(&mut self) -> Result<R, ResultError>
{
let Some(receiver) = self.result_receiver.take() else { return Err(ResultError::Taken); };
receiver.get().await
}
}
#[cfg(not(target_family = "wasm"))]
pub mod blocking
{
pub fn extract<R>(mut pending_result: super::PendingResult<R>) -> Result<R, super::ResultError>
where
R: Send + Sync + std::fmt::Debug + 'static
{
futures::executor::block_on(async move { pending_result.extract().await })
}
}