onion_vm/lambda/
runnable.rs1use std::fmt::Display;
2
3use arc_gc::gc::GC;
4use serde_json::Value;
5
6use crate::types::object::{OnionObjectCell, OnionStaticObject};
7
8#[derive(Clone, Debug)]
9pub enum RuntimeError {
10 StepError(Box<String>),
11 DetailedError(Box<String>),
12 InvalidType(Box<String>),
13 InvalidOperation(Box<String>),
14 CustomValue(Box<OnionStaticObject>),
15 BrokenReference,
16 BorrowError(Box<String>),
17}
18
19impl Display for RuntimeError {
20 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21 match self {
22 RuntimeError::StepError(msg) => write!(f, "Step Error: {}", msg),
23 RuntimeError::DetailedError(msg) => write!(f, "Detailed Error: {}", msg),
24 RuntimeError::InvalidType(msg) => write!(f, "Invalid type: {}", msg),
25 RuntimeError::InvalidOperation(msg) => write!(f, "Invalid operation: {}", msg),
26 RuntimeError::BrokenReference => write!(f, "Broken reference encountered"),
27 RuntimeError::BorrowError(msg) => write!(f, "Borrow error: {}", msg),
28 RuntimeError::CustomValue(value) => write!(f, "Custom value error: {}", value),
29 }
30 }
31}
32
33pub enum StepResult {
34 Continue,
35 NewRunnable(Box<dyn Runnable>),
36 ReplaceRunnable(Box<dyn Runnable>),
37 Return(Box<OnionStaticObject>),
38 SetSelfObject(Box<OnionStaticObject>),
39 Error(RuntimeError),
40}
41
42impl StepResult {
43 pub fn unwrap_error(self) -> RuntimeError {
44 match self {
45 StepResult::Error(error) => error,
46 _ => RuntimeError::StepError(
47 "Expected an error, but got a different result"
48 .to_string()
49 .into(),
50 ),
51 }
52 }
53}
54
55#[macro_export]
56macro_rules! unwrap_step_result {
57 ($result:expr) => {
58 match $result {
59 Ok(value) => value,
60 Err(error) => return StepResult::Error(error),
61 }
62 };
63}
64
65#[allow(unused_variables)]
66pub trait Runnable: Send + Sync + 'static {
67 fn step(&mut self, gc: &mut GC<OnionObjectCell>) -> StepResult;
68 fn receive(
69 &mut self,
70 step_result: &StepResult,
71 gc: &mut GC<OnionObjectCell>,
72 ) -> Result<(), RuntimeError> {
73 Err(RuntimeError::DetailedError(
74 "receive not implemented".to_string().into(),
75 ))
76 }
77 fn copy_with_gc(&self, gc: &mut GC<OnionObjectCell>) -> Box<dyn Runnable> {
78 panic!("copy_with_gc is not implemented for this Runnable")
79 }
80 fn copy(&self) -> Box<dyn Runnable>;
81
82 fn format_context(&self) -> Result<Value, RuntimeError>;
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88
89 #[test]
90 fn check_step_result_size() {
91 println!("Size of StepResult: {}", std::mem::size_of::<StepResult>());
92 }
93}