use std::marker::PhantomData; use mlua::{FromLua, IntoLua, LuaSerdeExt}; use serde::Serialize; #[derive(Debug, Clone)] struct Internal { value: mlua::Value, lua: mlua::Lua, } #[derive(Debug, Clone)] pub struct ActionCallback { internal: Option, _this: PhantomData, _state: PhantomData, } impl Default for ActionCallback { fn default() -> Self { Self { internal: None, _this: PhantomData::, _state: PhantomData::, } } } impl FromLua for ActionCallback { fn from_lua(value: mlua::Value, lua: &mlua::Lua) -> mlua::Result { Ok(ActionCallback { internal: Some(Internal { value, lua: lua.clone(), }), _this: PhantomData::, _state: PhantomData::, }) } } // TODO: Return proper error here impl ActionCallback where T: IntoLua + Sync + Send + Clone + 'static, S: Serialize, { pub async fn call(&self, this: &T, state: &S) { let Some(internal) = self.internal.as_ref() else { return; }; let state = internal.lua.to_value(state).unwrap(); match &internal.value { mlua::Value::Function(f) => f.call_async::<()>((this.clone(), state)).await.unwrap(), _ => todo!("Only functions are currently supported"), } } pub fn is_set(&self) -> bool { self.internal.is_some() } }