rtk_lua/
macros.rs

1/// Implements `IntoLua` for a struct.
2///
3/// ```rust,ignore
4/// impl_into_lua! {
5///     FunctionTypeValue {
6///         location,
7///         args_struct,
8///         // closure will apply to whatever the field name itself is
9///         return_type => return_type.map(|b| *b),
10///         item_id,
11///     }
12/// }
13/// ```
14#[macro_export]
15macro_rules! impl_into_lua {
16    (
17        $ty:ty {
18            $( $field:ident $(=> $conv:expr)? ),* $(,)?
19        }
20    ) => {
21        impl IntoLua for $ty {
22            fn into_lua(self, lua: &::mlua::Lua) -> ::mlua::Result<::mlua::Value> {
23                let Self { $( $field ),* } = self;
24
25                let table = lua.create_table()?;
26
27                $(
28                    impl_into_lua!(@assign table $field $(=> $conv)?);
29                )*
30
31                Ok(::mlua::Value::Table(table))
32            }
33        }
34    };
35
36    (@assign $tbl:ident $field:ident) => {
37        $tbl.set(stringify!($field), $field)?;
38    };
39
40    (@assign $tbl:ident $field:ident => $conv:expr) => {
41        $tbl.set(stringify!($field), $conv)?;
42    };
43}
44
45/// Implements `IntoLua` for enums by mapping each variant to a Lua table formed like
46/// `{ variant_name, variant_data }`
47///
48/// ```rust,ignore
49/// #[derive(Clone, Debug)]
50/// pub enum MyValue {
51///     Nil,
52///     Str(String),
53/// }
54///
55/// impl_enum_into_lua! {
56///     MyValue {
57///         Nil,
58///         // this will just forward the one tuple variant forwards
59///         Str(s) => s,
60///     }
61/// }
62/// ```
63#[macro_export]
64macro_rules! impl_enum_into_lua {
65    (
66        $enum:ident {
67            $(
68                $name:ident
69                    $( ( $($tuple_pat:pat),* ) )?
70                    $( { $($struct_pat:pat),* } )?
71                    $( => $data:expr )?
72            ),* $(,)?
73        }
74    ) => {
75        impl ::mlua::IntoLua for $enum {
76            fn into_lua(self, lua: &::mlua::Lua) -> ::mlua::Result<::mlua::Value> {
77                match self {
78                    $(
79                        $enum::$name
80                            $( ( $($tuple_pat),* ) )?
81                            $( { $($struct_pat),* } )?
82                            => {
83                                let tbl = lua.create_table()?;
84                                tbl.set("variant_name", stringify!($name))?;
85                                tbl.set(
86                                    "variant_data",
87                                    impl_enum_into_lua!(@value lua $(, $data)?)
88                                )?;
89                                Ok(::mlua::Value::Table(tbl))
90                            }
91                    ),*
92                }
93            }
94        }
95    };
96
97    (@value $lua:ident , $val:expr) => { $val };
98    (@value $lua:ident) => { ::mlua::Value::Nil };
99}