rune/module/
module_meta.rs

1use core::fmt;
2
3use ::rust_alloc::sync::Arc;
4
5use crate as rune;
6use crate::alloc;
7use crate::alloc::prelude::*;
8use crate::compile::context::{AttributeMacroHandler, MacroHandler, TraitHandler};
9use crate::compile::{meta, Docs};
10use crate::function_meta::AssociatedName;
11use crate::runtime::{ConstValue, FieldMap, FunctionHandler, TypeInfo};
12use crate::{Hash, ItemBuf};
13
14#[doc(hidden)]
15pub struct ModuleMetaData {
16    #[doc(hidden)]
17    pub item: ItemBuf,
18    #[doc(hidden)]
19    pub docs: &'static [&'static str],
20}
21
22/// Type used to collect and store module metadata through the `#[rune::module]`
23/// macro.
24///
25/// This is the argument type for [`Module::from_meta`], and is from a public
26/// API perspective completely opaque and might change for any release.
27///
28/// Calling and making use of `ModuleMeta` manually despite this warning might
29/// lead to future breakage.
30///
31/// [`Module::from_meta`]: crate::Module::from_meta
32pub type ModuleMeta = fn() -> alloc::Result<ModuleMetaData>;
33
34/// Data for an opaque type. If `spec` is set, indicates things which are known
35/// about that type.
36pub(crate) struct ModuleType {
37    /// The name of the installed type which will be the final component in the
38    /// item it will constitute.
39    pub(crate) item: ItemBuf,
40    /// Type hash of the type.
41    pub(crate) hash: Hash,
42    /// Common item metadata.
43    pub(crate) common: ModuleItemCommon,
44    /// Type parameters for this item.
45    pub(crate) type_parameters: Hash,
46    /// Type information for the installed type.
47    pub(crate) type_info: TypeInfo,
48    /// The specification for the type.
49    pub(crate) spec: Option<TypeSpecification>,
50    /// Handler to use if this type can be constructed through a regular function call.
51    pub(crate) constructor: Option<Arc<FunctionHandler>>,
52}
53
54/// A trait defined in a module.
55pub(crate) struct ModuleTrait {
56    pub(crate) item: ItemBuf,
57    pub(crate) hash: Hash,
58    pub(crate) common: ModuleItemCommon,
59    pub(crate) handler: Option<Arc<TraitHandler>>,
60    pub(crate) functions: Vec<TraitFunction>,
61}
62
63/// A type implementing a trait.
64pub(crate) struct ModuleTraitImpl {
65    pub(crate) item: ItemBuf,
66    pub(crate) hash: Hash,
67    pub(crate) type_info: TypeInfo,
68    pub(crate) trait_item: ItemBuf,
69    pub(crate) trait_hash: Hash,
70}
71
72/// A reexport of an item.
73pub(crate) struct ModuleReexport {
74    pub(crate) item: ItemBuf,
75    pub(crate) hash: Hash,
76    pub(crate) to: ItemBuf,
77}
78
79/// The kind of the variant.
80#[derive(Debug)]
81pub(crate) enum Fields {
82    /// Sequence of named fields.
83    Named(&'static [&'static str]),
84    /// Sequence of unnamed fields.
85    Unnamed(usize),
86    /// Empty.
87    Empty,
88}
89
90impl Fields {
91    /// Get the number of named fields.
92    #[inline]
93    fn size(&self) -> usize {
94        match self {
95            Fields::Named(fields) => fields.len(),
96            _ => 0,
97        }
98    }
99
100    /// Coerce into fields hash map.
101    #[inline]
102    pub(crate) fn to_fields(&self) -> alloc::Result<FieldMap<Box<str>, usize>> {
103        let mut fields = crate::runtime::new_field_hash_map_with_capacity(self.size())?;
104
105        if let Fields::Named(names) = self {
106            for (index, name) in names.iter().copied().enumerate() {
107                fields.try_insert(name.try_into()?, index)?;
108            }
109        }
110
111        Ok(fields)
112    }
113}
114
115/// Metadata about a variant.
116pub struct Variant {
117    /// The name of the variant.
118    pub(crate) name: &'static str,
119    /// Variant metadata.
120    pub(crate) fields: Option<Fields>,
121    /// Handler to use if this variant can be constructed through a regular function call.
122    pub(crate) constructor: Option<Arc<FunctionHandler>>,
123    /// Variant deprecation.
124    pub(crate) deprecated: Option<Box<str>>,
125    /// Variant documentation.
126    pub(crate) docs: Docs,
127}
128
129impl Variant {
130    pub(super) fn new(name: &'static str) -> Self {
131        Self {
132            name,
133            fields: None,
134            constructor: None,
135            deprecated: None,
136            docs: Docs::EMPTY,
137        }
138    }
139}
140
141impl fmt::Debug for Variant {
142    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143        let mut f = f.debug_struct("Variant");
144        f.field("fields", &self.fields);
145        f.field("constructor", &self.constructor.is_some());
146        #[cfg(feature = "doc")]
147        f.field("deprecated", &self.deprecated);
148        f.field("docs", &self.docs);
149        f.finish()
150    }
151}
152
153/// The type specification for a native enum.
154pub(crate) struct Enum {
155    /// The variants.
156    pub(crate) variants: Vec<Variant>,
157}
158
159/// A type specification.
160pub(crate) enum TypeSpecification {
161    Struct(Fields),
162    Enum(Enum),
163}
164
165/// A key that identifies an associated function.
166#[derive(Debug, TryClone, PartialEq, Eq, Hash)]
167#[non_exhaustive]
168pub(crate) struct AssociatedKey {
169    /// The type the associated function belongs to.
170    pub(crate) type_hash: Hash,
171    /// The kind of the associated function.
172    pub(crate) kind: meta::AssociatedKind,
173    /// The type parameters of the associated function.
174    pub(crate) parameters: Hash,
175}
176
177pub(crate) enum ModuleItemKind {
178    Constant(ConstValue),
179    Function(ModuleFunction),
180    Macro(ModuleMacro),
181    AttributeMacro(ModuleAttributeMacro),
182}
183
184pub(crate) struct ModuleItem {
185    pub(crate) item: ItemBuf,
186    pub(crate) hash: Hash,
187    pub(crate) common: ModuleItemCommon,
188    pub(crate) kind: ModuleItemKind,
189}
190
191#[derive(Default, TryClone)]
192pub(crate) struct DocFunction {
193    #[cfg(feature = "doc")]
194    #[try_clone(copy)]
195    pub(crate) is_async: bool,
196    #[cfg(feature = "doc")]
197    #[try_clone(copy)]
198    pub(crate) args: Option<usize>,
199    #[cfg(feature = "doc")]
200    pub(crate) argument_types: Box<[meta::DocType]>,
201    #[cfg(feature = "doc")]
202    pub(crate) return_type: meta::DocType,
203}
204
205#[derive(TryClone)]
206pub(crate) struct ModuleFunction {
207    /// The handler for the function.
208    pub(crate) handler: Arc<FunctionHandler>,
209    /// If the function is associated with a trait, this is the hash of that trait.
210    pub(crate) trait_hash: Option<Hash>,
211    /// Documentation related to the function.
212    pub(crate) doc: DocFunction,
213}
214
215#[derive(TryClone)]
216pub(crate) enum ModuleAssociatedKind {
217    Constant(ConstValue),
218    Function(ModuleFunction),
219}
220
221#[derive(Default, TryClone)]
222pub(crate) struct ModuleItemCommon {
223    /// Documentation for the item.
224    pub(crate) docs: Docs,
225    /// Deprecation marker for the item.
226    pub(crate) deprecated: Option<Box<str>>,
227}
228
229#[derive(TryClone)]
230pub(crate) struct ModuleAssociated {
231    pub(crate) container: Hash,
232    pub(crate) container_type_info: TypeInfo,
233    pub(crate) name: AssociatedName,
234    pub(crate) common: ModuleItemCommon,
235    pub(crate) kind: ModuleAssociatedKind,
236}
237
238/// Handle to a macro inserted into a module.
239pub(crate) struct ModuleMacro {
240    pub(crate) handler: Arc<MacroHandler>,
241}
242
243/// Handle to an attribute macro inserted into a module.
244pub(crate) struct ModuleAttributeMacro {
245    pub(crate) handler: Arc<AttributeMacroHandler>,
246}
247
248/// Handle to a trait function inserted into a module.
249pub(crate) struct TraitFunction {
250    pub(crate) name: AssociatedName,
251    pub(crate) common: ModuleItemCommon,
252    pub(crate) doc: DocFunction,
253}