rune/module/
trait_mut.rs

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