use crate::{
actors::user_engine::{
error::{Error, UserEngineResult},
UserEngine,
},
userscript_api::include::{LuaFunction, LuaString},
};
use kameo::message::{Context, Message};
pub struct RegisterUserEngine {
name: String,
spec: LuaFunction,
}
impl Message<RegisterUserEngine> for UserEngine {
type Reply = ();
async fn handle(
&mut self,
msg: RegisterUserEngine,
_: Context<'_, Self, Self::Reply>,
) -> Self::Reply {
self.engines.insert(msg.name, msg.spec);
}
}
impl RegisterUserEngine {
#[must_use]
pub fn using(name: String, spec: LuaFunction) -> Self {
Self { name, spec }
}
}
pub struct ScanBytes(Vec<u8>);
impl Message<ScanBytes> for UserEngine {
type Reply = UserEngineResult<Vec<String>>;
async fn handle(&mut self, msg: ScanBytes, _: Context<'_, Self, Self::Reply>) -> Self::Reply {
if let Some(_vm_guard) = self.lua_vm.upgrade() {
let mut results: Vec<String> = Vec::with_capacity(1024);
for (name, spec) in &self.engines {
let bytestring = LuaString::wrap(msg.0.as_slice());
let result: UserEngineResult<bool> = spec
.call_async(bytestring)
.await
.map_err(|err: mlua::Error| Error::engine_invocation(name.clone(), err));
if result? {
results.push(name.clone());
}
}
Ok(results)
} else {
Err(Error::NoLuaVm)
}
}
}
impl From<Vec<u8>> for ScanBytes {
fn from(value: Vec<u8>) -> Self {
Self(value)
}
}