rune/module/
variant_mut.rsuse core::marker::PhantomData;
use ::rust_alloc::sync::Arc;
use crate::compile::{ContextError, Docs};
use crate::function::{Function, Plain};
use crate::runtime::{FunctionHandler, TypeOf};
use super::Fields;
pub struct VariantMut<'a, T>
where
T: ?Sized + TypeOf,
{
pub(crate) index: usize,
pub(crate) docs: &'a mut Docs,
pub(crate) fields: &'a mut Option<Fields>,
pub(crate) constructor: &'a mut Option<Arc<FunctionHandler>>,
pub(crate) _marker: PhantomData<T>,
}
impl<T> VariantMut<'_, T>
where
T: ?Sized + TypeOf,
{
pub fn docs<I>(self, docs: I) -> Result<Self, ContextError>
where
I: IntoIterator,
I::Item: AsRef<str>,
{
self.docs.set_docs(docs)?;
Ok(self)
}
pub fn static_docs(self, docs: &'static [&'static str]) -> Result<Self, ContextError> {
self.docs.set_docs(docs)?;
Ok(self)
}
pub fn make_named(self, fields: &'static [&'static str]) -> Result<Self, ContextError> {
self.make(Fields::Named(fields))
}
pub fn make_unnamed(self, fields: usize) -> Result<Self, ContextError> {
self.make(Fields::Unnamed(fields))
}
pub fn make_empty(self) -> Result<Self, ContextError> {
self.make(Fields::Empty)
}
pub fn constructor<F, A>(self, constructor: F) -> Result<Self, ContextError>
where
F: Function<A, Plain, Return = T>,
{
if self.constructor.is_some() {
return Err(ContextError::VariantConstructorConflict {
type_info: T::type_info(),
index: self.index,
});
}
*self.constructor = Some(Arc::new(move |stack, addr, args, output| {
constructor.fn_call(stack, addr, args, output)
}));
Ok(self)
}
fn make(self, fields: Fields) -> Result<Self, ContextError> {
let old = self.fields.replace(fields);
if old.is_some() {
return Err(ContextError::ConflictingVariantMeta {
index: self.index,
type_info: T::type_info(),
});
}
Ok(self)
}
}