rune/module/
item_fn_mut.rs

1use core::fmt;
2
3#[cfg(feature = "doc")]
4use crate::alloc::Box;
5#[cfg(feature = "doc")]
6use crate::compile::meta;
7use crate::compile::{ContextError, Docs};
8use crate::function_meta::FunctionArgs;
9use crate::runtime::MaybeTypeOf;
10
11/// Handle to a an item inserted into a module which allows for mutation of item
12/// metadata.
13///
14/// This is returned by methods which insert meta items, such as:
15/// * [`Module::raw_fn`].
16/// * [`Module::function`].
17/// * [`Module::associated_function`].
18///
19/// While this is also returned by `*_meta` inserting functions, it is instead
20/// recommended that you make use of the appropriate macro to capture doc
21/// comments instead:
22/// * [`Module::macro_meta`].
23/// * [`Module::function_meta`].
24///
25/// [`Module::raw_fn`]: super::Module::raw_fn
26/// [`Module::function`]: super::Module::function
27/// [`Module::associated_function`]: super::Module::associated_function
28/// [`Module::macro_meta`]: super::Module::macro_meta
29/// [`Module::function_meta`]: super::Module::function_meta
30pub struct ItemFnMut<'a> {
31    pub(super) docs: &'a mut Docs,
32    #[cfg(feature = "doc")]
33    pub(super) deprecated: &'a mut Option<Box<str>>,
34    #[cfg(feature = "doc")]
35    pub(super) is_async: &'a mut bool,
36    #[cfg(feature = "doc")]
37    pub(super) args: &'a mut Option<usize>,
38    #[cfg(feature = "doc")]
39    pub(super) argument_types: &'a mut Box<[meta::DocType]>,
40    #[cfg(feature = "doc")]
41    pub(super) return_type: &'a mut meta::DocType,
42}
43
44impl ItemFnMut<'_> {
45    /// Set documentation for an inserted item.
46    ///
47    /// This completely replaces any existing documentation.
48    pub fn docs(self, docs: impl IntoIterator<Item: AsRef<str>>) -> Result<Self, ContextError> {
49        self.docs.set_docs(docs)?;
50        Ok(self)
51    }
52
53    /// Mark the given item as an async function.
54    pub fn is_async(self, #[cfg_attr(not(feature = "doc"), allow(unused))] is_async: bool) -> Self {
55        #[cfg(feature = "doc")]
56        {
57            *self.is_async = is_async;
58        }
59
60        self
61    }
62
63    /// Mark the given item as deprecated.
64    pub fn deprecated(
65        self,
66        #[cfg_attr(not(feature = "doc"), allow(unused))] deprecated: impl AsRef<str>,
67    ) -> Result<Self, ContextError> {
68        #[cfg(feature = "doc")]
69        {
70            *self.deprecated = Some(deprecated.as_ref().try_into()?);
71        }
72
73        Ok(self)
74    }
75
76    /// Indicate the number of arguments this function accepts.
77    pub fn args(self, #[cfg_attr(not(feature = "doc"), allow(unused))] args: usize) -> Self {
78        #[cfg(feature = "doc")]
79        {
80            *self.args = Some(args);
81        }
82
83        self
84    }
85
86    /// Set the kind of return type.
87    pub fn return_type<T>(self) -> Result<Self, ContextError>
88    where
89        T: MaybeTypeOf,
90    {
91        #[cfg(feature = "doc")]
92        {
93            *self.return_type = T::maybe_type_of()?;
94        }
95
96        Ok(self)
97    }
98
99    /// Set argument types.
100    pub fn argument_types<A>(self) -> Result<Self, ContextError>
101    where
102        A: FunctionArgs,
103    {
104        #[cfg(feature = "doc")]
105        {
106            *self.argument_types = A::into_box()?;
107            *self.args = Some(A::len());
108        }
109
110        Ok(self)
111    }
112}
113
114impl fmt::Debug for ItemFnMut<'_> {
115    #[inline]
116    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117        f.debug_struct("ItemFnMut").finish_non_exhaustive()
118    }
119}