goscript_vm/
ffi.rs

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}