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