1use sim_kernel::{Cx, Expr, Object, ObjectCompat, Ref, Result, Symbol};
2
3#[sim_citizen_derive::non_citizen(
4 reason = "live continuation capture handle; descriptor data is the continuation and capture refs",
5 kind = "handle",
6 descriptor = "core/Ref"
7)]
8#[derive(Clone, Debug, PartialEq, Eq)]
14pub struct ContinuationValue {
15 continuation: Ref,
16 capture_result: Ref,
17 multishot: bool,
18}
19
20impl ContinuationValue {
21 pub fn new(continuation: Ref, capture_result: Ref, multishot: bool) -> Self {
24 Self {
25 continuation,
26 capture_result,
27 multishot,
28 }
29 }
30
31 pub fn continuation(&self) -> &Ref {
33 &self.continuation
34 }
35
36 pub fn capture_result(&self) -> &Ref {
38 &self.capture_result
39 }
40
41 pub fn multishot(&self) -> bool {
43 self.multishot
44 }
45}
46
47impl Object for ContinuationValue {
48 fn display(&self, _cx: &mut Cx) -> Result<String> {
49 Ok(format!("#<control-continuation {:?}>", self.continuation))
50 }
51
52 fn as_any(&self) -> &dyn std::any::Any {
53 self
54 }
55}
56
57impl ObjectCompat for ContinuationValue {
58 fn as_expr(&self, _cx: &mut Cx) -> Result<Expr> {
59 Ok(Expr::Call {
60 operator: Box::new(Expr::Symbol(Symbol::qualified("control", "continuation"))),
61 args: vec![ref_expr(&self.continuation)],
62 })
63 }
64}
65
66#[sim_citizen_derive::non_citizen(
67 reason = "control result ref wrapper; canonical data is the referenced value",
68 kind = "marker"
69)]
70#[derive(Clone, Debug, PartialEq, Eq)]
75pub struct ControlResultValue {
76 reference: Ref,
77}
78
79impl ControlResultValue {
80 pub fn new(reference: Ref) -> Self {
82 Self { reference }
83 }
84
85 pub fn reference(&self) -> &Ref {
87 &self.reference
88 }
89}
90
91impl Object for ControlResultValue {
92 fn display(&self, _cx: &mut Cx) -> Result<String> {
93 Ok(format!("#<control-result {:?}>", self.reference))
94 }
95
96 fn as_any(&self) -> &dyn std::any::Any {
97 self
98 }
99}
100
101impl ObjectCompat for ControlResultValue {
102 fn as_expr(&self, _cx: &mut Cx) -> Result<Expr> {
103 Ok(ref_expr(&self.reference))
104 }
105}
106
107pub(crate) fn ref_expr(reference: &Ref) -> Expr {
108 match reference {
109 Ref::Symbol(symbol) => Expr::Symbol(symbol.clone()),
110 other => Expr::String(format!("{other:?}")),
111 }
112}