artichoke_backend/
module_registry.rs

1use std::any::Any;
2
3use crate::Artichoke;
4use crate::core::ModuleRegistry;
5use crate::error::Error;
6use crate::ffi::InterpreterExtractError;
7use crate::module;
8use crate::sys;
9use crate::value::Value;
10
11impl ModuleRegistry for Artichoke {
12    type Value = Value;
13    type Error = Error;
14    type Spec = module::Spec;
15
16    fn def_module<T>(&mut self, spec: Self::Spec) -> Result<(), Self::Error>
17    where
18        T: Any,
19    {
20        let state = self.state.as_deref_mut().ok_or_else(InterpreterExtractError::new)?;
21        state.modules.insert::<T>(Box::new(spec));
22        Ok(())
23    }
24
25    fn module_spec<T>(&self) -> Result<Option<&Self::Spec>, Self::Error>
26    where
27        T: Any,
28    {
29        let state = self.state.as_deref().ok_or_else(InterpreterExtractError::new)?;
30        let spec = state.modules.get::<T>();
31        Ok(spec)
32    }
33
34    fn module_of<T>(&mut self) -> Result<Option<Self::Value>, Self::Error>
35    where
36        T: Any,
37    {
38        let state = self.state.as_deref().ok_or_else(InterpreterExtractError::new)?;
39        let spec = state.modules.get::<T>();
40        let Some(spec) = spec else {
41            return Ok(None);
42        };
43        let rclass = spec.rclass();
44        let rclass = unsafe { self.with_ffi_boundary(|mrb| rclass.resolve(mrb))? };
45        let Some(mut rclass) = rclass else {
46            return Ok(None);
47        };
48        let module = unsafe { sys::mrb_sys_module_value(rclass.as_mut()) };
49        let module = Value::from(module);
50        Ok(Some(module))
51    }
52}