rune/module/
trait_mut.rs

1use core::fmt;
2
3use ::rust_alloc::sync::Arc;
4
5#[cfg(feature = "doc")]
6use crate::alloc::Box;
7use crate::alloc::Vec;
8use crate::compile::context::{TraitContext, TraitHandler};
9use crate::compile::{ContextError, Docs};
10use crate::function_meta::ToInstance;
11
12use super::{DocFunction, ItemFnMut, ModuleItemCommon, TraitFunction};
13
14/// Handle to a a trait inserted into a module which allows for mutation of its
15/// metadata.
16pub struct TraitMut<'a> {
17    pub(super) docs: &'a mut Docs,
18    #[cfg(feature = "doc")]
19    pub(super) deprecated: &'a mut Option<Box<str>>,
20    pub(super) handler: &'a mut Option<Arc<TraitHandler>>,
21    pub(super) functions: &'a mut Vec<TraitFunction>,
22}
23
24impl TraitMut<'_> {
25    /// Set documentation for an inserted trait.
26    ///
27    /// This completely replaces any existing documentation.
28    pub fn docs<I>(&mut self, docs: I) -> Result<&mut Self, ContextError>
29    where
30        I: IntoIterator,
31        I::Item: AsRef<str>,
32    {
33        self.docs.set_docs(docs)?;
34        Ok(self)
35    }
36
37    /// Set static documentation.
38    ///
39    /// This completely replaces any existing documentation.
40    pub fn static_docs(
41        &mut self,
42        docs: &'static [&'static str],
43    ) -> Result<&mut Self, ContextError> {
44        self.docs.set_docs(docs)?;
45        Ok(self)
46    }
47
48    /// Mark the given trait as deprecated.
49    pub fn deprecated<S>(
50        &mut self,
51        #[cfg_attr(not(feature = "doc"), allow(unused))] deprecated: S,
52    ) -> Result<&mut Self, ContextError>
53    where
54        S: AsRef<str>,
55    {
56        #[cfg(feature = "doc")]
57        {
58            *self.deprecated = Some(deprecated.as_ref().try_into()?);
59        }
60
61        Ok(self)
62    }
63
64    /// Define a trait handler.
65    pub fn handler<F>(&mut self, handler: F) -> Result<&mut Self, ContextError>
66    where
67        F: 'static + Fn(&mut TraitContext<'_>) -> Result<(), ContextError> + Send + Sync,
68    {
69        *self.handler = Some(Arc::new(handler));
70        Ok(self)
71    }
72
73    /// Define a function on the trait.
74    pub fn function(&mut self, name: impl ToInstance) -> Result<ItemFnMut<'_>, ContextError> {
75        let name = name.to_instance()?;
76
77        self.functions.try_push(TraitFunction {
78            name,
79            common: ModuleItemCommon::default(),
80            doc: DocFunction::default(),
81        })?;
82
83        let f = self.functions.last_mut().unwrap();
84
85        Ok(ItemFnMut {
86            docs: &mut f.common.docs,
87            #[cfg(feature = "doc")]
88            deprecated: &mut f.common.deprecated,
89            #[cfg(feature = "doc")]
90            is_async: &mut f.doc.is_async,
91            #[cfg(feature = "doc")]
92            args: &mut f.doc.args,
93            #[cfg(feature = "doc")]
94            return_type: &mut f.doc.return_type,
95            #[cfg(feature = "doc")]
96            argument_types: &mut f.doc.argument_types,
97        })
98    }
99}
100
101impl fmt::Debug for TraitMut<'_> {
102    #[inline]
103    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104        f.debug_struct("TraitMut").finish_non_exhaustive()
105    }
106}