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