1use std::{any::Any, sync::Arc};
4
5use async_trait::async_trait;
6use dyn_clone::DynClone;
7
8use super::{
9 errors::TaskError,
10 executor::EvaluatedTransition,
11 node::NodeId,
12 task::Task,
13 transition::{MarkedTransition, Transition},
14};
15
16pub trait NodeArg: Send + Sync + DynClone + 'static {}
21
22impl<T: Send + Sync + std::fmt::Debug + 'static + Clone> NodeArg for T {}
23
24#[async_trait]
31pub trait TaskNode: Send + Sync + DynClone + Any {
32 type Input: NodeArg;
34 type Output: NodeArg;
36 type Error: std::error::Error + Send + Sync + 'static;
38
39 async fn evaluate(
41 &self,
42 node_id: &DynNodeId<Self>,
43 input: &Self::Input,
44 ) -> Result<Self::Output, Self::Error>;
45}
46
47pub type DynNodeId<T> = NodeId<
49 dyn TaskNode<
50 Input = <T as TaskNode>::Input,
51 Output = <T as TaskNode>::Output,
52 Error = <T as TaskNode>::Error,
53 >,
54>;
55
56dyn_clone::clone_trait_object!(
57 TaskNode<
58 Input = dyn NodeArg,
59 Output = dyn NodeArg,
60 Error = dyn std::error::Error + Send + Sync,
61 >
62);
63
64#[async_trait]
65impl<Input: NodeArg, Output: NodeArg, Error: std::error::Error + Send + Sync + 'static> TaskNode
66 for Box<dyn TaskNode<Input = Input, Output = Output, Error = Error>>
67{
68 type Input = Input;
69 type Output = Output;
70 type Error = Error;
71
72 async fn evaluate(
73 &self,
74 node_id: &NodeId<
75 dyn TaskNode<Input = Self::Input, Output = Self::Output, Error = Self::Error>,
76 >,
77 input: &Self::Input,
78 ) -> Result<Self::Output, Self::Error> {
79 self.as_ref().evaluate(node_id, input).await
80 }
81}
82
83dyn_clone::clone_trait_object!(<Input, Output, Error> TaskNode<Input = Input, Output = Output, Error = Error>);
84
85#[doc(hidden)]
86pub trait RegisterTransition<From: TaskNode + ?Sized>: 'static {
87 #[doc(hidden)]
88 fn register<Input: NodeArg + Clone, Output: NodeArg + Clone>(
89 self,
90 task: &mut Task<Input, Output>,
91 from: NodeId<From>,
92 ) -> Result<(), TaskError>;
93}
94
95#[doc(hidden)]
96pub trait RegisterTransitionAsync<From: TaskNode + ?Sized>: 'static {
97 #[doc(hidden)]
98 fn register_async<Input: NodeArg + Clone, Output: NodeArg + Clone>(
99 self,
100 task: &mut Task<Input, Output>,
101 from: NodeId<From>,
102 ) -> Result<(), TaskError>;
103}
104
105pub(super) trait TransitionResult<From: TaskNode + ?Sized> {
106 fn into_transition(self) -> Transition;
107}
108
109impl<From, To> TransitionResult<From> for MarkedTransition<To>
110where
111 From: TaskNode + 'static + ?Sized,
112 To: TaskNode + ?Sized,
113{
114 fn into_transition(self) -> Transition {
115 self.into_inner()
116 }
117}
118
119impl<From> TransitionResult<From> for Transition
120where
121 From: TaskNode + 'static + ?Sized,
122{
123 fn into_transition(self) -> Transition {
124 self
125 }
126}
127
128#[async_trait]
130pub(crate) trait AnyNodeExecutor: Any + Send + Sync + std::fmt::Debug + DynClone {
131 fn node_as_any(&self) -> &dyn Any;
132
133 fn transition_is_set(&self) -> bool;
134
135 async fn evaluate_next(
136 &self,
137 context: Arc<dyn Any + Send + Sync>,
138 ) -> Result<EvaluatedTransition, TaskError>;
139}
140
141dyn_clone::clone_trait_object!(AnyNodeExecutor);