1use std::{any::Any, borrow::Cow, collections::BTreeMap};
2
3use mlua::{AnyUserData, FromLua, FromLuaMulti, IntoLua, IntoLuaMulti, Lua, MetaMethod};
4
5use crate::{typed::{function::Return, generator::FunctionBuilder, Field, Func, Index, IntoDocComment, Type}, MaybeSend};
6
7use super::{Typed, TypedDataDocumentation, TypedDataFields, TypedDataMethods, TypedMultiValue, TypedUserData};
8
9#[derive(Default, Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11pub struct TypedClassBuilder {
12 pub type_doc: Option<Cow<'static, str>>,
13 queued_doc: Option<String>,
14
15 pub fields: BTreeMap<Index, Field>,
16 pub static_fields: BTreeMap<Index, Field>,
17 pub meta_fields: BTreeMap<Index, Field>,
18 pub methods: BTreeMap<Index, Func>,
19 pub meta_methods: BTreeMap<Index, Func>,
20 pub functions: BTreeMap<Index, Func>,
21 pub meta_functions: BTreeMap<Index, Func>,
22}
23
24impl From<TypedClassBuilder> for Type {
25 fn from(value: TypedClassBuilder) -> Self {
26 Type::Class(Box::new(value))
27 }
28}
29
30impl TypedClassBuilder {
31 pub fn new<T: TypedUserData>() -> Self {
32 let mut gen = Self::default();
33 T::add_documentation(&mut gen);
34 T::add_fields(&mut gen);
35 T::add_methods(&mut gen);
36 gen
37 }
38
39 pub fn is_meta_empty(&self) -> bool {
41 self.meta_fields.is_empty()
42 && self.meta_functions.is_empty()
43 && self.meta_methods.is_empty()
44 }
45
46 pub fn field(mut self, key: impl Into<Index>, ty: Type, doc: impl IntoDocComment) -> Self {
61 self.fields.insert(key.into(), Field::new(ty, doc));
62 self
63 }
64
65 pub fn function<Params, Returns>(mut self, key: impl Into<Index>, doc: impl IntoDocComment) -> Self
78 where
79 Params: TypedMultiValue,
80 Returns: TypedMultiValue,
81 {
82 self.functions.insert(key.into(), Func::new::<Params, Returns>(doc));
83 self
84 }
85
86 pub fn function_with<Params, Returns, F, R>(mut self, key: impl Into<Index>, doc: impl IntoDocComment, generator: F) -> Self
105 where
106 Params: TypedMultiValue,
107 Returns: TypedMultiValue,
108 F: Fn(&mut FunctionBuilder<Params, Returns>) -> R,
109 R: Any,
110 {
111 let mut builder = FunctionBuilder::default();
112 generator(&mut builder);
113
114 self.functions.insert(key.into(), Func {
115 params: builder.params,
116 returns: builder.returns,
117 doc: doc.into_doc_comment()
118 });
119 self
120 }
121
122 pub fn method<Params, Returns>(mut self, key: impl Into<Index>, doc: impl IntoDocComment) -> Self
138 where
139 Params: TypedMultiValue,
140 Returns: TypedMultiValue,
141 {
142 self.methods.insert(key.into(), Func::new::<Params, Returns>(doc));
143 self
144 }
145
146 pub fn method_with<Params, Returns, F, R>(mut self, key: impl Into<Index>, doc: impl IntoDocComment, generator: F) -> Self
165 where
166 Params: TypedMultiValue,
167 Returns: TypedMultiValue,
168 F: Fn(&mut FunctionBuilder<Params, Returns>) -> R,
169 R: Any,
170 {
171 let mut builder = FunctionBuilder::default();
172 generator(&mut builder);
173
174 self.methods.insert(key.into(), Func {
175 params: builder.params,
176 returns: builder.returns,
177 doc: doc.into_doc_comment()
178 });
179 self
180 }
181
182 pub fn meta_field(mut self, key: impl Into<Index>, ty: Type, doc: impl IntoDocComment) -> Self {
197 self.meta_fields.insert(key.into(), Field::new(ty, doc));
198 self
199 }
200
201 pub fn meta_function<Params, Returns>(mut self, key: impl Into<Index>, doc: impl IntoDocComment) -> Self
214 where
215 Params: TypedMultiValue,
216 Returns: TypedMultiValue,
217 {
218 self.meta_functions.insert(key.into(), Func::new::<Params, Returns>(doc));
219 self
220 }
221
222 pub fn meta_function_with<Params, Returns, F, R>(mut self, key: impl Into<Index>, doc: impl IntoDocComment, generator: F) -> Self
241 where
242 F: Fn(&mut FunctionBuilder<Params, Returns>) -> R,
243 R: Any,
244 Params: TypedMultiValue,
245 Returns: TypedMultiValue,
246 {
247 let mut builder = FunctionBuilder::default();
248 generator(&mut builder);
249
250 self.meta_functions.insert(key.into(), Func {
251 params: builder.params,
252 returns: builder.returns,
253 doc: doc.into_doc_comment()
254 });
255 self
256 }
257
258 pub fn meta_method<Params, Returns>(mut self, key: impl Into<Index>, doc: impl IntoDocComment) -> Self
276 where
277 Params: TypedMultiValue,
278 Returns: TypedMultiValue,
279 {
280 self.meta_methods.insert(key.into(), Func::new::<Params, Returns>(doc));
281 self
282 }
283
284 pub fn meta_method_with<Params, Returns, F, R>(mut self, key: impl Into<Index>, doc: impl IntoDocComment, generator: F) -> Self
303 where
304 F: Fn(&mut FunctionBuilder<Params, Returns>) -> R,
305 R: Any,
306 Params: TypedMultiValue,
307 Returns: TypedMultiValue,
308 {
309 let mut builder = FunctionBuilder::default();
310 generator(&mut builder);
311
312 self.meta_methods.insert(key.into(), Func {
313 params: builder.params,
314 returns: builder.returns,
315 doc: doc.into_doc_comment()
316 });
317 self
318 }
319}
320
321impl<T: TypedUserData> TypedDataDocumentation<T> for TypedClassBuilder {
322 fn add(&mut self, doc: &str) -> &mut Self {
323 if let Some(type_doc) = self.type_doc.as_mut() {
324 *type_doc = format!("{type_doc}\n{doc}").into()
325 } else {
326 self.type_doc = Some(doc.to_string().into())
327 }
328 self
329 }
330}
331
332impl<'lua, T: TypedUserData> TypedDataFields<'lua, T> for TypedClassBuilder {
333 fn document(&mut self, doc: &str) -> &mut Self {
334 self.queued_doc = Some(doc.to_string());
335 self
336 }
337
338 fn add_field<V>(&mut self, name: impl AsRef<str>, _: V)
339 where
340 V: IntoLua<'lua> + Clone + 'static + Typed,
341 {
342 let name: Cow<'static, str> = name.as_ref().to_string().into();
343 self.static_fields
344 .entry(name.into())
345 .and_modify(|v| {
346 v.doc = self.queued_doc.take().map(|v| v.into());
347 v.ty = v.ty.clone() | V::ty();
348 })
349 .or_insert(Field {
350 ty: V::ty(),
351 doc: self.queued_doc.take().map(|v| v.into()),
352 });
353 }
354
355 fn add_field_function_set<S, A, F>(&mut self, name: &S, _: F)
356 where
357 S: AsRef<str> + ?Sized,
358 A: FromLua<'lua> + Typed,
359 F: 'static + MaybeSend + FnMut(&'lua Lua, AnyUserData<'lua>, A) -> mlua::Result<()>,
360 {
361 let name: Cow<'static, str> = name.as_ref().to_string().into();
362 self.static_fields
363 .entry(name.into())
364 .and_modify(|v| {
365 v.doc = self.queued_doc.take().map(|v| v.into());
366 v.ty = v.ty.clone() | A::ty();
367 })
368 .or_insert(Field {
369 ty: A::ty(),
370 doc: self.queued_doc.take().map(|v| v.into()),
371 });
372 }
373
374 fn add_field_function_get<S, R, F>(&mut self, name: &S, _: F)
375 where
376 S: AsRef<str> + ?Sized,
377 R: IntoLua<'lua> + Typed,
378 F: 'static + MaybeSend + Fn(&'lua Lua, AnyUserData<'lua>) -> mlua::Result<R>,
379 {
380 let name: Cow<'static, str> = name.as_ref().to_string().into();
381 self.static_fields
382 .entry(name.into())
383 .and_modify(|v| {
384 v.doc = self.queued_doc.take().map(|v| v.into());
385 v.ty = v.ty.clone() | R::ty();
386 })
387 .or_insert(Field {
388 ty: R::ty(),
389 doc: self.queued_doc.take().map(|v| v.into()),
390 });
391 }
392
393 fn add_field_function_get_set<S, R, A, GET, SET>(&mut self, name: &S, _: GET, _: SET)
394 where
395 S: AsRef<str> + ?Sized,
396 R: IntoLua<'lua> + Typed,
397 A: FromLua<'lua> + Typed,
398 GET: 'static + MaybeSend + Fn(&'lua Lua, AnyUserData<'lua>) -> mlua::Result<R>,
399 SET: 'static + MaybeSend + Fn(&'lua Lua, AnyUserData<'lua>, A) -> mlua::Result<()>,
400 {
401 let name: Cow<'static, str> = name.as_ref().to_string().into();
402 self.static_fields
403 .entry(name.into())
404 .and_modify(|v| {
405 v.doc = self.queued_doc.take().map(|v| v.into());
406 v.ty = v.ty.clone() | A::ty() | R::ty();
407 })
408 .or_insert(Field {
409 ty: A::ty() | R::ty(),
410 doc: self.queued_doc.take().map(|v| v.into()),
411 });
412 }
413
414 fn add_field_method_set<S, A, M>(&mut self, name: &S, _: M)
415 where
416 S: AsRef<str> + ?Sized,
417 A: FromLua<'lua> + Typed,
418 M: 'static + MaybeSend + FnMut(&'lua Lua, &mut T, A) -> mlua::Result<()>,
419 {
420 let name: Cow<'static, str> = name.as_ref().to_string().into();
421 self.fields
422 .entry(name.into())
423 .and_modify(|v| {
424 v.doc = self.queued_doc.take().map(|v| v.into());
425 v.ty = v.ty.clone() | A::ty();
426 })
427 .or_insert(Field {
428 ty: A::ty(),
429 doc: self.queued_doc.take().map(|v| v.into()),
430 });
431 }
432
433 fn add_field_method_get<S, R, M>(&mut self, name: &S, _: M)
434 where
435 S: AsRef<str> + ?Sized,
436 R: IntoLua<'lua> + Typed,
437 M: 'static + MaybeSend + Fn(&'lua Lua, &T) -> mlua::Result<R>,
438 {
439 let name: Cow<'static, str> = name.as_ref().to_string().into();
440 self.fields
441 .entry(name.into())
442 .and_modify(|v| {
443 v.doc = self.queued_doc.take().map(|v| v.into());
444 v.ty = v.ty.clone() | R::ty();
445 })
446 .or_insert(Field {
447 ty: R::ty(),
448 doc: self.queued_doc.take().map(|v| v.into()),
449 });
450 }
451
452 fn add_field_method_get_set<S, R, A, GET, SET>(&mut self, name: &S, _: GET, _: SET)
453 where
454 S: AsRef<str> + ?Sized,
455 R: IntoLua<'lua> + Typed,
456 A: FromLua<'lua> + Typed,
457 GET: 'static + MaybeSend + Fn(&'lua Lua, &T) -> mlua::Result<R>,
458 SET: 'static + MaybeSend + Fn(&'lua Lua, &mut T, A) -> mlua::Result<()>,
459 {
460 let name: Cow<'static, str> = name.as_ref().to_string().into();
461 self.fields
462 .entry(name.into())
463 .and_modify(|v| {
464 v.doc = self.queued_doc.take().map(|v| v.into());
465 v.ty = v.ty.clone() | A::ty() | R::ty();
466 })
467 .or_insert(Field {
468 ty: A::ty() | R::ty(),
469 doc: self.queued_doc.take().map(|v| v.into()),
470 });
471 }
472
473 fn add_meta_field<R, F>(&mut self, meta: MetaMethod, _: F)
474 where
475 F: 'static + MaybeSend + Fn(&'lua Lua) -> mlua::Result<R>,
476 R: IntoLua<'lua> + Typed,
477 {
478 let name: Cow<'static, str> = meta.as_ref().to_string().into();
479 self.meta_fields
480 .entry(name.into())
481 .and_modify(|v| {
482 v.doc = self.queued_doc.take().map(|v| v.into());
483 v.ty = v.ty.clone() | R::ty();
484 })
485 .or_insert(Field {
486 ty: R::ty(),
487 doc: self.queued_doc.take().map(|v| v.into()),
488 });
489 }
490}
491
492impl<'lua, T: TypedUserData> TypedDataMethods<'lua, T> for TypedClassBuilder {
493 fn document(&mut self, documentation: &str) -> &mut Self {
494 self.queued_doc = Some(documentation.to_string());
495 self
496 }
497
498 fn add_method<S, A, R, M>(&mut self, name: &S, _: M)
499 where
500 S: ?Sized + AsRef<str>,
501 A: FromLuaMulti<'lua> + TypedMultiValue,
502 R: IntoLuaMulti<'lua> + TypedMultiValue,
503 M: 'static + MaybeSend + Fn(&'lua Lua, &T, A) -> mlua::Result<R>,
504 {
505 let name: Cow<'static, str> = name.as_ref().to_string().into();
506 self.methods.insert(
507 name.into(),
508 Func {
509 params: A::get_types_as_params(),
510 returns: R::get_types_as_returns(),
511 doc: self.queued_doc.take().map(|v| v.into()),
512 },
513 );
514 }
515
516 fn add_method_with<S, A, R, M, G>(&mut self, name: &S, _method: M, generator: G)
517 where
518 S: ?Sized + AsRef<str>,
519 A: FromLuaMulti<'lua> + TypedMultiValue,
520 R: IntoLuaMulti<'lua> + TypedMultiValue,
521 M: 'static + MaybeSend + Fn(&'lua Lua, &T, A) -> mlua::Result<R>,
522 G: Fn(&mut FunctionBuilder<A, R>) {
523
524 let mut builder = FunctionBuilder::<A, R>::default();
525 generator(&mut builder);
526
527 let name: Cow<'static, str> = name.as_ref().to_string().into();
528 self.methods.insert(
529 name.into(),
530 Func {
531 params: builder.params,
532 returns: builder.returns,
533 doc: self.queued_doc.take().map(|v| v.into()),
534 },
535 );
536 }
537
538 fn add_function<S, A, R, F>(&mut self, name: &S, _: F)
539 where
540 S: ?Sized + AsRef<str>,
541 A: FromLuaMulti<'lua> + TypedMultiValue,
542 R: IntoLuaMulti<'lua> + TypedMultiValue,
543 F: 'static + MaybeSend + Fn(&'lua Lua, A) -> mlua::Result<R>,
544 {
545 let name: Cow<'static, str> = name.as_ref().to_string().into();
546 self.functions.insert(
547 name.into(),
548 Func {
549 params: A::get_types_as_params(),
550 returns: R::get_types_as_returns(),
551 doc: self.queued_doc.take().map(|v| v.into()),
552 },
553 );
554 }
555
556 fn add_function_with<S, A, R, F, G>(&mut self, name: &S, _function: F, generator: G)
557 where
558 S: ?Sized + AsRef<str>,
559 A: FromLuaMulti<'lua> + TypedMultiValue,
560 R: IntoLuaMulti<'lua> + TypedMultiValue,
561 F: 'static + MaybeSend + Fn(&'lua Lua, A) -> mlua::Result<R>,
562 G: Fn(&mut FunctionBuilder<A, R>) {
563
564 let mut builder = FunctionBuilder::<A, R>::default();
565 generator(&mut builder);
566
567 let name: Cow<'static, str> = name.as_ref().to_string().into();
568 self.functions.insert(
569 name.into(),
570 Func {
571 params: builder.params,
572 returns: builder.returns,
573 doc: self.queued_doc.take().map(|v| v.into()),
574 },
575 );
576 }
577
578 fn add_method_mut<S, A, R, M>(&mut self, name: &S, _: M)
579 where
580 S: ?Sized + AsRef<str>,
581 A: FromLuaMulti<'lua> + TypedMultiValue,
582 R: IntoLuaMulti<'lua> + TypedMultiValue,
583 M: 'static + MaybeSend + FnMut(&'lua Lua, &mut T, A) -> mlua::Result<R>,
584 {
585 let name: Cow<'static, str> = name.as_ref().to_string().into();
586 self.methods.insert(
587 name.into(),
588 Func {
589 params: A::get_types_as_params(),
590 returns: R::get_types_as_returns(),
591 doc: self.queued_doc.take().map(|v| v.into()),
592 },
593 );
594 }
595
596 fn add_method_mut_with<S, A, R, M, G>(&mut self, name: &S, _method: M, generator: G)
597 where
598 S: ?Sized + AsRef<str>,
599 A: FromLuaMulti<'lua> + TypedMultiValue,
600 R: IntoLuaMulti<'lua> + TypedMultiValue,
601 M: 'static + MaybeSend + FnMut(&'lua Lua, &mut T, A) -> mlua::Result<R>,
602 G: Fn(&mut FunctionBuilder<A, R>) {
603
604 let mut builder = FunctionBuilder::<A, R>::default();
605 generator(&mut builder);
606
607 let name: Cow<'static, str> = name.as_ref().to_string().into();
608 self.methods.insert(
609 name.into(),
610 Func {
611 params: builder.params,
612 returns: builder.returns,
613 doc: self.queued_doc.take().map(|v| v.into()),
614 },
615 );
616 }
617
618 fn add_meta_method<A, R, M>(&mut self, meta: MetaMethod, _: M)
619 where
620 A: FromLuaMulti<'lua> + TypedMultiValue,
621 R: IntoLuaMulti<'lua> + TypedMultiValue,
622 M: 'static + MaybeSend + Fn(&'lua Lua, &T, A) -> mlua::Result<R>,
623 {
624 let name: Cow<'static, str> = meta.as_ref().to_string().into();
625 self.meta_methods.insert(
626 name.into(),
627 Func {
628 params: A::get_types_as_params(),
629 returns: R::get_types_as_returns(),
630 doc: self.queued_doc.take().map(|v| v.into()),
631 },
632 );
633 }
634
635 fn add_meta_method_with<A, R, M, G>(&mut self, meta: MetaMethod, _method: M, generator: G)
636 where
637 A: FromLuaMulti<'lua> + TypedMultiValue,
638 R: IntoLuaMulti<'lua> + TypedMultiValue,
639 M: 'static + MaybeSend + Fn(&'lua Lua, &T, A) -> mlua::Result<R>,
640 G: Fn(&mut FunctionBuilder<A, R>) {
641
642 let mut builder = FunctionBuilder::<A, R>::default();
643 generator(&mut builder);
644
645 let name: Cow<'static, str> = meta.as_ref().to_string().into();
646 self.meta_methods.insert(
647 name.into(),
648 Func {
649 params: builder.params,
650 returns: builder.returns,
651 doc: self.queued_doc.take().map(|v| v.into()),
652 },
653 );
654 }
655
656 #[cfg(feature = "async")]
657 fn add_async_method<'s, S: ?Sized + AsRef<str>, A, R, M, MR>(&mut self, name: &S, _: M)
658 where
659 'lua: 's,
660 T: 'static,
661 M: Fn(&'lua Lua, &'s T, A) -> MR + MaybeSend + 'static,
662 A: FromLuaMulti<'lua> + TypedMultiValue,
663 MR: std::future::Future<Output = mlua::Result<R>> + 's,
664 R: IntoLuaMulti<'lua> + TypedMultiValue,
665 {
666 let name: Cow<'static, str> = name.as_ref().to_string().into();
667 self.methods.insert(
668 name.into(),
669 Func {
670 params: A::get_types_as_params(),
671 returns: R::get_types_as_returns(),
672 doc: self.queued_doc.take().map(|v| v.into()),
673 },
674 );
675 }
676
677 #[cfg(feature = "async")]
678 fn add_async_method_with<'s, S: ?Sized + AsRef<str>, A, R, M, MR, G>(&mut self, name: &S, _method: M, generator: G)
679 where
680 'lua: 's,
681 T: 'static,
682 M: Fn(&'lua Lua, &'s T, A) -> MR + MaybeSend + 'static,
683 A: FromLuaMulti<'lua> + TypedMultiValue,
684 MR: std::future::Future<Output = mlua::Result<R>> + 's,
685 R: IntoLuaMulti<'lua> + TypedMultiValue,
686 G: Fn(&mut FunctionBuilder<A, R>) {
687
688 let mut builder = FunctionBuilder::<A, R>::default();
689 generator(&mut builder);
690
691 let name: Cow<'static, str> = name.as_ref().to_string().into();
692 self.methods.insert(
693 name.into(),
694 Func {
695 params: builder.params,
696 returns: builder.returns,
697 doc: self.queued_doc.take().map(|v| v.into()),
698 },
699 );
700 }
701
702 #[cfg(feature = "async")]
703 fn add_async_method_mut<'s, S: ?Sized + AsRef<str>, A, R, M, MR>(&mut self, name: &S, method: M)
704 where
705 'lua: 's,
706 T: 'static,
707 M: Fn(&'lua Lua, &'s mut T, A) -> MR + MaybeSend + 'static,
708 A: FromLuaMulti<'lua> + TypedMultiValue,
709 MR: std::future::Future<Output = mlua::Result<R>> + 's,
710 R: IntoLuaMulti<'lua> + TypedMultiValue {
711
712 let name: Cow<'static, str> = name.as_ref().to_string().into();
713 self.methods.insert(
714 name.into(),
715 Func {
716 params: A::get_types_as_params(),
717 returns: R::get_types_as_returns(),
718 doc: self.queued_doc.take().map(|v| v.into()),
719 },
720 );
721 }
722
723 #[cfg(feature = "async")]
724 fn add_async_method_mut_with<'s, S: ?Sized + AsRef<str>, A, R, M, MR, G>(&mut self, name: &S, _method: M, generator: G)
725 where
726 'lua: 's,
727 T: 'static,
728 M: Fn(&'lua Lua, &'s mut T, A) -> MR + MaybeSend + 'static,
729 A: FromLuaMulti<'lua> + TypedMultiValue,
730 MR: std::future::Future<Output = mlua::Result<R>> + 's,
731 R: IntoLuaMulti<'lua> + TypedMultiValue,
732 G: Fn(&mut FunctionBuilder<A, R>) {
733
734 let mut builder = FunctionBuilder::<A, R>::default();
735 generator(&mut builder);
736
737 let name: Cow<'static, str> = name.as_ref().to_string().into();
738 self.methods.insert(
739 name.into(),
740 Func {
741 params: builder.params,
742 returns: builder.returns,
743 doc: self.queued_doc.take().map(|v| v.into()),
744 },
745 );
746 }
747
748 fn add_function_mut<S, A, R, F>(&mut self, name: &S, _: F)
749 where
750 S: ?Sized + AsRef<str>,
751 A: FromLuaMulti<'lua> + TypedMultiValue,
752 R: IntoLuaMulti<'lua> + TypedMultiValue,
753 F: 'static + MaybeSend + FnMut(&'lua Lua, A) -> mlua::Result<R>,
754 {
755 let name: Cow<'static, str> = name.as_ref().to_string().into();
756 self.functions.insert(
757 name.into(),
758 Func {
759 params: A::get_types_as_params(),
760 returns: R::get_types_as_returns(),
761 doc: self.queued_doc.take().map(|v| v.into()),
762 },
763 );
764 }
765
766 fn add_function_mut_with<S, A, R, F, G>(&mut self, name: &S, _function: F, generator: G)
767 where
768 S: ?Sized + AsRef<str>,
769 A: FromLuaMulti<'lua> + TypedMultiValue,
770 R: IntoLuaMulti<'lua> + TypedMultiValue,
771 F: 'static + MaybeSend + FnMut(&'lua Lua, A) -> mlua::Result<R>,
772 G: Fn(&mut FunctionBuilder<A, R>) {
773
774 let mut builder = FunctionBuilder::<A, R>::default();
775 generator(&mut builder);
776
777 let name: Cow<'static, str> = name.as_ref().to_string().into();
778 self.functions.insert(
779 name.into(),
780 Func {
781 params: builder.params,
782 returns: builder.returns,
783 doc: self.queued_doc.take().map(|v| v.into()),
784 },
785 );
786 }
787
788 fn add_meta_function<A, R, F>(&mut self, meta: MetaMethod, _: F)
789 where
790 A: FromLuaMulti<'lua> + TypedMultiValue,
791 R: IntoLuaMulti<'lua> + TypedMultiValue,
792 F: 'static + MaybeSend + Fn(&'lua Lua, A) -> mlua::Result<R>,
793 {
794 let name: Cow<'static, str> = meta.as_ref().to_string().into();
795 self.meta_functions.insert(
796 name.into(),
797 Func {
798 params: A::get_types_as_params(),
799 returns: R::get_types_as_returns(),
800 doc: self.queued_doc.take().map(|v| v.into()),
801 },
802 );
803 }
804
805 fn add_meta_function_with<A, R, F, G>(&mut self, meta: MetaMethod, _function: F, generator: G)
806 where
807 A: FromLuaMulti<'lua> + TypedMultiValue,
808 R: IntoLuaMulti<'lua> + TypedMultiValue,
809 F: 'static + MaybeSend + Fn(&'lua Lua, A) -> mlua::Result<R>,
810 G: Fn(&mut FunctionBuilder<A, R>) {
811
812 let mut builder = FunctionBuilder::<A, R>::default();
813 generator(&mut builder);
814
815 let name: Cow<'static, str> = meta.as_ref().to_string().into();
816 self.functions.insert(
817 name.into(),
818 Func {
819 params: builder.params,
820 returns: builder.returns,
821 doc: self.queued_doc.take().map(|v| v.into()),
822 },
823 );
824 }
825
826 #[cfg(feature = "async")]
827 fn add_async_function<S: ?Sized, A, R, F, FR>(&mut self, name: &S, _: F)
828 where
829 S: AsRef<str>,
830 A: FromLuaMulti<'lua> + TypedMultiValue,
831 R: IntoLuaMulti<'lua> + TypedMultiValue,
832 F: 'static + MaybeSend + Fn(&'lua Lua, A) -> FR,
833 FR: 'lua + std::future::Future<Output = mlua::Result<R>>,
834 {
835 let name: Cow<'static, str> = name.as_ref().to_string().into();
836 self.functions.insert(
837 name.into(),
838 Func {
839 params: A::get_types_as_params(),
840 returns: R::get_types_as_returns(),
841 doc: self.queued_doc.take().map(|v| v.into()),
842 },
843 );
844 }
845
846 #[cfg(feature = "async")]
847 fn add_async_function_with<S: ?Sized, A, R, F, FR, G>(&mut self, name: &S, _function: F, generator: G)
848 where
849 S: AsRef<str>,
850 A: FromLuaMulti<'lua> + TypedMultiValue,
851 R: IntoLuaMulti<'lua> + TypedMultiValue,
852 F: 'static + MaybeSend + Fn(&'lua Lua, A) -> FR,
853 FR: 'lua + std::future::Future<Output = mlua::Result<R>>,
854 G: Fn(&mut FunctionBuilder<A, R>) {
855
856 let mut builder = FunctionBuilder::<A, R>::default();
857 generator(&mut builder);
858
859 let name: Cow<'static, str> = name.as_ref().to_string().into();
860 self.functions.insert(
861 name.into(),
862 Func {
863 params: builder.params,
864 returns: builder.returns,
865 doc: self.queued_doc.take().map(|v| v.into()),
866 },
867 );
868 }
869
870 fn add_meta_method_mut<A, R, M>(&mut self, meta: MetaMethod, _: M)
871 where
872 A: FromLuaMulti<'lua> + TypedMultiValue,
873 R: IntoLuaMulti<'lua> + TypedMultiValue,
874 M: 'static + MaybeSend + FnMut(&'lua Lua, &mut T, A) -> mlua::Result<R>,
875 {
876 let name: Cow<'static, str> = meta.as_ref().to_string().into();
877 self.meta_methods.insert(
878 name.into(),
879 Func {
880 params: A::get_types_as_params(),
881 returns: R::get_types_as_returns(),
882 doc: self.queued_doc.take().map(|v| v.into()),
883 },
884 );
885 }
886
887 fn add_meta_method_mut_with<A, R, M, G>(&mut self, meta: MetaMethod, _method: M, generator: G)
888 where
889 A: FromLuaMulti<'lua> + TypedMultiValue,
890 R: IntoLuaMulti<'lua> + TypedMultiValue,
891 M: 'static + MaybeSend + FnMut(&'lua Lua, &mut T, A) -> mlua::Result<R>,
892 G: Fn(&mut FunctionBuilder<A, R>) {
893
894 let mut builder = FunctionBuilder::<A, R>::default();
895 generator(&mut builder);
896
897 let name: Cow<'static, str> = meta.as_ref().to_string().into();
898 self.meta_methods.insert(
899 name.into(),
900 Func {
901 params: builder.params,
902 returns: builder.returns,
903 doc: self.queued_doc.take().map(|v| v.into()),
904 },
905 );
906 }
907
908 fn add_meta_function_mut<A, R, F>(&mut self, meta: MetaMethod, _: F)
909 where
910 A: FromLuaMulti<'lua> + TypedMultiValue,
911 R: IntoLuaMulti<'lua> + TypedMultiValue,
912 F: 'static + MaybeSend + FnMut(&'lua Lua, A) -> mlua::Result<R>,
913 {
914 let name: Cow<'static, str> = meta.as_ref().to_string().into();
915 self.meta_functions.insert(
916 name.into(),
917 Func {
918 params: A::get_types_as_params(),
919 returns: R::get_types().into_iter().map(|ty| Return { doc: None, ty }).collect(),
920 doc: self.queued_doc.take().map(|v| v.into()),
921 },
922 );
923 }
924
925 fn add_meta_function_mut_with<A, R, F, G>(&mut self, meta: MetaMethod, _function: F, generator: G)
926 where
927 A: FromLuaMulti<'lua> + TypedMultiValue,
928 R: IntoLuaMulti<'lua> + TypedMultiValue,
929 F: 'static + MaybeSend + FnMut(&'lua Lua, A) -> mlua::Result<R>,
930 G: Fn(&mut FunctionBuilder<A, R>) {
931
932 let mut builder = FunctionBuilder::<A, R>::default();
933 generator(&mut builder);
934
935 let name: Cow<'static, str> = meta.as_ref().to_string().into();
936 self.meta_functions.insert(
937 name.into(),
938 Func {
939 params: builder.params,
940 returns: builder.returns,
941 doc: self.queued_doc.take().map(|v| v.into()),
942 },
943 );
944 }
945}