1use std::{borrow::Cow, collections::BTreeMap};
2
3use mlua::{AnyUserData, FromLua, FromLuaMulti, IntoLua, IntoLuaMulti, Lua, MetaMethod};
4
5use crate::{typed::{function::Return, generator::FunctionBuilder, Func, Field}, MaybeSend};
6
7use super::{Typed, TypedDataDocumentation, TypedDataFields, TypedDataMethods, TypedMultiValue, TypedUserData};
8
9#[derive(Default, Debug, Clone, PartialEq, PartialOrd, Eq, Ord)]
11pub struct TypedClassBuilder {
12 pub type_doc: Option<Cow<'static, str>>,
13 queued_doc: Option<String>,
14
15 pub fields: BTreeMap<Cow<'static, str>, Field>,
16 pub static_fields: BTreeMap<Cow<'static, str>, Field>,
17 pub meta_fields: BTreeMap<Cow<'static, str>, Field>,
18 pub methods: BTreeMap<Cow<'static, str>, Func>,
19 pub meta_methods: BTreeMap<Cow<'static, str>, Func>,
20 pub functions: BTreeMap<Cow<'static, str>, Func>,
21 pub meta_functions: BTreeMap<Cow<'static, str>, Func>,
22}
23
24impl TypedClassBuilder {
25 pub fn new<T: TypedUserData>() -> Self {
26 let mut gen = Self::default();
27 T::add_documentation(&mut gen);
28 T::add_fields(&mut gen);
29 T::add_methods(&mut gen);
30 gen
31 }
32}
33
34impl<T: TypedUserData> TypedDataDocumentation<T> for TypedClassBuilder {
35 fn add(&mut self, doc: &str) -> &mut Self {
36 if let Some(type_doc) = self.type_doc.as_mut() {
37 *type_doc = format!("{type_doc}\n{doc}").into()
38 } else {
39 self.type_doc = Some(doc.to_string().into())
40 }
41 self
42 }
43}
44
45impl<'lua, T: TypedUserData> TypedDataFields<'lua, T> for TypedClassBuilder {
46 fn document(&mut self, doc: &str) -> &mut Self {
47 self.queued_doc = Some(doc.to_string());
48 self
49 }
50
51 fn add_field<V>(&mut self, name: impl AsRef<str>, _: V)
52 where
53 V: IntoLua<'lua> + Clone + 'static + Typed,
54 {
55 let name: Cow<'static, str> = name.as_ref().to_string().into();
56 self.static_fields
57 .entry(name)
58 .and_modify(|v| {
59 v.doc = self.queued_doc.take().map(|v| v.into());
60 v.ty = v.ty.clone() | V::ty();
61 })
62 .or_insert(Field {
63 ty: V::ty(),
64 doc: self.queued_doc.take().map(|v| v.into()),
65 });
66 }
67
68 fn add_field_function_set<S, A, F>(&mut self, name: &S, _: F)
69 where
70 S: AsRef<str> + ?Sized,
71 A: FromLua<'lua> + Typed,
72 F: 'static + MaybeSend + FnMut(&'lua Lua, AnyUserData<'lua>, A) -> mlua::Result<()>,
73 {
74 let name: Cow<'static, str> = name.as_ref().to_string().into();
75 self.static_fields
76 .entry(name)
77 .and_modify(|v| {
78 v.doc = self.queued_doc.take().map(|v| v.into());
79 v.ty = v.ty.clone() | A::ty();
80 })
81 .or_insert(Field {
82 ty: A::ty(),
83 doc: self.queued_doc.take().map(|v| v.into()),
84 });
85 }
86
87 fn add_field_function_get<S, R, F>(&mut self, name: &S, _: F)
88 where
89 S: AsRef<str> + ?Sized,
90 R: IntoLua<'lua> + Typed,
91 F: 'static + MaybeSend + Fn(&'lua Lua, AnyUserData<'lua>) -> mlua::Result<R>,
92 {
93 let name: Cow<'static, str> = name.as_ref().to_string().into();
94 self.static_fields
95 .entry(name)
96 .and_modify(|v| {
97 v.doc = self.queued_doc.take().map(|v| v.into());
98 v.ty = v.ty.clone() | R::ty();
99 })
100 .or_insert(Field {
101 ty: R::ty(),
102 doc: self.queued_doc.take().map(|v| v.into()),
103 });
104 }
105
106 fn add_field_function_get_set<S, R, A, GET, SET>(&mut self, name: &S, _: GET, _: SET)
107 where
108 S: AsRef<str> + ?Sized,
109 R: IntoLua<'lua> + Typed,
110 A: FromLua<'lua> + Typed,
111 GET: 'static + MaybeSend + Fn(&'lua Lua, AnyUserData<'lua>) -> mlua::Result<R>,
112 SET: 'static + MaybeSend + Fn(&'lua Lua, AnyUserData<'lua>, A) -> mlua::Result<()>,
113 {
114 let name: Cow<'static, str> = name.as_ref().to_string().into();
115 self.static_fields
116 .entry(name)
117 .and_modify(|v| {
118 v.doc = self.queued_doc.take().map(|v| v.into());
119 v.ty = v.ty.clone() | A::ty() | R::ty();
120 })
121 .or_insert(Field {
122 ty: A::ty() | R::ty(),
123 doc: self.queued_doc.take().map(|v| v.into()),
124 });
125 }
126
127 fn add_field_method_set<S, A, M>(&mut self, name: &S, _: M)
128 where
129 S: AsRef<str> + ?Sized,
130 A: FromLua<'lua> + Typed,
131 M: 'static + MaybeSend + FnMut(&'lua Lua, &mut T, A) -> mlua::Result<()>,
132 {
133 let name: Cow<'static, str> = name.as_ref().to_string().into();
134 self.fields
135 .entry(name)
136 .and_modify(|v| {
137 v.doc = self.queued_doc.take().map(|v| v.into());
138 v.ty = v.ty.clone() | A::ty();
139 })
140 .or_insert(Field {
141 ty: A::ty(),
142 doc: self.queued_doc.take().map(|v| v.into()),
143 });
144 }
145
146 fn add_field_method_get<S, R, M>(&mut self, name: &S, _: M)
147 where
148 S: AsRef<str> + ?Sized,
149 R: IntoLua<'lua> + Typed,
150 M: 'static + MaybeSend + Fn(&'lua Lua, &T) -> mlua::Result<R>,
151 {
152 let name: Cow<'static, str> = name.as_ref().to_string().into();
153 self.fields
154 .entry(name)
155 .and_modify(|v| {
156 v.doc = self.queued_doc.take().map(|v| v.into());
157 v.ty = v.ty.clone() | R::ty();
158 })
159 .or_insert(Field {
160 ty: R::ty(),
161 doc: self.queued_doc.take().map(|v| v.into()),
162 });
163 }
164
165 fn add_field_method_get_set<S, R, A, GET, SET>(&mut self, name: &S, _: GET, _: SET)
166 where
167 S: AsRef<str> + ?Sized,
168 R: IntoLua<'lua> + Typed,
169 A: FromLua<'lua> + Typed,
170 GET: 'static + MaybeSend + Fn(&'lua Lua, &T) -> mlua::Result<R>,
171 SET: 'static + MaybeSend + Fn(&'lua Lua, &mut T, A) -> mlua::Result<()>,
172 {
173 let name: Cow<'static, str> = name.as_ref().to_string().into();
174 self.fields
175 .entry(name)
176 .and_modify(|v| {
177 v.doc = self.queued_doc.take().map(|v| v.into());
178 v.ty = v.ty.clone() | A::ty() | R::ty();
179 })
180 .or_insert(Field {
181 ty: A::ty() | R::ty(),
182 doc: self.queued_doc.take().map(|v| v.into()),
183 });
184 }
185
186 fn add_meta_field<R, F>(&mut self, meta: MetaMethod, _: F)
187 where
188 F: 'static + MaybeSend + Fn(&'lua Lua) -> mlua::Result<R>,
189 R: IntoLua<'lua> + Typed,
190 {
191 let name: Cow<'static, str> = meta.as_ref().to_string().into();
192 self.meta_fields
193 .entry(name)
194 .and_modify(|v| {
195 v.doc = self.queued_doc.take().map(|v| v.into());
196 v.ty = v.ty.clone() | R::ty();
197 })
198 .or_insert(Field {
199 ty: R::ty(),
200 doc: self.queued_doc.take().map(|v| v.into()),
201 });
202 }
203}
204
205impl<'lua, T: TypedUserData> TypedDataMethods<'lua, T> for TypedClassBuilder {
206 fn document(&mut self, documentation: &str) -> &mut Self {
207 self.queued_doc = Some(documentation.to_string());
208 self
209 }
210
211 fn add_method<S, A, R, M>(&mut self, name: &S, _: M)
212 where
213 S: ?Sized + AsRef<str>,
214 A: FromLuaMulti<'lua> + TypedMultiValue,
215 R: IntoLuaMulti<'lua> + TypedMultiValue,
216 M: 'static + MaybeSend + Fn(&'lua Lua, &T, A) -> mlua::Result<R>,
217 {
218 let name: Cow<'static, str> = name.as_ref().to_string().into();
219 self.methods.insert(
220 name,
221 Func {
222 params: A::get_types_as_params(),
223 returns: R::get_types_as_returns(),
224 doc: self.queued_doc.take().map(|v| v.into()),
225 },
226 );
227 }
228
229 fn add_method_with<S, A, R, M, G>(&mut self, name: &S, _method: M, generator: G)
230 where
231 S: ?Sized + AsRef<str>,
232 A: FromLuaMulti<'lua> + TypedMultiValue,
233 R: IntoLuaMulti<'lua> + TypedMultiValue,
234 M: 'static + MaybeSend + Fn(&'lua Lua, &T, A) -> mlua::Result<R>,
235 G: Fn(&mut FunctionBuilder<A, R>) {
236
237 let mut builder = FunctionBuilder::<A, R>::default();
238 generator(&mut builder);
239
240 let name: Cow<'static, str> = name.as_ref().to_string().into();
241 self.methods.insert(
242 name,
243 Func {
244 params: builder.params,
245 returns: builder.returns,
246 doc: self.queued_doc.take().map(|v| v.into()),
247 },
248 );
249 }
250
251 fn add_function<S, A, R, F>(&mut self, name: &S, _: F)
252 where
253 S: ?Sized + AsRef<str>,
254 A: FromLuaMulti<'lua> + TypedMultiValue,
255 R: IntoLuaMulti<'lua> + TypedMultiValue,
256 F: 'static + MaybeSend + Fn(&'lua Lua, A) -> mlua::Result<R>,
257 {
258 let name: Cow<'static, str> = name.as_ref().to_string().into();
259 self.functions.insert(
260 name,
261 Func {
262 params: A::get_types_as_params(),
263 returns: R::get_types_as_returns(),
264 doc: self.queued_doc.take().map(|v| v.into()),
265 },
266 );
267 }
268
269 fn add_function_with<S, A, R, F, G>(&mut self, name: &S, _function: F, generator: G)
270 where
271 S: ?Sized + AsRef<str>,
272 A: FromLuaMulti<'lua> + TypedMultiValue,
273 R: IntoLuaMulti<'lua> + TypedMultiValue,
274 F: 'static + MaybeSend + Fn(&'lua Lua, A) -> mlua::Result<R>,
275 G: Fn(&mut FunctionBuilder<A, R>) {
276
277 let mut builder = FunctionBuilder::<A, R>::default();
278 generator(&mut builder);
279
280 let name: Cow<'static, str> = name.as_ref().to_string().into();
281 self.functions.insert(
282 name,
283 Func {
284 params: builder.params,
285 returns: builder.returns,
286 doc: self.queued_doc.take().map(|v| v.into()),
287 },
288 );
289 }
290
291 fn add_method_mut<S, A, R, M>(&mut self, name: &S, _: M)
292 where
293 S: ?Sized + AsRef<str>,
294 A: FromLuaMulti<'lua> + TypedMultiValue,
295 R: IntoLuaMulti<'lua> + TypedMultiValue,
296 M: 'static + MaybeSend + FnMut(&'lua Lua, &mut T, A) -> mlua::Result<R>,
297 {
298 let name: Cow<'static, str> = name.as_ref().to_string().into();
299 self.methods.insert(
300 name,
301 Func {
302 params: A::get_types_as_params(),
303 returns: R::get_types_as_returns(),
304 doc: self.queued_doc.take().map(|v| v.into()),
305 },
306 );
307 }
308
309 fn add_method_mut_with<S, A, R, M, G>(&mut self, name: &S, _method: M, generator: G)
310 where
311 S: ?Sized + AsRef<str>,
312 A: FromLuaMulti<'lua> + TypedMultiValue,
313 R: IntoLuaMulti<'lua> + TypedMultiValue,
314 M: 'static + MaybeSend + FnMut(&'lua Lua, &mut T, A) -> mlua::Result<R>,
315 G: Fn(&mut FunctionBuilder<A, R>) {
316
317 let mut builder = FunctionBuilder::<A, R>::default();
318 generator(&mut builder);
319
320 let name: Cow<'static, str> = name.as_ref().to_string().into();
321 self.methods.insert(
322 name,
323 Func {
324 params: builder.params,
325 returns: builder.returns,
326 doc: self.queued_doc.take().map(|v| v.into()),
327 },
328 );
329 }
330
331 fn add_meta_method<A, R, M>(&mut self, meta: MetaMethod, _: M)
332 where
333 A: FromLuaMulti<'lua> + TypedMultiValue,
334 R: IntoLuaMulti<'lua> + TypedMultiValue,
335 M: 'static + MaybeSend + Fn(&'lua Lua, &T, A) -> mlua::Result<R>,
336 {
337 let name: Cow<'static, str> = meta.as_ref().to_string().into();
338 self.meta_methods.insert(
339 name,
340 Func {
341 params: A::get_types_as_params(),
342 returns: R::get_types_as_returns(),
343 doc: self.queued_doc.take().map(|v| v.into()),
344 },
345 );
346 }
347
348 fn add_meta_method_with<A, R, M, G>(&mut self, meta: MetaMethod, _method: M, generator: G)
349 where
350 A: FromLuaMulti<'lua> + TypedMultiValue,
351 R: IntoLuaMulti<'lua> + TypedMultiValue,
352 M: 'static + MaybeSend + Fn(&'lua Lua, &T, A) -> mlua::Result<R>,
353 G: Fn(&mut FunctionBuilder<A, R>) {
354
355 let mut builder = FunctionBuilder::<A, R>::default();
356 generator(&mut builder);
357
358 let name: Cow<'static, str> = meta.as_ref().to_string().into();
359 self.meta_methods.insert(
360 name,
361 Func {
362 params: builder.params,
363 returns: builder.returns,
364 doc: self.queued_doc.take().map(|v| v.into()),
365 },
366 );
367 }
368
369 #[cfg(feature = "async")]
370 fn add_async_method<'s, S: ?Sized + AsRef<str>, A, R, M, MR>(&mut self, name: &S, _: M)
371 where
372 'lua: 's,
373 T: 'static,
374 M: Fn(&'lua Lua, &'s T, A) -> MR + MaybeSend + 'static,
375 A: FromLuaMulti<'lua> + TypedMultiValue,
376 MR: std::future::Future<Output = mlua::Result<R>> + 's,
377 R: IntoLuaMulti<'lua> + TypedMultiValue,
378 {
379 let name: Cow<'static, str> = name.as_ref().to_string().into();
380 self.methods.insert(
381 name,
382 Func {
383 params: A::get_types_as_params(),
384 returns: R::get_types_as_returns(),
385 doc: self.queued_doc.take().map(|v| v.into()),
386 },
387 );
388 }
389
390 #[cfg(feature = "async")]
391 fn add_async_method_with<'s, S: ?Sized + AsRef<str>, A, R, M, MR, G>(&mut self, name: &S, _method: M, generator: G)
392 where
393 'lua: 's,
394 T: 'static,
395 M: Fn(&'lua Lua, &'s T, A) -> MR + MaybeSend + 'static,
396 A: FromLuaMulti<'lua> + TypedMultiValue,
397 MR: std::future::Future<Output = mlua::Result<R>> + 's,
398 R: IntoLuaMulti<'lua> + TypedMultiValue,
399 G: Fn(&mut FunctionBuilder<A, R>) {
400
401 let mut builder = FunctionBuilder::<A, R>::default();
402 generator(&mut builder);
403
404 let name: Cow<'static, str> = name.as_ref().to_string().into();
405 self.methods.insert(
406 name,
407 Func {
408 params: builder.params,
409 returns: builder.returns,
410 doc: self.queued_doc.take().map(|v| v.into()),
411 },
412 );
413 }
414
415 #[cfg(feature = "async")]
416 fn add_async_method_mut<'s, S: ?Sized + AsRef<str>, A, R, M, MR>(&mut self, name: &S, method: M)
417 where
418 'lua: 's,
419 T: 'static,
420 M: Fn(&'lua Lua, &'s mut T, A) -> MR + MaybeSend + 'static,
421 A: FromLuaMulti<'lua> + TypedMultiValue,
422 MR: std::future::Future<Output = mlua::Result<R>> + 's,
423 R: IntoLuaMulti<'lua> + TypedMultiValue {
424
425 let name: Cow<'static, str> = name.as_ref().to_string().into();
426 self.methods.insert(
427 name,
428 Func {
429 params: A::get_types_as_params(),
430 returns: R::get_types_as_returns(),
431 doc: self.queued_doc.take().map(|v| v.into()),
432 },
433 );
434 }
435
436 #[cfg(feature = "async")]
437 fn add_async_method_mut_with<'s, S: ?Sized + AsRef<str>, A, R, M, MR, G>(&mut self, name: &S, _method: M, generator: G)
438 where
439 'lua: 's,
440 T: 'static,
441 M: Fn(&'lua Lua, &'s mut T, A) -> MR + MaybeSend + 'static,
442 A: FromLuaMulti<'lua> + TypedMultiValue,
443 MR: std::future::Future<Output = mlua::Result<R>> + 's,
444 R: IntoLuaMulti<'lua> + TypedMultiValue,
445 G: Fn(&mut FunctionBuilder<A, R>) {
446
447 let mut builder = FunctionBuilder::<A, R>::default();
448 generator(&mut builder);
449
450 let name: Cow<'static, str> = name.as_ref().to_string().into();
451 self.methods.insert(
452 name,
453 Func {
454 params: builder.params,
455 returns: builder.returns,
456 doc: self.queued_doc.take().map(|v| v.into()),
457 },
458 );
459 }
460
461 fn add_function_mut<S, A, R, F>(&mut self, name: &S, _: F)
462 where
463 S: ?Sized + AsRef<str>,
464 A: FromLuaMulti<'lua> + TypedMultiValue,
465 R: IntoLuaMulti<'lua> + TypedMultiValue,
466 F: 'static + MaybeSend + FnMut(&'lua Lua, A) -> mlua::Result<R>,
467 {
468 let name: Cow<'static, str> = name.as_ref().to_string().into();
469 self.functions.insert(
470 name,
471 Func {
472 params: A::get_types_as_params(),
473 returns: R::get_types_as_returns(),
474 doc: self.queued_doc.take().map(|v| v.into()),
475 },
476 );
477 }
478
479 fn add_function_mut_with<S, A, R, F, G>(&mut self, name: &S, _function: F, generator: G)
480 where
481 S: ?Sized + AsRef<str>,
482 A: FromLuaMulti<'lua> + TypedMultiValue,
483 R: IntoLuaMulti<'lua> + TypedMultiValue,
484 F: 'static + MaybeSend + FnMut(&'lua Lua, A) -> mlua::Result<R>,
485 G: Fn(&mut FunctionBuilder<A, R>) {
486
487 let mut builder = FunctionBuilder::<A, R>::default();
488 generator(&mut builder);
489
490 let name: Cow<'static, str> = name.as_ref().to_string().into();
491 self.functions.insert(
492 name,
493 Func {
494 params: builder.params,
495 returns: builder.returns,
496 doc: self.queued_doc.take().map(|v| v.into()),
497 },
498 );
499 }
500
501 fn add_meta_function<A, R, F>(&mut self, meta: MetaMethod, _: F)
502 where
503 A: FromLuaMulti<'lua> + TypedMultiValue,
504 R: IntoLuaMulti<'lua> + TypedMultiValue,
505 F: 'static + MaybeSend + Fn(&'lua Lua, A) -> mlua::Result<R>,
506 {
507 let name: Cow<'static, str> = meta.as_ref().to_string().into();
508 self.meta_functions.insert(
509 name,
510 Func {
511 params: A::get_types_as_params(),
512 returns: R::get_types_as_returns(),
513 doc: self.queued_doc.take().map(|v| v.into()),
514 },
515 );
516 }
517
518 fn add_meta_function_with<A, R, F, G>(&mut self, meta: MetaMethod, _function: F, generator: G)
519 where
520 A: FromLuaMulti<'lua> + TypedMultiValue,
521 R: IntoLuaMulti<'lua> + TypedMultiValue,
522 F: 'static + MaybeSend + Fn(&'lua Lua, A) -> mlua::Result<R>,
523 G: Fn(&mut FunctionBuilder<A, R>) {
524
525 let mut builder = FunctionBuilder::<A, R>::default();
526 generator(&mut builder);
527
528 let name: Cow<'static, str> = meta.as_ref().to_string().into();
529 self.functions.insert(
530 name,
531 Func {
532 params: builder.params,
533 returns: builder.returns,
534 doc: self.queued_doc.take().map(|v| v.into()),
535 },
536 );
537 }
538
539 #[cfg(feature = "async")]
540 fn add_async_function<S: ?Sized, A, R, F, FR>(&mut self, name: &S, _: F)
541 where
542 S: AsRef<str>,
543 A: FromLuaMulti<'lua> + TypedMultiValue,
544 R: IntoLuaMulti<'lua> + TypedMultiValue,
545 F: 'static + MaybeSend + Fn(&'lua Lua, A) -> FR,
546 FR: 'lua + std::future::Future<Output = mlua::Result<R>>,
547 {
548 let name: Cow<'static, str> = name.as_ref().to_string().into();
549 self.functions.insert(
550 name,
551 Func {
552 params: A::get_types_as_params(),
553 returns: R::get_types_as_returns(),
554 doc: self.queued_doc.take().map(|v| v.into()),
555 },
556 );
557 }
558
559 #[cfg(feature = "async")]
560 fn add_async_function_with<S: ?Sized, A, R, F, FR, G>(&mut self, name: &S, _function: F, generator: G)
561 where
562 S: AsRef<str>,
563 A: FromLuaMulti<'lua> + TypedMultiValue,
564 R: IntoLuaMulti<'lua> + TypedMultiValue,
565 F: 'static + MaybeSend + Fn(&'lua Lua, A) -> FR,
566 FR: 'lua + std::future::Future<Output = mlua::Result<R>>,
567 G: Fn(&mut FunctionBuilder<A, R>) {
568
569 let mut builder = FunctionBuilder::<A, R>::default();
570 generator(&mut builder);
571
572 let name: Cow<'static, str> = name.as_ref().to_string().into();
573 self.functions.insert(
574 name,
575 Func {
576 params: builder.params,
577 returns: builder.returns,
578 doc: self.queued_doc.take().map(|v| v.into()),
579 },
580 );
581 }
582
583 fn add_meta_method_mut<A, R, M>(&mut self, meta: MetaMethod, _: M)
584 where
585 A: FromLuaMulti<'lua> + TypedMultiValue,
586 R: IntoLuaMulti<'lua> + TypedMultiValue,
587 M: 'static + MaybeSend + FnMut(&'lua Lua, &mut T, A) -> mlua::Result<R>,
588 {
589 let name: Cow<'static, str> = meta.as_ref().to_string().into();
590 self.meta_methods.insert(
591 name,
592 Func {
593 params: A::get_types_as_params(),
594 returns: R::get_types_as_returns(),
595 doc: self.queued_doc.take().map(|v| v.into()),
596 },
597 );
598 }
599
600 fn add_meta_method_mut_with<A, R, M, G>(&mut self, meta: MetaMethod, _method: M, generator: G)
601 where
602 A: FromLuaMulti<'lua> + TypedMultiValue,
603 R: IntoLuaMulti<'lua> + TypedMultiValue,
604 M: 'static + MaybeSend + FnMut(&'lua Lua, &mut T, A) -> mlua::Result<R>,
605 G: Fn(&mut FunctionBuilder<A, R>) {
606
607 let mut builder = FunctionBuilder::<A, R>::default();
608 generator(&mut builder);
609
610 let name: Cow<'static, str> = meta.as_ref().to_string().into();
611 self.meta_methods.insert(
612 name,
613 Func {
614 params: builder.params,
615 returns: builder.returns,
616 doc: self.queued_doc.take().map(|v| v.into()),
617 },
618 );
619 }
620
621 fn add_meta_function_mut<A, R, F>(&mut self, meta: MetaMethod, _: F)
622 where
623 A: FromLuaMulti<'lua> + TypedMultiValue,
624 R: IntoLuaMulti<'lua> + TypedMultiValue,
625 F: 'static + MaybeSend + FnMut(&'lua Lua, A) -> mlua::Result<R>,
626 {
627 let name: Cow<'static, str> = meta.as_ref().to_string().into();
628 self.meta_functions.insert(
629 name,
630 Func {
631 params: A::get_types_as_params(),
632 returns: R::get_types().into_iter().map(|ty| Return { doc: None, ty }).collect(),
633 doc: self.queued_doc.take().map(|v| v.into()),
634 },
635 );
636 }
637
638 fn add_meta_function_mut_with<A, R, F, G>(&mut self, meta: MetaMethod, _function: F, generator: G)
639 where
640 A: FromLuaMulti<'lua> + TypedMultiValue,
641 R: IntoLuaMulti<'lua> + TypedMultiValue,
642 F: 'static + MaybeSend + FnMut(&'lua Lua, A) -> mlua::Result<R>,
643 G: Fn(&mut FunctionBuilder<A, R>) {
644
645 let mut builder = FunctionBuilder::<A, R>::default();
646 generator(&mut builder);
647
648 let name: Cow<'static, str> = meta.as_ref().to_string().into();
649 self.meta_functions.insert(
650 name,
651 Func {
652 params: builder.params,
653 returns: builder.returns,
654 doc: self.queued_doc.take().map(|v| v.into()),
655 },
656 );
657 }
658}