rune/module/
module_meta.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
use core::fmt;

use ::rust_alloc::sync::Arc;

use crate as rune;
use crate::alloc;
use crate::alloc::prelude::*;
use crate::compile::context::{AttributeMacroHandler, MacroHandler, TraitHandler};
use crate::compile::{meta, Docs};
use crate::function_meta::AssociatedName;
use crate::runtime::{ConstValue, FieldMap, FunctionHandler, TypeInfo};
use crate::{Hash, ItemBuf};

#[doc(hidden)]
pub struct ModuleMetaData {
    #[doc(hidden)]
    pub item: ItemBuf,
    #[doc(hidden)]
    pub docs: &'static [&'static str],
}

/// Type used to collect and store module metadata through the `#[rune::module]`
/// macro.
///
/// This is the argument type for [`Module::from_meta`], and is from a public
/// API perspective completely opaque and might change for any release.
///
/// Calling and making use of `ModuleMeta` manually despite this warning might
/// lead to future breakage.
///
/// [`Module::from_meta`]: crate::Module::from_meta
pub type ModuleMeta = fn() -> alloc::Result<ModuleMetaData>;

/// Data for an opaque type. If `spec` is set, indicates things which are known
/// about that type.
pub(crate) struct ModuleType {
    /// The name of the installed type which will be the final component in the
    /// item it will constitute.
    pub(crate) item: ItemBuf,
    /// Type hash of the type.
    pub(crate) hash: Hash,
    /// Common item metadata.
    pub(crate) common: ModuleItemCommon,
    /// Type parameters for this item.
    pub(crate) type_parameters: Hash,
    /// Type information for the installed type.
    pub(crate) type_info: TypeInfo,
    /// The specification for the type.
    pub(crate) spec: Option<TypeSpecification>,
    /// Handler to use if this type can be constructed through a regular function call.
    pub(crate) constructor: Option<Arc<FunctionHandler>>,
}

/// A trait defined in a module.
pub(crate) struct ModuleTrait {
    pub(crate) item: ItemBuf,
    pub(crate) hash: Hash,
    pub(crate) common: ModuleItemCommon,
    pub(crate) handler: Option<Arc<TraitHandler>>,
    pub(crate) functions: Vec<TraitFunction>,
}

/// A type implementing a trait.
pub(crate) struct ModuleTraitImpl {
    pub(crate) item: ItemBuf,
    pub(crate) hash: Hash,
    pub(crate) type_info: TypeInfo,
    pub(crate) trait_item: ItemBuf,
    pub(crate) trait_hash: Hash,
}

/// A reexport of an item.
pub(crate) struct ModuleReexport {
    pub(crate) item: ItemBuf,
    pub(crate) hash: Hash,
    pub(crate) to: ItemBuf,
}

/// The kind of the variant.
#[derive(Debug)]
pub(crate) enum Fields {
    /// Sequence of named fields.
    Named(&'static [&'static str]),
    /// Sequence of unnamed fields.
    Unnamed(usize),
    /// Empty.
    Empty,
}

impl Fields {
    /// Get the number of named fields.
    #[inline]
    fn size(&self) -> usize {
        match self {
            Fields::Named(fields) => fields.len(),
            _ => 0,
        }
    }

    /// Coerce into fields hash map.
    #[inline]
    pub(crate) fn to_fields(&self) -> alloc::Result<FieldMap<Box<str>, usize>> {
        let mut fields = crate::runtime::new_field_hash_map_with_capacity(self.size())?;

        if let Fields::Named(names) = self {
            for (index, name) in names.iter().copied().enumerate() {
                fields.try_insert(name.try_into()?, index)?;
            }
        }

        Ok(fields)
    }
}

/// Metadata about a variant.
pub struct Variant {
    /// The name of the variant.
    pub(crate) name: &'static str,
    /// Variant metadata.
    pub(crate) fields: Option<Fields>,
    /// Handler to use if this variant can be constructed through a regular function call.
    pub(crate) constructor: Option<Arc<FunctionHandler>>,
    /// Variant deprecation.
    pub(crate) deprecated: Option<Box<str>>,
    /// Variant documentation.
    pub(crate) docs: Docs,
}

impl Variant {
    pub(super) fn new(name: &'static str) -> Self {
        Self {
            name,
            fields: None,
            constructor: None,
            deprecated: None,
            docs: Docs::EMPTY,
        }
    }
}

impl fmt::Debug for Variant {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut f = f.debug_struct("Variant");
        f.field("fields", &self.fields);
        f.field("constructor", &self.constructor.is_some());
        #[cfg(feature = "doc")]
        f.field("deprecated", &self.deprecated);
        f.field("docs", &self.docs);
        f.finish()
    }
}

/// The type specification for a native enum.
pub(crate) struct Enum {
    /// The variants.
    pub(crate) variants: Vec<Variant>,
}

/// A type specification.
pub(crate) enum TypeSpecification {
    Struct(Fields),
    Enum(Enum),
}

/// A key that identifies an associated function.
#[derive(Debug, TryClone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub(crate) struct AssociatedKey {
    /// The type the associated function belongs to.
    pub(crate) type_hash: Hash,
    /// The kind of the associated function.
    pub(crate) kind: meta::AssociatedKind,
    /// The type parameters of the associated function.
    pub(crate) parameters: Hash,
}

pub(crate) enum ModuleItemKind {
    Constant(ConstValue),
    Function(ModuleFunction),
    Macro(ModuleMacro),
    AttributeMacro(ModuleAttributeMacro),
}

pub(crate) struct ModuleItem {
    pub(crate) item: ItemBuf,
    pub(crate) hash: Hash,
    pub(crate) common: ModuleItemCommon,
    pub(crate) kind: ModuleItemKind,
}

#[derive(Default, TryClone)]
pub(crate) struct DocFunction {
    #[cfg(feature = "doc")]
    #[try_clone(copy)]
    pub(crate) is_async: bool,
    #[cfg(feature = "doc")]
    #[try_clone(copy)]
    pub(crate) args: Option<usize>,
    #[cfg(feature = "doc")]
    pub(crate) argument_types: Box<[meta::DocType]>,
    #[cfg(feature = "doc")]
    pub(crate) return_type: meta::DocType,
}

#[derive(TryClone)]
pub(crate) struct ModuleFunction {
    /// The handler for the function.
    pub(crate) handler: Arc<FunctionHandler>,
    /// If the function is associated with a trait, this is the hash of that trait.
    pub(crate) trait_hash: Option<Hash>,
    /// Documentation related to the function.
    pub(crate) doc: DocFunction,
}

#[derive(TryClone)]
pub(crate) enum ModuleAssociatedKind {
    Constant(ConstValue),
    Function(ModuleFunction),
}

#[derive(Default, TryClone)]
pub(crate) struct ModuleItemCommon {
    /// Documentation for the item.
    pub(crate) docs: Docs,
    /// Deprecation marker for the item.
    pub(crate) deprecated: Option<Box<str>>,
}

#[derive(TryClone)]
pub(crate) struct ModuleAssociated {
    pub(crate) container: Hash,
    pub(crate) container_type_info: TypeInfo,
    pub(crate) name: AssociatedName,
    pub(crate) common: ModuleItemCommon,
    pub(crate) kind: ModuleAssociatedKind,
}

/// Handle to a macro inserted into a module.
pub(crate) struct ModuleMacro {
    pub(crate) handler: Arc<MacroHandler>,
}

/// Handle to an attribute macro inserted into a module.
pub(crate) struct ModuleAttributeMacro {
    pub(crate) handler: Arc<AttributeMacroHandler>,
}

/// Handle to a trait function inserted into a module.
pub(crate) struct TraitFunction {
    pub(crate) name: AssociatedName,
    pub(crate) common: ModuleItemCommon,
    pub(crate) doc: DocFunction,
}