use std::fmt;
use crate::{ll::vm, Engine, Error, TryFromValue, Value};
pub struct Fiber<'e> {
pub(crate) engine: &'e mut Engine,
pub(crate) inner: vm::Fiber,
}
impl<'e> Fiber<'e> {
pub fn resume<T>(&mut self) -> Result<Option<T>, Error>
where
T: TryFromValue,
{
if self.inner.halted() {
Ok(None)
} else {
let Engine { env, globals, gc, .. } = &mut self.engine;
let result = self.inner.interpret(env, globals, gc)?;
Ok(Some(T::try_from_value(&Value::from_raw(result), &self.engine.env)?))
}
}
pub fn trampoline<T>(mut self) -> Result<T, Error>
where
T: TryFromValue,
{
let mut result = Value::Nil;
while let Some(v) = self.resume()? {
result = v;
}
T::try_from_value(&result, &self.engine.env)
}
}
impl<'e> fmt::Debug for Fiber<'e> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Fiber").finish_non_exhaustive()
}
}