onion_vm/lambda/
runnable.rs1
2use std::fmt::Display;
6
7use arc_gc::gc::GC;
8
9use crate::{
10 lambda::scheduler::async_scheduler::Task,
11 types::object::{OnionObjectCell, OnionStaticObject},
12};
13
14
15#[derive(Clone, Debug)]
19pub enum RuntimeError {
20 Pending,
22 BrokenReference,
24 StepError(Box<str>),
26 DetailedError(Box<str>),
28 InvalidType(Box<str>),
30 InvalidOperation(Box<str>),
32 CustomValue(Box<OnionStaticObject>),
34 BorrowError(Box<str>),
36}
37
38impl Display for RuntimeError {
39 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40 match self {
41 RuntimeError::Pending => write!(f, "Pending: The operation is not yet complete"),
42 RuntimeError::StepError(msg) => write!(f, "Step Error: {}", msg),
43 RuntimeError::DetailedError(msg) => write!(f, "{}", msg),
44 RuntimeError::InvalidType(msg) => write!(f, "Invalid type: {}", msg),
45 RuntimeError::InvalidOperation(msg) => write!(f, "Invalid operation: {}", msg),
46 RuntimeError::BrokenReference => write!(f, "Broken reference encountered"),
47 RuntimeError::BorrowError(msg) => write!(f, "Borrow error: {}", msg),
48 RuntimeError::CustomValue(value) => write!(f, "Custom value error: {}", value),
49 }
50 }
51}
52
53
54pub enum StepResult {
58 Continue,
60 NewRunnable(Box<dyn Runnable>),
62 ReplaceRunnable(Box<dyn Runnable>),
64 SpawnRunnable(Box<Task>),
66 Return(Box<OnionStaticObject>),
68 Error(RuntimeError),
70}
71
72#[macro_export]
76macro_rules! unwrap_step_result {
77 ($result:expr) => {
78 match $result {
79 Ok(value) => value,
80 Err(error) => return StepResult::Error(error),
81 }
82 };
83}
84
85
86pub trait Runnable: Send + Sync + 'static {
90 fn step(&mut self, gc: &mut GC<OnionObjectCell>) -> StepResult;
98
99 #[allow(unused_variables)]
109 fn receive(
110 &mut self,
111 step_result: &StepResult,
112 gc: &mut GC<OnionObjectCell>,
113 ) -> Result<(), RuntimeError> {
114 Err(RuntimeError::DetailedError(
115 "receive not implemented".into(),
116 ))
117 }
118
119 fn format_context(&self) -> String;
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126
127 #[test]
128 fn check_step_result_size() {
129 println!("Size of StepResult: {}", std::mem::size_of::<StepResult>());
130 }
131}