mlua_codemp_patch/userdata/
object.rs

1use std::string::String as StdString;
2
3use crate::error::{Error, Result};
4use crate::table::Table;
5use crate::traits::ObjectLike;
6use crate::userdata::AnyUserData;
7use crate::value::{FromLua, FromLuaMulti, IntoLua, IntoLuaMulti, Value};
8use crate::Function;
9
10#[cfg(feature = "async")]
11use futures_util::future::{self, Either, Future};
12
13impl ObjectLike for AnyUserData {
14    #[inline]
15    fn get<V: FromLua>(&self, key: impl IntoLua) -> Result<V> {
16        // `lua_gettable` method used under the hood can work with any Lua value
17        // that has `__index` metamethod
18        Table(self.0.copy()).get_protected(key)
19    }
20
21    #[inline]
22    fn set(&self, key: impl IntoLua, value: impl IntoLua) -> Result<()> {
23        // `lua_settable` method used under the hood can work with any Lua value
24        // that has `__newindex` metamethod
25        Table(self.0.copy()).set_protected(key, value)
26    }
27
28    #[inline]
29    fn call<R>(&self, args: impl IntoLuaMulti) -> Result<R>
30    where
31        R: FromLuaMulti,
32    {
33        Function(self.0.copy()).call(args)
34    }
35
36    #[cfg(feature = "async")]
37    #[inline]
38    fn call_async<R>(&self, args: impl IntoLuaMulti) -> impl Future<Output = Result<R>>
39    where
40        R: FromLuaMulti,
41    {
42        Function(self.0.copy()).call_async(args)
43    }
44
45    #[inline]
46    fn call_method<R>(&self, name: &str, args: impl IntoLuaMulti) -> Result<R>
47    where
48        R: FromLuaMulti,
49    {
50        self.call_function(name, (self, args))
51    }
52
53    #[cfg(feature = "async")]
54    fn call_async_method<R>(&self, name: &str, args: impl IntoLuaMulti) -> impl Future<Output = Result<R>>
55    where
56        R: FromLuaMulti,
57    {
58        self.call_async_function(name, (self, args))
59    }
60
61    fn call_function<R>(&self, name: &str, args: impl IntoLuaMulti) -> Result<R>
62    where
63        R: FromLuaMulti,
64    {
65        match self.get(name)? {
66            Value::Function(func) => func.call(args),
67            val => {
68                let msg = format!("attempt to call a {} value (function '{name}')", val.type_name());
69                Err(Error::RuntimeError(msg))
70            }
71        }
72    }
73
74    #[cfg(feature = "async")]
75    fn call_async_function<R>(&self, name: &str, args: impl IntoLuaMulti) -> impl Future<Output = Result<R>>
76    where
77        R: FromLuaMulti,
78    {
79        match self.get(name) {
80            Ok(Value::Function(func)) => Either::Left(func.call_async(args)),
81            Ok(val) => {
82                let msg = format!("attempt to call a {} value (function '{name}')", val.type_name());
83                Either::Right(future::ready(Err(Error::RuntimeError(msg))))
84            }
85            Err(err) => Either::Right(future::ready(Err(err))),
86        }
87    }
88
89    #[inline]
90    fn to_string(&self) -> Result<StdString> {
91        Value::UserData(AnyUserData(self.0.copy(), self.1)).to_string()
92    }
93}