rune/module/
variant_mut.rs1use core::marker::PhantomData;
2
3use crate::compile::{ContextError, Docs};
4use crate::function::{Function, Plain};
5use crate::runtime::{FunctionHandler, TypeOf};
6
7use super::{Fields, TypeConstructor};
8
9pub struct VariantMut<'a, T>
12where
13 T: ?Sized + TypeOf,
14{
15 pub(crate) name: &'static str,
16 pub(crate) docs: &'a mut Docs,
17 pub(crate) fields: &'a mut Option<Fields>,
18 pub(crate) constructor: &'a mut Option<TypeConstructor>,
19 pub(crate) _marker: PhantomData<T>,
20}
21
22impl<T> VariantMut<'_, T>
23where
24 T: ?Sized + TypeOf,
25{
26 pub fn docs(self, docs: impl IntoIterator<Item: AsRef<str>>) -> Result<Self, ContextError> {
30 self.docs.set_docs(docs)?;
31 Ok(self)
32 }
33
34 pub fn static_docs(self, docs: &'static [&'static str]) -> Result<Self, ContextError> {
38 self.docs.set_docs(docs)?;
39 Ok(self)
40 }
41
42 pub fn make_named(self, fields: &'static [&'static str]) -> Result<Self, ContextError> {
44 self.make(Fields::Named(fields))
45 }
46
47 pub fn make_unnamed(self, fields: usize) -> Result<Self, ContextError> {
49 self.make(Fields::Unnamed(fields))
50 }
51
52 pub fn make_empty(self) -> Result<Self, ContextError> {
54 self.make(Fields::Empty)
55 }
56
57 pub fn constructor<F, A>(self, constructor: F) -> Result<Self, ContextError>
59 where
60 F: Function<A, Plain, Return = T>,
61 {
62 if self.constructor.is_some() {
63 return Err(ContextError::VariantConstructorConflict {
64 type_info: T::type_info(),
65 name: self.name,
66 });
67 }
68
69 let handler = FunctionHandler::new(move |stack, addr, args, output| {
70 constructor.call(stack, addr, args, output)
71 })?;
72
73 *self.constructor = Some(TypeConstructor {
74 handler,
75 args: F::ARGS,
76 });
77
78 Ok(self)
79 }
80
81 fn make(self, fields: Fields) -> Result<Self, ContextError> {
82 let old = self.fields.replace(fields);
83
84 if old.is_some() {
85 return Err(ContextError::ConflictingVariantMeta {
86 type_info: T::type_info(),
87 name: self.name,
88 });
89 }
90
91 Ok(self)
92 }
93}