#[cfg(feature = "js")]
pub mod boa;
pub mod python;
pub mod rhai;
use crate::core::{Result, Value};
use std::collections::HashMap;
use std::sync::Arc;
pub trait ScriptingBackend {
fn name(&self) -> &'static str;
fn supported_languages(&self) -> &[&'static str];
fn execute(&self, code: &str, args: &[Value], param_names: &[&str]) -> Result<Value>;
fn validate_code(&self, code: &str) -> Result<()>;
}
pub fn create_backend_registry() -> BackendRegistry {
let mut registry = BackendRegistry::new();
registry.register_backend(Arc::new(rhai::RhaiBackend::new()));
#[cfg(feature = "js")]
registry.register_backend(Arc::new(boa::BoaBackend::new()));
#[cfg(feature = "python")]
registry.register_backend(Arc::new(python::PythonBackend::new()));
registry
}
pub struct BackendRegistry {
backends: HashMap<String, Arc<dyn ScriptingBackend + Send + Sync>>,
}
impl BackendRegistry {
pub fn new() -> Self {
Self {
backends: HashMap::new(),
}
}
pub fn register_backend(&mut self, backend: Arc<dyn ScriptingBackend + Send + Sync>) {
for &lang in backend.supported_languages() {
self.backends.insert(lang.to_lowercase(), backend.clone());
}
}
pub fn get_backend(&self, language: &str) -> Option<&Arc<dyn ScriptingBackend + Send + Sync>> {
self.backends.get(&language.to_lowercase())
}
pub fn is_language_supported(&self, language: &str) -> bool {
self.backends.contains_key(&language.to_lowercase())
}
pub fn list_supported_languages(&self) -> Vec<String> {
self.backends.keys().cloned().collect()
}
}
impl Default for BackendRegistry {
fn default() -> Self {
Self::new()
}
}