use std::collections::HashMap;
use crate::types::Effect;
use super::manifest::{FfiArg, FfiManifest, FfiReturn};
#[derive(Debug, Clone)]
pub struct FfiBindings {
pub functions: HashMap<String, FfiFunctionInfo>,
pub linker_flags: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct FfiFunctionInfo {
pub c_name: String,
pub seq_name: String,
pub effect: Effect,
pub args: Vec<FfiArg>,
pub return_spec: Option<FfiReturn>,
}
impl FfiBindings {
pub fn new() -> Self {
FfiBindings {
functions: HashMap::new(),
linker_flags: Vec::new(),
}
}
pub fn add_manifest(&mut self, manifest: &FfiManifest) -> Result<(), String> {
self.linker_flags.extend(manifest.linker_flags());
for func in manifest.functions() {
let effect = func.effect()?;
let info = FfiFunctionInfo {
c_name: func.c_name.clone(),
seq_name: func.seq_name.clone(),
effect,
args: func.args.clone(),
return_spec: func.return_spec.clone(),
};
if self.functions.contains_key(&func.seq_name) {
return Err(format!(
"FFI function '{}' is already defined",
func.seq_name
));
}
self.functions.insert(func.seq_name.clone(), info);
}
Ok(())
}
pub fn is_ffi_function(&self, name: &str) -> bool {
self.functions.contains_key(name)
}
pub fn function_names(&self) -> Vec<&str> {
self.functions.keys().map(|s| s.as_str()).collect()
}
}
impl Default for FfiBindings {
fn default() -> Self {
Self::new()
}
}