Skip to main content

mlua/userdata/
object.rs

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