Skip to main content

mlua_extras/typed/class/
wrapped.rs

1use mlua::{
2    AnyUserData, FromLua, FromLuaMulti, IntoLua, IntoLuaMulti, Lua, UserData,
3    UserDataFields, UserDataMethods,
4};
5#[cfg(feature = "async")]
6use mlua::{UserDataRef, UserDataRefMut};
7use crate::{MaybeSend, typed::IntoDocComment};
8
9use super::{Type, Typed, TypedDataFields, TypedDataMethods, TypedMultiValue};
10
11/// Wrapper around a [`UserDataFields`] and [`UserDataMethods`]
12/// to allow [`TypedUserData`](super::TypedUserData) implementations to be used for [`mlua::UserData`]
13/// implementations
14pub struct WrappedBuilder<'ctx, U>(&'ctx mut U);
15impl<'ctx, U> WrappedBuilder<'ctx, U> {
16    pub fn new(u: &'ctx mut U) -> Self {
17        WrappedBuilder(u)
18    }
19}
20
21impl<'ctx, T: UserData, U: UserDataFields<T>> TypedDataFields<T> for WrappedBuilder<'ctx, U> {
22    fn document(&mut self, _doc: impl IntoDocComment) -> &mut Self {
23        self
24    }
25
26    fn coerce(&mut self, _ty: impl Into<Type>) -> &mut Self {
27        self
28    }
29
30    fn add_field<V>(&mut self, name: impl Into<String>, value: V)
31    where
32        V: IntoLua + Clone + 'static + Typed,
33    {
34        self.0.add_field(name, value)
35    }
36
37    fn add_field_function_set<S, A, F>(&mut self, name: S, function: F)
38    where
39        S: Into<String>,
40        A: FromLua + Typed,
41        F: FnMut(&Lua, AnyUserData, A) -> mlua::Result<()> + MaybeSend + 'static,
42    {
43        self.0.add_field_function_set(name, function)
44    }
45
46    fn add_field_function_get<S, R, F>(&mut self, name: S, function: F)
47    where
48        S: Into<String>,
49        R: IntoLua + Typed,
50        F: Fn(&Lua, AnyUserData) -> mlua::Result<R> + MaybeSend + 'static,
51    {
52        self.0.add_field_function_get(name, function)
53    }
54
55    fn add_field_function_get_set<S, R, A, GET, SET>(&mut self, name: S, get: GET, set: SET)
56    where
57        S: Into<String>,
58        R: IntoLua + Typed,
59        A: FromLua + Typed,
60        GET: Fn(&Lua, AnyUserData) -> mlua::Result<R> + MaybeSend + 'static,
61        SET: Fn(&Lua, AnyUserData, A) -> mlua::Result<()> + MaybeSend + 'static,
62    {
63        let name: String = name.into();
64        self.0.add_field_function_get(&name, get);
65        self.0.add_field_function_set(name, set);
66    }
67
68    fn add_field_method_set<S, A, M>(&mut self, name: S, method: M)
69    where
70        S: Into<String>,
71        A: FromLua + Typed,
72        M: FnMut(&Lua, &mut T, A) -> mlua::Result<()> + MaybeSend + 'static,
73    {
74        self.0.add_field_method_set(name, method)
75    }
76
77    fn add_field_method_get<S, R, M>(&mut self, name: S, method: M)
78    where
79        S: Into<String>,
80        R: IntoLua + Typed,
81        M: Fn(&Lua, &T) -> mlua::Result<R> + MaybeSend + 'static,
82    {
83        self.0.add_field_method_get(name, method)
84    }
85
86    fn add_field_method_get_set<S, R, A, GET, SET>(&mut self, name: S, get: GET, set: SET)
87    where
88        S: Into<String>,
89        R: IntoLua + Typed,
90        A: FromLua + Typed,
91        GET: Fn(&Lua, &T) -> mlua::Result<R> + MaybeSend + 'static,
92        SET: Fn(&Lua, &mut T, A) -> mlua::Result<()> + MaybeSend + 'static,
93    {
94        let name: String = name.into();
95        self.0.add_field_method_get(&name, get);
96        self.0.add_field_method_set(name, set);
97    }
98
99    fn add_meta_field<V>(&mut self, meta: impl Into<String>, value: V)
100    where
101        V: IntoLua + 'static,
102    {
103        self.0.add_meta_field(meta, value)
104    }
105
106    fn add_meta_field_with<R, F>(&mut self, name: impl Into<String>, f: F)
107        where
108            F: 'static + MaybeSend + Fn(&Lua) -> mlua::Result<R>,
109            R: IntoLua + 'static {
110        self.0.add_meta_field_with(name, f);
111    }
112}
113
114impl<'ctx, T: UserData, U: UserDataMethods<T>> TypedDataMethods<T> for WrappedBuilder<'ctx, U> {
115    fn document(&mut self, _documentation: impl IntoDocComment) -> &mut Self {
116        self
117    }
118
119    fn param(
120        &mut self,
121        _name: impl std::fmt::Display,
122        _doc: impl IntoDocComment,
123    ) -> &mut Self {
124        self
125    }
126    
127    fn param_as(
128        &mut self,
129        _ty: impl Into<Type>,
130        _name: impl std::fmt::Display,
131        _doc: impl IntoDocComment,
132    ) -> &mut Self {
133        self
134    }
135
136
137    fn ret(&mut self, _: impl IntoDocComment) -> &mut Self {
138        self
139    }
140    
141    fn ret_as(&mut self, _: impl Into<Type>, _: impl IntoDocComment) -> &mut Self {
142        self
143    }
144
145    fn index<I: Typed>(&mut self, _idx: isize, _doc: impl IntoDocComment) -> &mut Self {
146        self
147    }
148
149    fn index_as(&mut self, _idx: isize, _ty: impl Into<Type>, _doc: impl IntoDocComment) -> &mut Self {
150        self
151    }
152
153    fn add_method<S, A, R, M>(&mut self, name: S, method: M)
154    where
155        S: Into<String>,
156        A: FromLuaMulti + TypedMultiValue,
157        R: IntoLuaMulti + TypedMultiValue,
158        M: Fn(&Lua, &T, A) -> mlua::Result<R> + MaybeSend + 'static,
159    {
160        self.0.add_method(name, method)
161    }
162
163    fn add_function<S, A, R, F>(&mut self, name: S, function: F)
164    where
165        S: Into<String>,
166        A: FromLuaMulti + TypedMultiValue,
167        R: IntoLuaMulti + TypedMultiValue,
168        F: Fn(&Lua, A) -> mlua::Result<R> + MaybeSend + 'static,
169    {
170        self.0.add_function(name, function)
171    }
172
173    fn add_method_mut<S, A, R, M>(&mut self, name: S, method: M)
174    where
175        S: Into<String>,
176        A: FromLuaMulti + TypedMultiValue,
177        R: IntoLuaMulti + TypedMultiValue,
178        M: FnMut(&Lua, &mut T, A) -> mlua::Result<R> + MaybeSend + 'static,
179    {
180        self.0.add_method_mut(name, method)
181    }
182
183    fn add_meta_method<A, R, M>(&mut self, meta: impl Into<String>, method: M)
184    where
185        A: FromLuaMulti + TypedMultiValue,
186        R: IntoLuaMulti + TypedMultiValue,
187        M: 'static + MaybeSend + Fn(&Lua, &T, A) -> mlua::Result<R>,
188    {
189        self.0.add_meta_method(meta, method)
190    }
191
192    #[cfg(feature = "async")]
193    fn add_async_method<S: Into<String>, A, R, M, MR>(&mut self, name: S, method: M)
194    where
195        T: 'static,
196        M: Fn(Lua, UserDataRef<T>, A) -> MR + MaybeSend + 'static,
197        A: FromLuaMulti + TypedMultiValue,
198        MR: std::future::Future<Output = mlua::Result<R>> + MaybeSend + 'static,
199        R: IntoLuaMulti + TypedMultiValue,
200    {
201        self.0.add_async_method(name, method)
202    }
203
204    #[cfg(feature = "async")]
205    fn add_async_method_mut<S: Into<String>, A, R, M, MR>(&mut self, name: S, method: M)
206    where
207        T: 'static,
208        M: Fn(Lua, UserDataRefMut<T>, A) -> MR + MaybeSend + 'static,
209        A: FromLuaMulti + TypedMultiValue,
210        MR: std::future::Future<Output = mlua::Result<R>> + MaybeSend + 'static,
211        R: IntoLuaMulti + TypedMultiValue,
212    {
213        self.0.add_async_method_mut(name, method)
214    }
215
216    fn add_function_mut<S, A, R, F>(&mut self, name: S, function: F)
217    where
218        S: Into<String>,
219        A: FromLuaMulti + TypedMultiValue,
220        R: IntoLuaMulti + TypedMultiValue,
221        F: FnMut(&Lua, A) -> mlua::Result<R> + MaybeSend + 'static,
222    {
223        self.0.add_function_mut(name, function)
224    }
225
226    fn add_meta_function<A, R, F>(&mut self, meta: impl Into<String>, function: F)
227    where
228        A: FromLuaMulti + TypedMultiValue,
229        R: IntoLuaMulti + TypedMultiValue,
230        F: Fn(&Lua, A) -> mlua::Result<R> + MaybeSend + 'static,
231    {
232        self.0.add_meta_function(meta, function)
233    }
234
235    #[cfg(feature = "async")]
236    fn add_async_function<S, A, R, F, FR>(&mut self, name: S, function: F)
237    where
238        S: Into<String>,
239        A: FromLuaMulti + TypedMultiValue,
240        R: IntoLuaMulti + TypedMultiValue,
241        F: 'static + MaybeSend + Fn(Lua, A) -> FR,
242        FR: 'static + MaybeSend + std::future::Future<Output = mlua::Result<R>>,
243    {
244        self.0.add_async_function(name, function)
245    }
246
247    fn add_meta_method_mut<A, R, M>(&mut self, meta: impl Into<String>, method: M)
248    where
249        A: FromLuaMulti + TypedMultiValue,
250        R: IntoLuaMulti + TypedMultiValue,
251        M: 'static + MaybeSend + FnMut(&Lua, &mut T, A) -> mlua::Result<R>,
252    {
253        self.0.add_meta_method_mut(meta, method)
254    }
255    
256    fn add_meta_function_mut<A, R, F>(&mut self, meta: impl Into<String>, function: F)
257    where
258        A: FromLuaMulti + TypedMultiValue,
259        R: IntoLuaMulti + TypedMultiValue,
260        F: FnMut(&Lua, A) -> mlua::Result<R> + MaybeSend + 'static,
261    {
262        self.0.add_meta_function_mut(meta, function)
263    }
264}
265
266#[cfg(test)]
267#[cfg(all(feature = "async", feature = "macros"))]
268mod tests {
269    use super::*;
270    use crate as mlua_extras;
271    use crate::typed::TypedUserData;
272    use crate::{Typed, UserData};
273
274    #[derive(Clone, Typed, UserData)]
275    struct Counter {
276        value: i64,
277    }
278
279    impl TypedUserData for Counter {
280        fn add_methods<T: TypedDataMethods<Self>>(methods: &mut T) {
281            methods.add_async_method("get_value", |_lua, this, _: ()| async move {
282                Ok(this.value)
283            });
284        }
285    }
286
287    #[test]
288    fn test_add_async_method_compiles() {
289        let lua = Lua::new();
290        lua.globals()
291            .set("counter", Counter { value: 42 })
292            .unwrap();
293    }
294}