use std::sync::{Arc, OnceLock};
static JSC_POOL: OnceLock<Arc<dyn JscBridge + Send + Sync>> = OnceLock::new();
pub trait JscBridge: Send + Sync {
fn render_page(&self, props_json: String) -> Result<String, String>;
fn render_component(&self, component_id: String, props_json: String) -> Result<String, String>;
}
pub fn set_jsc_bridge(bridge: Arc<dyn JscBridge + Send + Sync>) {
let _ = JSC_POOL.set(bridge);
}
pub fn has_jsc_bridge() -> bool {
JSC_POOL.get().is_some()
}
pub fn jsc_render(props_json: &str) -> String {
match JSC_POOL.get() {
Some(pool) => match pool.render_page(props_json.to_string()) {
Ok(html) => html,
Err(e) => format!("<div style=\"color:red\">JSC render error: {}</div>", e),
},
None => "<div style=\"color:red\">JSC pool not available. \
Configure [render] bundle_path in bext.config.toml</div>"
.to_string(),
}
}
pub fn jsc_render_component(component_id: &str, props_json: &str) -> String {
match JSC_POOL.get() {
Some(pool) => match pool.render_component(component_id.to_string(), props_json.to_string())
{
Ok(html) => html,
Err(e) => format!("<div style=\"color:red\">JSC component error: {}</div>", e),
},
None => "<div style=\"color:red\">JSC pool not available</div>".into(),
}
}
static PHP_POOL: OnceLock<Arc<dyn PhpBridge + Send + Sync>> = OnceLock::new();
pub trait PhpBridge: Send + Sync {
fn call(&self, method: &str, uri: &str, body: Option<&str>) -> Result<PhpCallResult, String>;
}
#[derive(Debug, Clone)]
pub struct PhpCallResult {
pub status: u16,
pub body: String,
pub content_type: String,
}
pub fn set_php_bridge(bridge: Arc<dyn PhpBridge + Send + Sync>) {
let _ = PHP_POOL.set(bridge);
}
pub fn has_php_bridge() -> bool {
PHP_POOL.get().is_some()
}
pub fn php_call(method: &str, uri: &str, body: Option<&str>) -> Result<PhpCallResult, String> {
match PHP_POOL.get() {
Some(pool) => pool.call(method, uri, body),
None => Err("PHP pool not available".into()),
}
}