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