Skip to main content

telltale_machine/driver/
single_thread.rs

1//! Native single-thread guest-runtime driver.
2
3use crate::effect::EffectHandler;
4use crate::engine::{
5    ObsEvent, ProtocolMachine, ProtocolMachineConfig, ProtocolMachineError, RunStatus, StepResult,
6};
7use crate::kernel::ProtocolMachineKernel;
8use crate::loader::CodeImage;
9use crate::owned::OwnedSession;
10
11/// Native cooperative guest runtime backed by the canonical protocol machine.
12#[doc(alias = "GuestRuntime")]
13#[derive(Debug)]
14pub struct NativeSingleThreadDriver {
15    machine: ProtocolMachine,
16}
17
18impl NativeSingleThreadDriver {
19    /// Create a new guest runtime from protocol-machine config.
20    #[must_use]
21    pub fn new(config: ProtocolMachineConfig) -> Self {
22        Self {
23            machine: ProtocolMachine::new(config),
24        }
25    }
26
27    /// Wrap an existing protocol-machine instance inside this guest runtime.
28    #[must_use]
29    pub fn with_vm(machine: ProtocolMachine) -> Self {
30        Self { machine }
31    }
32
33    /// Access the inner protocol machine.
34    #[must_use]
35    pub fn machine(&self) -> &ProtocolMachine {
36        &self.machine
37    }
38
39    /// Preferred choreography open path that returns an ownership-bearing handle.
40    ///
41    /// # Errors
42    ///
43    /// Returns a `ProtocolMachineError` if the choreography cannot be loaded or claimed.
44    pub fn load_choreography_owned(
45        &mut self,
46        image: &CodeImage,
47        owner_id: impl Into<String>,
48    ) -> Result<OwnedSession, ProtocolMachineError> {
49        self.machine.load_choreography_owned(image, owner_id)
50    }
51
52    /// Execute one scheduler round via the protocol-machine kernel.
53    ///
54    /// # Errors
55    ///
56    /// Returns a `ProtocolMachineError` if a coroutine faults.
57    pub fn step_round(
58        &mut self,
59        handler: &dyn EffectHandler,
60        n: usize,
61    ) -> Result<StepResult, ProtocolMachineError> {
62        ProtocolMachineKernel::step_round(&mut self.machine, handler, n)
63    }
64
65    /// Run up to `max_rounds` with concurrency `n` via the protocol-machine kernel.
66    ///
67    /// # Errors
68    ///
69    /// Returns a `ProtocolMachineError` if a coroutine faults.
70    pub fn run(
71        &mut self,
72        handler: &dyn EffectHandler,
73        max_rounds: usize,
74        n: usize,
75    ) -> Result<RunStatus, ProtocolMachineError> {
76        ProtocolMachineKernel::run_concurrent(&mut self.machine, handler, max_rounds, n)
77    }
78
79    /// Borrow the observable trace.
80    #[must_use]
81    pub fn trace(&self) -> &[ObsEvent] {
82        self.machine.trace()
83    }
84}