1use std::ops::{Deref, DerefMut};
2use std::os::raw::c_int;
3use std::result::Result as StdResult;
4
5use crate::error::Result;
6use crate::lua::Lua;
7use crate::util::check_stack;
8use crate::value::{FromLua, FromLuaMulti, IntoLua, IntoLuaMulti, MultiValue, Nil};
9
10impl<'lua, T: IntoLua<'lua>, E: IntoLua<'lua>> IntoLuaMulti<'lua> for StdResult<T, E> {
13 #[inline]
14 fn into_lua_multi(self, lua: &'lua Lua) -> Result<MultiValue<'lua>> {
15 let mut result = MultiValue::with_lua_and_capacity(lua, 2);
16 match self {
17 Ok(v) => result.push_front(v.into_lua(lua)?),
18 Err(e) => {
19 result.push_front(e.into_lua(lua)?);
20 result.push_front(Nil);
21 }
22 }
23 Ok(result)
24 }
25
26 #[inline]
27 unsafe fn push_into_stack_multi(self, lua: &'lua Lua) -> Result<c_int> {
28 match self {
29 Ok(v) => v.push_into_stack(lua).map(|_| 1),
30 Err(e) => {
31 let state = lua.state();
32 check_stack(state, 3)?;
33 ffi::lua_pushnil(state);
34 e.push_into_stack(lua)?;
35 Ok(2)
36 }
37 }
38 }
39}
40
41impl<'lua, E: IntoLua<'lua>> IntoLuaMulti<'lua> for StdResult<(), E> {
42 #[inline]
43 fn into_lua_multi(self, lua: &'lua Lua) -> Result<MultiValue<'lua>> {
44 match self {
45 Ok(_) => return Ok(MultiValue::new()),
46 Err(e) => {
47 let mut result = MultiValue::with_lua_and_capacity(lua, 2);
48 result.push_front(e.into_lua(lua)?);
49 result.push_front(Nil);
50 Ok(result)
51 }
52 }
53 }
54
55 #[inline]
56 unsafe fn push_into_stack_multi(self, lua: &'lua Lua) -> Result<c_int> {
57 match self {
58 Ok(_) => Ok(0),
59 Err(e) => {
60 let state = lua.state();
61 check_stack(state, 3)?;
62 ffi::lua_pushnil(state);
63 e.push_into_stack(lua)?;
64 Ok(2)
65 }
66 }
67 }
68}
69
70impl<'lua, T: IntoLua<'lua>> IntoLuaMulti<'lua> for T {
71 #[inline]
72 fn into_lua_multi(self, lua: &'lua Lua) -> Result<MultiValue<'lua>> {
73 let mut v = MultiValue::with_lua_and_capacity(lua, 1);
74 v.push_front(self.into_lua(lua)?);
75 Ok(v)
76 }
77
78 #[inline]
79 unsafe fn push_into_stack_multi(self, lua: &'lua Lua) -> Result<c_int> {
80 self.push_into_stack(lua)?;
81 Ok(1)
82 }
83}
84
85impl<'lua, T: FromLua<'lua>> FromLuaMulti<'lua> for T {
86 #[inline]
87 fn from_lua_multi(mut values: MultiValue<'lua>, lua: &'lua Lua) -> Result<Self> {
88 T::from_lua(values.pop_front().unwrap_or(Nil), lua)
89 }
90
91 #[inline]
92 fn from_lua_args(
93 mut args: MultiValue<'lua>,
94 i: usize,
95 to: Option<&str>,
96 lua: &'lua Lua,
97 ) -> Result<Self> {
98 T::from_lua_arg(args.pop_front().unwrap_or(Nil), i, to, lua)
99 }
100
101 #[inline]
102 unsafe fn from_stack_multi(nvals: c_int, lua: &'lua Lua) -> Result<Self> {
103 if nvals == 0 {
104 return T::from_lua(Nil, lua);
105 }
106 T::from_stack(-nvals, lua)
107 }
108
109 #[inline]
110 unsafe fn from_stack_args(
111 nargs: c_int,
112 i: usize,
113 to: Option<&str>,
114 lua: &'lua Lua,
115 ) -> Result<Self> {
116 if nargs == 0 {
117 return T::from_lua_arg(Nil, i, to, lua);
118 }
119 T::from_stack_arg(-nargs, i, to, lua)
120 }
121}
122
123impl<'lua> IntoLuaMulti<'lua> for MultiValue<'lua> {
124 #[inline]
125 fn into_lua_multi(self, _: &'lua Lua) -> Result<MultiValue<'lua>> {
126 Ok(self)
127 }
128}
129
130impl<'lua> FromLuaMulti<'lua> for MultiValue<'lua> {
131 #[inline]
132 fn from_lua_multi(values: MultiValue<'lua>, _: &'lua Lua) -> Result<Self> {
133 Ok(values)
134 }
135}
136
137#[derive(Debug, Clone)]
164pub struct Variadic<T>(Vec<T>);
165
166impl<T> Variadic<T> {
167 pub const fn new() -> Variadic<T> {
169 Variadic(Vec::new())
170 }
171}
172
173impl<T> Default for Variadic<T> {
174 fn default() -> Variadic<T> {
175 Variadic::new()
176 }
177}
178
179impl<T> FromIterator<T> for Variadic<T> {
180 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
181 Variadic(Vec::from_iter(iter))
182 }
183}
184
185impl<T> IntoIterator for Variadic<T> {
186 type Item = T;
187 type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
188
189 fn into_iter(self) -> Self::IntoIter {
190 self.0.into_iter()
191 }
192}
193
194impl<T> Deref for Variadic<T> {
195 type Target = Vec<T>;
196
197 fn deref(&self) -> &Self::Target {
198 &self.0
199 }
200}
201
202impl<T> DerefMut for Variadic<T> {
203 fn deref_mut(&mut self) -> &mut Self::Target {
204 &mut self.0
205 }
206}
207
208impl<'lua, T: IntoLua<'lua>> IntoLuaMulti<'lua> for Variadic<T> {
209 #[inline]
210 fn into_lua_multi(self, lua: &'lua Lua) -> Result<MultiValue<'lua>> {
211 let mut values = MultiValue::with_lua_and_capacity(lua, self.0.len());
212 values.refill(self.0.into_iter().map(|e| e.into_lua(lua)))?;
213 Ok(values)
214 }
215}
216
217impl<'lua, T: FromLua<'lua>> FromLuaMulti<'lua> for Variadic<T> {
218 #[inline]
219 fn from_lua_multi(mut values: MultiValue<'lua>, lua: &'lua Lua) -> Result<Self> {
220 values
221 .drain_all()
222 .map(|e| T::from_lua(e, lua))
223 .collect::<Result<Vec<T>>>()
224 .map(Variadic)
225 }
226}
227
228macro_rules! impl_tuple {
229 () => (
230 impl<'lua> IntoLuaMulti<'lua> for () {
231 #[inline]
232 fn into_lua_multi(self, lua: &'lua Lua) -> Result<MultiValue<'lua>> {
233 Ok(MultiValue::with_lua_and_capacity(lua, 0))
234 }
235
236 #[inline]
237 unsafe fn push_into_stack_multi(self, _lua: &'lua Lua) -> Result<c_int> {
238 Ok(0)
239 }
240 }
241
242 impl<'lua> FromLuaMulti<'lua> for () {
243 #[inline]
244 fn from_lua_multi(_values: MultiValue<'lua>, _lua: &'lua Lua) -> Result<Self> {
245 Ok(())
246 }
247
248 #[inline]
249 unsafe fn from_stack_multi(nvals: c_int, lua: &'lua Lua) -> Result<Self> {
250 if nvals > 0 {
251 ffi::lua_pop(lua.state(), nvals);
252 }
253 Ok(())
254 }
255 }
256 );
257
258 ($last:ident $($name:ident)*) => (
259 impl<'lua, $($name,)* $last> IntoLuaMulti<'lua> for ($($name,)* $last,)
260 where $($name: IntoLua<'lua>,)*
261 $last: IntoLuaMulti<'lua>
262 {
263 #[allow(unused_mut, non_snake_case)]
264 #[inline]
265 fn into_lua_multi(self, lua: &'lua Lua) -> Result<MultiValue<'lua>> {
266 let ($($name,)* $last,) = self;
267
268 let mut results = $last.into_lua_multi(lua)?;
269 push_reverse!(results, $($name.into_lua(lua)?,)*);
270 Ok(results)
271 }
272
273 #[allow(non_snake_case)]
274 #[inline]
275 unsafe fn push_into_stack_multi(self, lua: &'lua Lua) -> Result<c_int> {
276 let ($($name,)* $last,) = self;
277 let mut nresults = 0;
278 $(
279 _ = $name;
280 nresults += 1;
281 )*
282 check_stack(lua.state(), nresults + 1)?;
283 $(
284 $name.push_into_stack(lua)?;
285 )*
286 nresults += $last.push_into_stack_multi(lua)?;
287 Ok(nresults)
288 }
289 }
290
291 impl<'lua, $($name,)* $last> FromLuaMulti<'lua> for ($($name,)* $last,)
292 where $($name: FromLua<'lua>,)*
293 $last: FromLuaMulti<'lua>
294 {
295 #[allow(unused_mut, non_snake_case)]
296 #[inline]
297 fn from_lua_multi(mut values: MultiValue<'lua>, lua: &'lua Lua) -> Result<Self> {
298 $(let $name = FromLua::from_lua(values.pop_front().unwrap_or(Nil), lua)?;)*
299 let $last = FromLuaMulti::from_lua_multi(values, lua)?;
300 Ok(($($name,)* $last,))
301 }
302
303 #[allow(unused_mut, non_snake_case)]
304 #[inline]
305 fn from_lua_args(mut args: MultiValue<'lua>, mut i: usize, to: Option<&str>, lua: &'lua Lua) -> Result<Self> {
306 $(
307 let $name = FromLua::from_lua_arg(args.pop_front().unwrap_or(Nil), i, to, lua)?;
308 i += 1;
309 )*
310 let $last = FromLuaMulti::from_lua_args(args, i, to, lua)?;
311 Ok(($($name,)* $last,))
312 }
313
314 #[allow(unused_mut, non_snake_case)]
315 #[inline]
316 unsafe fn from_stack_multi(mut nvals: c_int, lua: &'lua Lua) -> Result<Self> {
317 $(
318 let $name = if nvals > 0 {
319 nvals -= 1;
320 FromLua::from_stack(-(nvals + 1), lua)
321 } else {
322 FromLua::from_lua(Nil, lua)
323 }?;
324 )*
325 let $last = FromLuaMulti::from_stack_multi(nvals, lua)?;
326 Ok(($($name,)* $last,))
327 }
328
329 #[allow(unused_mut, non_snake_case)]
330 #[inline]
331 unsafe fn from_stack_args(mut nargs: c_int, mut i: usize, to: Option<&str>, lua: &'lua Lua) -> Result<Self> {
332 $(
333 let $name = if nargs > 0 {
334 nargs -= 1;
335 FromLua::from_stack_arg(-(nargs + 1), i, to, lua)
336 } else {
337 FromLua::from_lua_arg(Nil, i, to, lua)
338 }?;
339 i += 1;
340 )*
341 let $last = FromLuaMulti::from_stack_args(nargs, i, to, lua)?;
342 Ok(($($name,)* $last,))
343 }
344 }
345 );
346}
347
348macro_rules! push_reverse {
349 ($multi_value:expr, $first:expr, $($rest:expr,)*) => (
350 push_reverse!($multi_value, $($rest,)*);
351 $multi_value.push_front($first);
352 );
353
354 ($multi_value:expr, $first:expr) => (
355 $multi_value.push_front($first);
356 );
357
358 ($multi_value:expr,) => ();
359}
360
361impl_tuple!();
362impl_tuple!(A);
363impl_tuple!(A B);
364impl_tuple!(A B C);
365impl_tuple!(A B C D);
366impl_tuple!(A B C D E);
367impl_tuple!(A B C D E F);
368impl_tuple!(A B C D E F G);
369impl_tuple!(A B C D E F G H);
370impl_tuple!(A B C D E F G H I);
371impl_tuple!(A B C D E F G H I J);
372impl_tuple!(A B C D E F G H I J K);
373impl_tuple!(A B C D E F G H I J K L);
374impl_tuple!(A B C D E F G H I J K L M);
375impl_tuple!(A B C D E F G H I J K L M N);
376impl_tuple!(A B C D E F G H I J K L M N O);
377impl_tuple!(A B C D E F G H I J K L M N O P);