use thiserror::Error;
use crate::bridge::EffectId;
type ResolveOnce<Out> = Box<dyn FnOnce(Out) + Send>;
type ResolveMany<Out> = Box<dyn Fn(Out) -> Result<(), ()> + Send>;
pub enum RequestHandle<Out> {
Never,
Once(ResolveOnce<Out>),
Many(ResolveMany<Out>),
}
pub trait Resolvable<Output> {
fn resolve(&mut self, output: Output) -> Result<(), ResolveError>;
}
impl<Output> Resolvable<Output> for RequestHandle<Output> {
fn resolve(&mut self, output: Output) -> Result<(), ResolveError> {
self.resolve(output)
}
}
impl<Output> RequestHandle<Output> {
pub fn resolve(&mut self, output: Output) -> Result<(), ResolveError> {
match self {
RequestHandle::Never => Err(ResolveError::Never),
RequestHandle::Many(f) => f(output).map_err(|()| ResolveError::FinishedMany),
RequestHandle::Once(_) => {
if let RequestHandle::Once(f) = std::mem::replace(self, RequestHandle::Never) {
f(output);
}
Ok(())
}
}
}
}
#[derive(Error, Debug)]
pub enum ResolveError {
#[error("Attempted to resolve a request that is not expected to be resolved.")]
Never,
#[error("Attempted to resolve a request that has concluded.")]
FinishedMany,
#[error("Request with {0:?} not found.")]
NotFound(EffectId), }