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}