1use std::collections::HashMap;
5
6use crate::types::Effect;
7
8use super::manifest::{FfiArg, FfiManifest, FfiReturn};
9
10#[derive(Debug, Clone)]
16pub struct FfiBindings {
17 pub functions: HashMap<String, FfiFunctionInfo>,
19 pub linker_flags: Vec<String>,
21}
22
23#[derive(Debug, Clone)]
25pub struct FfiFunctionInfo {
26 pub c_name: String,
28 pub seq_name: String,
30 pub effect: Effect,
32 pub args: Vec<FfiArg>,
34 pub return_spec: Option<FfiReturn>,
36}
37
38impl FfiBindings {
39 pub fn new() -> Self {
41 FfiBindings {
42 functions: HashMap::new(),
43 linker_flags: Vec::new(),
44 }
45 }
46
47 pub fn add_manifest(&mut self, manifest: &FfiManifest) -> Result<(), String> {
49 self.linker_flags.extend(manifest.linker_flags());
51
52 for func in manifest.functions() {
54 let effect = func.effect()?;
55 let info = FfiFunctionInfo {
56 c_name: func.c_name.clone(),
57 seq_name: func.seq_name.clone(),
58 effect,
59 args: func.args.clone(),
60 return_spec: func.return_spec.clone(),
61 };
62
63 if self.functions.contains_key(&func.seq_name) {
64 return Err(format!(
65 "FFI function '{}' is already defined",
66 func.seq_name
67 ));
68 }
69
70 self.functions.insert(func.seq_name.clone(), info);
71 }
72
73 Ok(())
74 }
75
76 pub fn is_ffi_function(&self, name: &str) -> bool {
78 self.functions.contains_key(name)
79 }
80
81 pub fn function_names(&self) -> Vec<&str> {
83 self.functions.keys().map(|s| s.as_str()).collect()
84 }
85}
86
87impl Default for FfiBindings {
88 fn default() -> Self {
89 Self::new()
90 }
91}