Skip to main content

sim_lib_control/
prompt.rs

1use sim_kernel::{
2    Cx, Ref, Result, Symbol,
3    control::{ControlPrompt as KernelControlPrompt, default_control_result_shape, prompt},
4};
5
6/// Stable tag identifying a delimited control prompt.
7#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
8pub struct ControlTag {
9    symbol: Symbol,
10}
11
12impl ControlTag {
13    /// Builds a control tag from a symbol.
14    pub fn new(symbol: Symbol) -> Self {
15        Self { symbol }
16    }
17
18    /// Returns the symbol carried by this tag.
19    pub fn symbol(&self) -> &Symbol {
20        &self.symbol
21    }
22
23    /// Consumes this tag and returns its symbol.
24    pub fn into_symbol(self) -> Symbol {
25        self.symbol
26    }
27}
28
29/// Library-level contract for prompts raised by runtime organs.
30pub trait ControlPrompt {
31    /// Returns the stable tag identifying the prompt kind.
32    fn tag(&self) -> ControlTag;
33
34    /// Returns the input reference supplied to the prompt body.
35    fn input(&self) -> Ref {
36        Ref::Symbol(self.tag().into_symbol())
37    }
38
39    /// Returns the shape reference expected for the prompt result.
40    fn result_shape(&self) -> Ref {
41        default_control_result_shape()
42    }
43}
44
45/// Raises a library-level control prompt through the kernel control contract.
46pub fn raise_prompt(cx: &mut Cx, prompt_record: &dyn ControlPrompt) -> Result<Ref> {
47    let kernel_prompt = KernelControlPrompt::new(
48        Ref::Symbol(prompt_record.tag().into_symbol()),
49        prompt_record.input(),
50        prompt_record.result_shape(),
51    );
52    let input = kernel_prompt.input.clone();
53    prompt(cx, kernel_prompt, |_cx| Ok(input))
54}