Skip to main content

rune/runtime/
call.rs

1use core::fmt;
2
3#[cfg(feature = "musli")]
4use musli_core::{Decode, Encode};
5#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize};
7
8use crate as rune;
9use crate::alloc::prelude::*;
10use crate::runtime::{Future, Generator, Stream, Value, Vm, VmError};
11
12/// The calling convention of a function.
13#[derive(Debug, TryClone, Clone, Copy)]
14#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
15#[cfg_attr(feature = "musli", derive(Decode, Encode), musli(crate = musli_core))]
16#[try_clone(copy)]
17#[non_exhaustive]
18pub enum Call {
19    /// Function is `async` and returns a future that must be await:ed to make
20    /// progress.
21    Async,
22    /// Functions are immediately called and control handed over.
23    Immediate,
24    /// Function produces a stream, also known as an async generator.
25    Stream,
26    /// Function produces a generator.
27    Generator,
28}
29
30impl Call {
31    /// Perform the call with the given virtual machine.
32    #[inline]
33    pub(crate) fn call_with_vm(self, vm: Vm) -> Result<Value, VmError> {
34        Ok(match self {
35            Call::Stream => Value::try_from(Stream::new(vm))?,
36            Call::Generator => Value::try_from(Generator::new(vm))?,
37            Call::Immediate => vm.complete()?,
38            Call::Async => {
39                let future = Future::from_execution(vm.into_execution())?;
40                Value::try_from(future)?
41            }
42        })
43    }
44}
45
46impl fmt::Display for Call {
47    #[inline]
48    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49        match self {
50            Self::Immediate => {
51                write!(f, "immediate")
52            }
53            Self::Async => {
54                write!(f, "async")
55            }
56            Self::Stream => {
57                write!(f, "stream")
58            }
59            Self::Generator => {
60                write!(f, "generator")
61            }
62        }
63    }
64}