use crate::Function; use crate::error::{Error, Result}; use crate::state::WeakLua; use crate::table::Table; use crate::traits::{FromLua, FromLuaMulti, IntoLua, IntoLuaMulti, ObjectLike}; use crate::userdata::AnyUserData; use crate::value::Value; #[cfg(feature = "async")] use crate::function::AsyncCallFuture; impl ObjectLike for AnyUserData { #[inline] fn get(&self, key: impl IntoLua) -> Result { // `lua_gettable` method used under the hood can work with any Lua value // that has `__index` metamethod Table(self.0.clone()).get_protected(key) } #[inline] fn set(&self, key: impl IntoLua, value: impl IntoLua) -> Result<()> { // `lua_settable` method used under the hood can work with any Lua value // that has `__newindex` metamethod Table(self.0.clone()).set_protected(key, value) } #[inline] fn call(&self, args: impl IntoLuaMulti) -> Result where R: FromLuaMulti, { Function(self.0.clone()).call(args) } #[cfg(feature = "async")] #[inline] fn call_async(&self, args: impl IntoLuaMulti) -> AsyncCallFuture where R: FromLuaMulti, { Function(self.0.clone()).call_async(args) } #[inline] fn call_method(&self, name: &str, args: impl IntoLuaMulti) -> Result where R: FromLuaMulti, { self.call_function(name, (self, args)) } #[cfg(feature = "async")] fn call_async_method(&self, name: &str, args: impl IntoLuaMulti) -> AsyncCallFuture where R: FromLuaMulti, { self.call_async_function(name, (self, args)) } fn call_function(&self, name: &str, args: impl IntoLuaMulti) -> Result where R: FromLuaMulti, { match self.get(name)? { Value::Function(func) => func.call(args), val => { let msg = format!("attempt to call a {} value (function '{name}')", val.type_name()); Err(Error::RuntimeError(msg)) } } } #[cfg(feature = "async")] fn call_async_function(&self, name: &str, args: impl IntoLuaMulti) -> AsyncCallFuture where R: FromLuaMulti, { match self.get(name) { Ok(Value::Function(func)) => func.call_async(args), Ok(val) => { let msg = format!("attempt to call a {} value (function '{name}')", val.type_name()); AsyncCallFuture::error(Error::RuntimeError(msg)) } Err(err) => AsyncCallFuture::error(err), } } #[inline] fn to_string(&self) -> Result { Value::UserData(self.clone()).to_string() } #[inline] fn to_value(&self) -> Value { Value::UserData(self.clone()) } #[inline] fn weak_lua(&self) -> &WeakLua { &self.0.lua } }