rune/module/
module_constant_builder.rs

1use crate::compile::ContextError;
2use crate::function_meta::{Associated, ToInstance};
3use crate::item::IntoComponent;
4use crate::module::ItemMut;
5use crate::runtime::{ToConstValue, TypeHash, TypeOf};
6
7use super::Module;
8
9/// Raw function builder as returned by [`Module::raw_function`].
10///
11/// This allows for building a function regularly with
12/// [`ModuleConstantBuilder::build`] or statically associate the function with a
13/// type through [`ModuleConstantBuilder::build_associated::<T>`].
14#[must_use = "Must call one of the build functions, like `build` or `build_associated`"]
15pub struct ModuleConstantBuilder<'a, N, V> {
16    pub(super) module: &'a mut Module,
17    pub(super) name: N,
18    pub(super) value: V,
19}
20
21impl<'a, N, V> ModuleConstantBuilder<'a, N, V>
22where
23    V: TypeHash + TypeOf + ToConstValue,
24{
25    /// Add the free constant directly to the module.
26    ///
27    /// # Examples
28    ///
29    /// ```
30    /// use rune::{Any, Module};
31    /// use rune::runtime::VmResult;
32    ///
33    /// let mut m = Module::with_item(["module"])?;
34    /// m.constant("NAME", "Hello World").build()?;
35    /// # Ok::<_, rune::support::Error>(())
36    /// ```
37    pub fn build(self) -> Result<ItemMut<'a>, ContextError>
38    where
39        N: IntoComponent,
40    {
41        self.module.insert_constant(self.name, self.value)
42    }
43
44    /// Build a constant that is associated with the static type `T`.
45    ///
46    /// # Errors
47    ///
48    /// This function call will cause an error in [`Context::install`] if the
49    /// type we're associating it with has not been registered.
50    ///
51    /// [`Context::install`]: crate::Context::install
52    ///
53    /// ```
54    /// use rune::{Any, Context, Module};
55    ///
56    /// #[derive(Any)]
57    /// struct Thing;
58    ///
59    /// let mut m = Module::default();
60    /// m.constant("CONSTANT", "Hello World").build_associated::<Thing>()?;
61    ///
62    /// let mut c = Context::default();
63    /// assert!(c.install(m).is_err());
64    /// # Ok::<_, rune::support::Error>(())
65    /// ```
66    ///
67    /// # Examples
68    ///
69    /// ```
70    /// use rune::{docstring, Any, Module};
71    ///
72    /// let mut module = Module::default();
73    ///
74    /// #[derive(Any)]
75    /// struct Thing;
76    ///
77    /// module.constant("TEN", 10)
78    ///     .build_associated::<Thing>()?
79    ///     .docs(docstring! {
80    ///         /// Ten which is an associated constant.
81    ///     });
82    /// # Ok::<_, rune::support::Error>(())
83    /// ```
84    pub fn build_associated<T>(self) -> Result<ItemMut<'a>, ContextError>
85    where
86        T: TypeOf,
87        N: ToInstance,
88    {
89        let name = self.name.to_instance()?;
90        let associated = Associated::from_type::<T>(name)?;
91        self.module
92            .insert_associated_constant(associated, self.value)
93    }
94}