artichoke_backend/
module_registry.rs1use 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}