rune/module/
module_meta.rs

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