pub const SCALAR_EXPORT: &str = "invoke";
pub const AGG_INIT: &str = "agg_init";
pub const AGG_ACCUMULATE: &str = "agg_accumulate";
pub const AGG_MERGE: &str = "agg_merge";
pub const AGG_FINALIZE: &str = "agg_finalize";
pub fn validate_scalar_exports(module: &wasmtime::Module, func_name: &str) -> crate::Result<()> {
let has_named = module
.exports()
.any(|e| e.name() == func_name && e.ty().func().is_some());
let has_invoke = module
.exports()
.any(|e| e.name() == SCALAR_EXPORT && e.ty().func().is_some());
if !has_named && !has_invoke {
return Err(crate::Error::BadRequest {
detail: format!("WASM module must export function '{func_name}' or '{SCALAR_EXPORT}'"),
});
}
Ok(())
}
pub fn validate_aggregate_exports(module: &wasmtime::Module) -> crate::Result<()> {
for name in [AGG_INIT, AGG_ACCUMULATE, AGG_MERGE, AGG_FINALIZE] {
let has_export = module
.exports()
.any(|e| e.name() == name && e.ty().func().is_some());
if !has_export {
return Err(crate::Error::BadRequest {
detail: format!("WASM aggregate module must export function '{name}'"),
});
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn export_names_are_consistent() {
assert_eq!(SCALAR_EXPORT, "invoke");
assert_eq!(AGG_INIT, "agg_init");
assert_eq!(AGG_ACCUMULATE, "agg_accumulate");
assert_eq!(AGG_MERGE, "agg_merge");
assert_eq!(AGG_FINALIZE, "agg_finalize");
}
}