use sim_kernel::{Cx, Expr, Object, ObjectCompat, Ref, Result, Symbol};
#[sim_citizen_derive::non_citizen(
reason = "live continuation capture handle; descriptor data is the continuation and capture refs",
kind = "handle",
descriptor = "core/Ref"
)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ContinuationValue {
continuation: Ref,
capture_result: Ref,
multishot: bool,
}
impl ContinuationValue {
pub fn new(continuation: Ref, capture_result: Ref, multishot: bool) -> Self {
Self {
continuation,
capture_result,
multishot,
}
}
pub fn continuation(&self) -> &Ref {
&self.continuation
}
pub fn capture_result(&self) -> &Ref {
&self.capture_result
}
pub fn multishot(&self) -> bool {
self.multishot
}
}
impl Object for ContinuationValue {
fn display(&self, _cx: &mut Cx) -> Result<String> {
Ok(format!("#<control-continuation {:?}>", self.continuation))
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl ObjectCompat for ContinuationValue {
fn as_expr(&self, _cx: &mut Cx) -> Result<Expr> {
Ok(Expr::Call {
operator: Box::new(Expr::Symbol(Symbol::qualified("control", "continuation"))),
args: vec![ref_expr(&self.continuation)],
})
}
}
#[sim_citizen_derive::non_citizen(
reason = "control result ref wrapper; canonical data is the referenced value",
kind = "marker"
)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ControlResultValue {
reference: Ref,
}
impl ControlResultValue {
pub fn new(reference: Ref) -> Self {
Self { reference }
}
pub fn reference(&self) -> &Ref {
&self.reference
}
}
impl Object for ControlResultValue {
fn display(&self, _cx: &mut Cx) -> Result<String> {
Ok(format!("#<control-result {:?}>", self.reference))
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl ObjectCompat for ControlResultValue {
fn as_expr(&self, _cx: &mut Cx) -> Result<Expr> {
Ok(ref_expr(&self.reference))
}
}
pub(crate) fn ref_expr(reference: &Ref) -> Expr {
match reference {
Ref::Symbol(symbol) => Expr::Symbol(symbol.clone()),
other => Expr::String(format!("{other:?}")),
}
}