use super::RunId;
use super::run_control::RunControlCommand;
use super::run_primitive::RunPrimitive;
use super::run_receipt::RunBoundaryReceipt;
use crate::types::RunResult;
#[derive(Debug, Clone, thiserror::Error)]
#[non_exhaustive]
pub enum CoreExecutorError {
#[error("Apply failed: {reason}")]
ApplyFailed { reason: String },
#[error("Control failed: {reason}")]
ControlFailed { reason: String },
#[error("Executor is stopped")]
Stopped,
#[error("Internal error: {0}")]
Internal(String),
}
#[derive(Debug, Clone)]
pub struct CoreApplyOutput {
pub receipt: RunBoundaryReceipt,
pub session_snapshot: Option<Vec<u8>>,
pub run_result: Option<RunResult>,
}
#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
pub trait CoreExecutor: Send + Sync {
async fn apply(
&mut self,
run_id: RunId,
primitive: RunPrimitive,
) -> Result<CoreApplyOutput, CoreExecutorError>;
async fn control(&mut self, command: RunControlCommand) -> Result<(), CoreExecutorError>;
}
#[cfg(test)]
mod tests {
use super::*;
fn _assert_object_safe(_: &dyn CoreExecutor) {}
#[test]
fn core_executor_error_display() {
let err = CoreExecutorError::ApplyFailed {
reason: "bad input".into(),
};
assert_eq!(err.to_string(), "Apply failed: bad input");
let err = CoreExecutorError::ControlFailed {
reason: "not running".into(),
};
assert_eq!(err.to_string(), "Control failed: not running");
let err = CoreExecutorError::Stopped;
assert_eq!(err.to_string(), "Executor is stopped");
let err = CoreExecutorError::Internal("oops".into());
assert_eq!(err.to_string(), "Internal error: oops");
}
}