Skip to main content

traverse_runtime/executor/
native.rs

1//! Native (Rust closure) executor.
2
3use serde_json::Value;
4
5use super::{ArtifactType, CapabilityExecutor, ExecutorCapability, ExecutorError, ExecutorOutput};
6
7/// Handler type alias for native capability implementations.
8type NativeHandler = Box<dyn Fn(&Value) -> Result<Value, String> + Send + Sync>;
9
10/// Executes capabilities implemented as native Rust functions.
11///
12/// The handler is stored as a boxed closure and invoked synchronously.
13pub struct NativeExecutor {
14    handler: NativeHandler,
15}
16
17impl std::fmt::Debug for NativeExecutor {
18    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19        f.debug_struct("NativeExecutor").finish_non_exhaustive()
20    }
21}
22
23impl NativeExecutor {
24    /// Create a new [`NativeExecutor`] backed by `handler`.
25    pub fn new(handler: impl Fn(&Value) -> Result<Value, String> + Send + Sync + 'static) -> Self {
26        Self {
27            handler: Box::new(handler),
28        }
29    }
30}
31
32impl CapabilityExecutor for NativeExecutor {
33    fn execute(
34        &self,
35        capability: &ExecutorCapability,
36        input: &Value,
37    ) -> Result<ExecutorOutput, ExecutorError> {
38        if capability.artifact_type != ArtifactType::Native {
39            return Err(ExecutorError::UnsupportedArtifactType);
40        }
41        (self.handler)(input)
42            .map(|value| ExecutorOutput {
43                value,
44                emitted_events: Vec::new(),
45            })
46            .map_err(ExecutorError::ExecutionFailed)
47    }
48}