mlua/userdata/
object.rs

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