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    ///
32    /// let mut m = Module::with_item(["module"])?;
33    /// m.constant("NAME", "Hello World").build()?;
34    /// # Ok::<_, rune::support::Error>(())
35    /// ```
36    pub fn build(self) -> Result<ItemMut<'a>, ContextError>
37    where
38        N: IntoComponent,
39    {
40        self.module.insert_constant(self.name, self.value)
41    }
42
43    /// Build a constant that is associated with the static type `T`.
44    ///
45    /// # Errors
46    ///
47    /// This function call will cause an error in [`Context::install`] if the
48    /// type we're associating it with has not been registered.
49    ///
50    /// [`Context::install`]: crate::Context::install
51    ///
52    /// ```
53    /// use rune::{Any, Context, Module};
54    ///
55    /// #[derive(Any)]
56    /// struct Thing;
57    ///
58    /// let mut m = Module::default();
59    /// m.constant("CONSTANT", "Hello World").build_associated::<Thing>()?;
60    ///
61    /// let mut c = Context::default();
62    /// assert!(c.install(m).is_err());
63    /// # Ok::<_, rune::support::Error>(())
64    /// ```
65    ///
66    /// # Examples
67    ///
68    /// ```
69    /// use rune::{docstring, Any, Module};
70    ///
71    /// let mut module = Module::default();
72    ///
73    /// #[derive(Any)]
74    /// struct Thing;
75    ///
76    /// module.constant("TEN", 10)
77    ///     .build_associated::<Thing>()?
78    ///     .docs(docstring! {
79    ///         /// Ten which is an associated constant.
80    ///     });
81    /// # Ok::<_, rune::support::Error>(())
82    /// ```
83    pub fn build_associated<T>(self) -> Result<ItemMut<'a>, ContextError>
84    where
85        T: TypeOf,
86        N: ToInstance,
87    {
88        let name = self.name.to_instance()?;
89        let associated = Associated::from_type::<T>(name)?;
90        self.module
91            .insert_associated_constant(associated, self.value)
92    }
93}