use std::any::Any;
use std::future::Future;
use std::marker::PhantomData;
use std::pin::Pin;
use std::sync::Arc;
use crate::error::DagError;
use crate::task::{Task, TaskInput};
type ExecuteFuture =
Pin<Box<dyn Future<Output = Result<Arc<dyn Any + Send + Sync>, DagError>> + Send>>;
pub(crate) trait ExecutableNode: Send {
fn execute_with_deps(
self: Box<Self>,
dependencies: Vec<Arc<dyn Any + Send + Sync>>,
) -> ExecuteFuture;
}
pub(crate) struct TypedNode<Input, T>
where
Input: Send + Sync + 'static,
T: Task<Input> + 'static,
{
pub(crate) task: T,
phantom: PhantomData<Input>,
}
impl<Input, T> TypedNode<Input, T>
where
T: Task<Input>,
Input: Send + Sync + 'static,
{
pub(crate) fn new(task: T) -> Self {
Self {
task,
phantom: PhantomData,
}
}
}
impl<Input, T> ExecutableNode for TypedNode<Input, T>
where
T: Task<Input>,
Input: Send + Sync + 'static,
{
fn execute_with_deps(
self: Box<Self>,
dependencies: Vec<Arc<dyn Any + Send + Sync>>,
) -> ExecuteFuture {
Box::pin(async move {
let output = self.task.run(TaskInput::new(dependencies.iter())).await;
let arc_output = Arc::new(output);
Ok(arc_output as Arc<dyn Any + Send + Sync>)
})
}
}
#[cfg(test)]
mod tests;