use crate::lang::TypeId;
use crate::pass::Outcome::Unchanged;
use crate::pass::{ModelResult, PassInfo, model};
use crate::try_resolve;
use interoptopus::inventory::{Functions, Types};
use interoptopus::lang::types::TypeKind;
use std::collections::HashMap;
#[derive(Default)]
pub struct Config {}
#[derive(Clone, Debug)]
pub struct VecHelpers {
pub create_entry_point: String,
pub destroy_entry_point: String,
}
pub struct Pass {
info: PassInfo,
helpers: HashMap<TypeId, VecHelpers>,
}
impl Pass {
#[must_use]
pub fn new(_: Config) -> Self {
Self { info: PassInfo { name: file!() }, helpers: HashMap::default() }
}
pub fn process(&mut self, pass_meta: &mut crate::pass::PassMeta, id_map: &model::common::id_map::Pass, rs_functions: &Functions, rs_types: &Types) -> ModelResult {
let mut outcome = Unchanged;
let mut creates: HashMap<interoptopus::inventory::TypeId, String> = HashMap::new();
let mut destroys: HashMap<interoptopus::inventory::TypeId, String> = HashMap::new();
for rust_fn in rs_functions.values() {
if rust_fn.name.starts_with("interoptopus_vec_create") {
if let Some(last_arg) = rust_fn.signature.arguments.last()
&& let Some(ty) = rs_types.get(&last_arg.ty)
&& let TypeKind::ReadWritePointer(inner_id) = &ty.kind
{
creates.insert(*inner_id, rust_fn.name.clone());
}
} else if rust_fn.name.starts_with("interoptopus_vec_destroy")
&& let Some(first_arg) = rust_fn.signature.arguments.first()
{
destroys.insert(first_arg.ty, rust_fn.name.clone());
}
}
for (rust_vec_id, destroy_name) in &destroys {
let cs_vec_id = try_resolve!(id_map.ty(*rust_vec_id), pass_meta, self.info, crate::pass::MissingItem::RustType(*rust_vec_id));
if self.helpers.contains_key(&cs_vec_id) {
continue;
}
let Some(create_name) = creates.get(rust_vec_id) else {
continue;
};
self.helpers
.insert(cs_vec_id, VecHelpers { create_entry_point: create_name.clone(), destroy_entry_point: destroy_name.clone() });
outcome.changed();
}
Ok(outcome)
}
#[must_use]
pub fn helpers(&self, cs_vec_id: TypeId) -> Option<&VecHelpers> {
self.helpers.get(&cs_vec_id)
}
pub fn iter(&self) -> impl Iterator<Item = (&TypeId, &VecHelpers)> {
self.helpers.iter()
}
}