use crate::BaseDocument;
use bliss_traits::events::DomEvent;
#[derive(Debug, Clone)]
pub enum ScriptValue {
Null,
Bool(bool),
Number(f64),
String(String),
Object(Vec<(String, ScriptValue)>),
Promise(u64), }
#[derive(Debug, Clone)]
pub enum ScriptError {
ParseError(String),
RuntimeError(String),
CapabilityDenied { operation: String, reason: String },
Timeout,
MemoryLimitExceeded,
UnsupportedLanguage(String),
}
pub enum EventHandled {
Handled, Propagate, }
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ScriptLanguage {
JavaScript,
TypeScript,
Lua,
Python,
Casm, }
impl std::fmt::Display for ScriptLanguage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ScriptLanguage::JavaScript => write!(f, "javascript"),
ScriptLanguage::TypeScript => write!(f, "typescript"),
ScriptLanguage::Lua => write!(f, "lua"),
ScriptLanguage::Python => write!(f, "python"),
ScriptLanguage::Casm => write!(f, "casm"),
}
}
}
#[derive(Debug, Clone)]
pub struct ExecutionContext {
pub source_url: Option<String>,
pub line_number: u32,
pub is_module: bool,
}
impl Default for ExecutionContext {
fn default() -> Self {
Self {
source_url: None,
line_number: 1,
is_module: false,
}
}
}
pub type ScriptErrorCallback = Box<dyn Fn(&ScriptError) + Send + Sync>;
pub trait ScriptEngine: Send {
fn init(&mut self, document: &mut BaseDocument);
fn execute(
&mut self,
code: &str,
language: ScriptLanguage,
context: &ExecutionContext,
) -> Result<ScriptValue, ScriptError>;
fn handle_event(&mut self, event: &DomEvent) -> EventHandled;
fn tick(&mut self) -> Result<bool, ScriptError>;
fn set_error_handler(&mut self, callback: Option<ScriptErrorCallback>);
}
pub struct NoopScriptEngine;
impl ScriptEngine for NoopScriptEngine {
fn init(&mut self, _document: &mut BaseDocument) {}
fn execute(
&mut self,
_code: &str,
language: ScriptLanguage,
_context: &ExecutionContext,
) -> Result<ScriptValue, ScriptError> {
Err(ScriptError::UnsupportedLanguage(language.to_string()))
}
fn handle_event(&mut self, _event: &DomEvent) -> EventHandled {
EventHandled::Propagate
}
fn tick(&mut self) -> Result<bool, ScriptError> {
Ok(false)
}
fn set_error_handler(&mut self, _callback: Option<ScriptErrorCallback>) {}
}
pub type BoxedScriptEngine = Box<dyn ScriptEngine>;