artichoke_core/
value.rs

1//! Types that implement `Value` can be represented in the Artichoke VM.
2
3use alloc::vec::Vec;
4
5use crate::convert::{TryConvert, TryConvertMut};
6use crate::types::Ruby;
7
8/// A boxed Ruby value owned by the interpreter.
9///
10/// `Value` is equivalent to an `RValue` in MRI or `mrb_value` in mruby.
11pub trait Value {
12    /// Concrete type for Artichoke interpreter.
13    type Artichoke;
14
15    /// Concrete type for arguments passed to [`funcall`](Value::funcall).
16    type Arg;
17
18    /// Concrete type for results from [`funcall`](Value::funcall).
19    type Value: Value;
20
21    /// Concrete type for blocks passed to [`funcall`](Value::funcall).
22    type Block;
23
24    /// Concrete error type for funcall errors.
25    type Error;
26
27    /// Call a method on this [`Value`] with arguments and an optional block.
28    ///
29    /// # Errors
30    ///
31    /// If an exception is raised on the interpreter, then an error is returned.
32    ///
33    /// If a [`TryConvert`] conversion fails, then an error is returned.
34    fn funcall(
35        &self,
36        interp: &mut Self::Artichoke,
37        func: &str,
38        args: &[Self::Arg],
39        block: Option<Self::Block>,
40    ) -> Result<Self::Value, Self::Error>;
41
42    /// Consume `self` and try to convert `self` to type `T` using a
43    /// [`TryConvert`] conversion.
44    ///
45    /// # Errors
46    ///
47    /// If a [`TryConvert`] conversion fails, then an error is returned.
48    fn try_convert_into<T>(self, interp: &Self::Artichoke) -> Result<T, Self::Error>
49    where
50        Self: Sized,
51        Self::Artichoke: TryConvert<Self, T, Error = Self::Error>,
52    {
53        interp.try_convert(self)
54    }
55
56    /// Consume `self` and try to convert `self` to type `T` using a
57    /// [`TryConvertMut`] conversion.
58    ///
59    /// # Errors
60    ///
61    /// If a [`TryConvertMut`] conversion fails, then an error is returned.
62    fn try_convert_into_mut<T>(self, interp: &mut Self::Artichoke) -> Result<T, Self::Error>
63    where
64        Self: Sized,
65        Self::Artichoke: TryConvertMut<Self, T, Error = Self::Error>,
66    {
67        interp.try_convert_mut(self)
68    }
69
70    /// Call `#freeze` on this [`Value`].
71    ///
72    /// # Errors
73    ///
74    /// If an exception is raised on the interpreter, then an error is returned.
75    fn freeze(&mut self, interp: &mut Self::Artichoke) -> Result<(), Self::Error>;
76
77    /// Call `#frozen?` on this [`Value`].
78    fn is_frozen(&self, interp: &mut Self::Artichoke) -> bool;
79
80    /// Whether `self` is `nil`
81    fn is_nil(&self) -> bool;
82
83    /// Whether `self` responds to a method.
84    ///
85    /// Equivalent to invoking `#respond_to?` on this [`Value`].
86    ///
87    /// # Errors
88    ///
89    /// If an exception is raised on the interpreter, then an error is returned.
90    fn respond_to(&self, interp: &mut Self::Artichoke, method: &str) -> Result<bool, Self::Error>;
91
92    /// Call `#inspect` on this [`Value`].
93    ///
94    /// This function can never fail.
95    fn inspect(&self, interp: &mut Self::Artichoke) -> Vec<u8>;
96
97    /// Call `#to_s` on this [`Value`].
98    ///
99    /// This function can never fail.
100    fn to_s(&self, interp: &mut Self::Artichoke) -> Vec<u8>;
101
102    /// Return this values [Rust-mapped type tag](Ruby).
103    fn ruby_type(&self) -> Ruby;
104}