Skip to main content

reifydb_engine/procedure/
wasm_loader.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (c) 2025 ReifyDB
3
4//! WASM procedure loader — scans a directory for `.wasm` files and builds a procedure registry
5
6use std::{fs, path::Path};
7
8use reifydb_sdk::error::FFIError;
9use reifydb_type::Result;
10
11use super::{
12	registry::{Procedures, ProceduresBuilder},
13	wasm::WasmProcedure,
14};
15
16/// Scan a directory for `.wasm` files, read each one, and return a `Procedures`
17/// registry with factory functions that create `WasmProcedure` instances.
18///
19/// The procedure name is derived from the file stem (e.g. `my_proc.wasm` → `"my_proc"`).
20pub fn load_wasm_procedures_from_dir(dir: &Path) -> Result<Procedures> {
21	Ok(register_wasm_procedures_from_dir(dir, Procedures::builder())?.build())
22}
23
24/// Scan a directory for `.wasm` files and register each as a `WasmProcedure` into the given
25/// `ProceduresBuilder`, returning the updated builder.
26pub fn register_wasm_procedures_from_dir(dir: &Path, mut builder: ProceduresBuilder) -> Result<ProceduresBuilder> {
27	let entries = fs::read_dir(dir).map_err(|e| {
28		FFIError::Other(format!("Failed to read WASM procedure directory {}: {}", dir.display(), e))
29	})?;
30
31	for entry in entries {
32		let entry = entry.map_err(|e| FFIError::Other(format!("Failed to read directory entry: {}", e)))?;
33		let path = entry.path();
34
35		if path.extension().and_then(|s| s.to_str()) != Some("wasm") {
36			continue;
37		}
38
39		let name = match path.file_stem().and_then(|s| s.to_str()) {
40			Some(n) => n.to_string(),
41			None => continue,
42		};
43
44		let wasm_bytes = fs::read(&path)
45			.map_err(|e| FFIError::Other(format!("Failed to read WASM file {}: {}", path.display(), e)))?;
46
47		let name_for_closure = name.clone();
48		builder = builder.with_procedure(&name, move || {
49			WasmProcedure::new(name_for_closure.clone(), wasm_bytes.clone())
50		});
51	}
52
53	Ok(builder)
54}