1use super::value::GosValue;
2use std::cell::RefCell;
3use std::collections::HashMap;
4use std::rc::Rc;
5
6pub type FfiResult<T> = std::result::Result<T, String>;
7
8pub type Ctor = dyn Fn(Vec<GosValue>) -> FfiResult<Rc<RefCell<dyn Ffi>>>;
9
10pub trait Ffi {
11 fn call(&self, func_name: &str, params: Vec<GosValue>) -> Vec<GosValue>;
12}
13
14impl std::fmt::Debug for dyn Ffi {
15 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
16 write!(f, "{}", "ffi obj")
17 }
18}
19
20pub struct FfiFactory {
21 registry: HashMap<&'static str, Box<Ctor>>,
22}
23
24impl FfiFactory {
25 pub fn new() -> FfiFactory {
26 FfiFactory {
27 registry: HashMap::new(),
28 }
29 }
30
31 pub fn register(&mut self, name: &'static str, ctor: Box<Ctor>) {
32 self.registry.insert(name, ctor);
33 }
34
35 pub fn create_by_name(
36 &self,
37 name: &str,
38 params: Vec<GosValue>,
39 ) -> FfiResult<Rc<RefCell<dyn Ffi>>> {
40 match self.registry.get(name) {
41 Some(ctor) => (*ctor)(params),
42 None => Err(format!("FFI named {} not found", name)),
43 }
44 }
45}
46
47impl std::fmt::Debug for FfiFactory {
48 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
49 write!(f, "FfiFactory")
50 }
51}