mlua/
multi.rs

1use std::collections::{vec_deque, VecDeque};
2use std::iter::FromIterator;
3use std::mem;
4use std::ops::{Deref, DerefMut};
5use std::os::raw::c_int;
6use std::result::Result as StdResult;
7
8use crate::error::Result;
9use crate::state::{Lua, RawLua};
10use crate::traits::{FromLua, FromLuaMulti, IntoLua, IntoLuaMulti};
11use crate::util::check_stack;
12use crate::value::{Nil, Value};
13
14/// Result is convertible to [`MultiValue`] following the common Lua idiom of returning the result
15/// on success, or in the case of an error, returning `nil` and an error message.
16impl<T: IntoLua, E: IntoLua> IntoLuaMulti for StdResult<T, E> {
17    #[inline]
18    fn into_lua_multi(self, lua: &Lua) -> Result<MultiValue> {
19        match self {
20            Ok(val) => (val,).into_lua_multi(lua),
21            Err(err) => (Nil, err).into_lua_multi(lua),
22        }
23    }
24
25    #[inline]
26    unsafe fn push_into_stack_multi(self, lua: &RawLua) -> Result<c_int> {
27        match self {
28            Ok(val) => (val,).push_into_stack_multi(lua),
29            Err(err) => (Nil, err).push_into_stack_multi(lua),
30        }
31    }
32}
33
34impl<E: IntoLua> IntoLuaMulti for StdResult<(), E> {
35    #[inline]
36    fn into_lua_multi(self, lua: &Lua) -> Result<MultiValue> {
37        match self {
38            Ok(_) => const { Ok(MultiValue::new()) },
39            Err(err) => (Nil, err).into_lua_multi(lua),
40        }
41    }
42
43    #[inline]
44    unsafe fn push_into_stack_multi(self, lua: &RawLua) -> Result<c_int> {
45        match self {
46            Ok(_) => Ok(0),
47            Err(err) => (Nil, err).push_into_stack_multi(lua),
48        }
49    }
50}
51
52impl<T: IntoLua> IntoLuaMulti for T {
53    #[inline]
54    fn into_lua_multi(self, lua: &Lua) -> Result<MultiValue> {
55        let mut v = MultiValue::with_capacity(1);
56        v.push_back(self.into_lua(lua)?);
57        Ok(v)
58    }
59
60    #[inline]
61    unsafe fn push_into_stack_multi(self, lua: &RawLua) -> Result<c_int> {
62        self.push_into_stack(lua)?;
63        Ok(1)
64    }
65}
66
67impl<T: FromLua> FromLuaMulti for T {
68    #[inline]
69    fn from_lua_multi(mut values: MultiValue, lua: &Lua) -> Result<Self> {
70        T::from_lua(values.pop_front().unwrap_or(Nil), lua)
71    }
72
73    #[inline]
74    fn from_lua_args(mut args: MultiValue, i: usize, to: Option<&str>, lua: &Lua) -> Result<Self> {
75        T::from_lua_arg(args.pop_front().unwrap_or(Nil), i, to, lua)
76    }
77
78    #[inline]
79    unsafe fn from_stack_multi(nvals: c_int, lua: &RawLua) -> Result<Self> {
80        if nvals == 0 {
81            return T::from_lua(Nil, lua.lua());
82        }
83        T::from_stack(-nvals, lua)
84    }
85
86    #[inline]
87    unsafe fn from_stack_args(nargs: c_int, i: usize, to: Option<&str>, lua: &RawLua) -> Result<Self> {
88        if nargs == 0 {
89            return T::from_lua_arg(Nil, i, to, lua.lua());
90        }
91        T::from_stack_arg(-nargs, i, to, lua)
92    }
93}
94
95/// Multiple Lua values used for both argument passing and also for multiple return values.
96#[derive(Default, Debug, Clone)]
97pub struct MultiValue(VecDeque<Value>);
98
99impl Deref for MultiValue {
100    type Target = VecDeque<Value>;
101
102    #[inline]
103    fn deref(&self) -> &Self::Target {
104        &self.0
105    }
106}
107
108impl DerefMut for MultiValue {
109    #[inline]
110    fn deref_mut(&mut self) -> &mut Self::Target {
111        &mut self.0
112    }
113}
114
115impl MultiValue {
116    /// Creates an empty `MultiValue` containing no values.
117    #[inline]
118    pub const fn new() -> MultiValue {
119        MultiValue(VecDeque::new())
120    }
121
122    /// Creates an empty `MultiValue` container with space for at least `capacity` elements.
123    pub fn with_capacity(capacity: usize) -> MultiValue {
124        MultiValue(VecDeque::with_capacity(capacity))
125    }
126
127    /// Creates a `MultiValue` container from vector of values.
128    ///
129    /// This method works in *O*(1) time and does not allocate any additional memory.
130    #[inline]
131    pub fn from_vec(vec: Vec<Value>) -> MultiValue {
132        vec.into()
133    }
134
135    /// Consumes the `MultiValue` and returns a vector of values.
136    ///
137    /// This method needs *O*(*n*) data movement if the circular buffer doesn't happen to be at the
138    /// beginning of the allocation.
139    #[inline]
140    pub fn into_vec(self) -> Vec<Value> {
141        self.into()
142    }
143
144    #[inline]
145    pub(crate) fn from_lua_iter<T: IntoLua>(lua: &Lua, iter: impl IntoIterator<Item = T>) -> Result<Self> {
146        let iter = iter.into_iter();
147        let mut multi_value = MultiValue::with_capacity(iter.size_hint().0);
148        for value in iter {
149            multi_value.push_back(value.into_lua(lua)?);
150        }
151        Ok(multi_value)
152    }
153}
154
155impl From<Vec<Value>> for MultiValue {
156    #[inline]
157    fn from(value: Vec<Value>) -> Self {
158        MultiValue(value.into())
159    }
160}
161
162impl From<MultiValue> for Vec<Value> {
163    #[inline]
164    fn from(value: MultiValue) -> Self {
165        value.0.into()
166    }
167}
168
169impl FromIterator<Value> for MultiValue {
170    #[inline]
171    fn from_iter<I: IntoIterator<Item = Value>>(iter: I) -> Self {
172        let mut multi_value = MultiValue::new();
173        multi_value.extend(iter);
174        multi_value
175    }
176}
177
178impl IntoIterator for MultiValue {
179    type Item = Value;
180    type IntoIter = vec_deque::IntoIter<Value>;
181
182    #[inline]
183    fn into_iter(mut self) -> Self::IntoIter {
184        let deque = mem::take(&mut self.0);
185        mem::forget(self);
186        deque.into_iter()
187    }
188}
189
190impl<'a> IntoIterator for &'a MultiValue {
191    type Item = &'a Value;
192    type IntoIter = vec_deque::Iter<'a, Value>;
193
194    #[inline]
195    fn into_iter(self) -> Self::IntoIter {
196        self.0.iter()
197    }
198}
199
200impl IntoLuaMulti for MultiValue {
201    #[inline]
202    fn into_lua_multi(self, _: &Lua) -> Result<MultiValue> {
203        Ok(self)
204    }
205}
206
207impl FromLuaMulti for MultiValue {
208    #[inline]
209    fn from_lua_multi(values: MultiValue, _: &Lua) -> Result<Self> {
210        Ok(values)
211    }
212}
213
214/// Wraps a variable number of `T`s.
215///
216/// Can be used to work with variadic functions more easily. Using this type as the last argument of
217/// a Rust callback will accept any number of arguments from Lua and convert them to the type `T`
218/// using [`FromLua`]. `Variadic<T>` can also be returned from a callback, returning a variable
219/// number of values to Lua.
220///
221/// The [`MultiValue`] type is equivalent to `Variadic<Value>`.
222///
223/// # Examples
224///
225/// ```
226/// # use mlua::{Lua, Result, Variadic};
227/// # fn main() -> Result<()> {
228/// # let lua = Lua::new();
229/// let add = lua.create_function(|_, vals: Variadic<f64>| -> Result<f64> {
230///     Ok(vals.iter().sum())
231/// })?;
232/// lua.globals().set("add", add)?;
233/// assert_eq!(lua.load("add(3, 2, 5)").eval::<f32>()?, 10.0);
234/// # Ok(())
235/// # }
236/// ```
237#[derive(Default, Debug, Clone)]
238pub struct Variadic<T>(Vec<T>);
239
240impl<T> Variadic<T> {
241    /// Creates an empty `Variadic` wrapper containing no values.
242    pub const fn new() -> Variadic<T> {
243        Variadic(Vec::new())
244    }
245
246    /// Creates an empty `Variadic` container with space for at least `capacity` elements.
247    pub fn with_capacity(capacity: usize) -> Variadic<T> {
248        Variadic(Vec::with_capacity(capacity))
249    }
250}
251
252impl<T> Deref for Variadic<T> {
253    type Target = Vec<T>;
254
255    fn deref(&self) -> &Self::Target {
256        &self.0
257    }
258}
259
260impl<T> DerefMut for Variadic<T> {
261    fn deref_mut(&mut self) -> &mut Self::Target {
262        &mut self.0
263    }
264}
265
266impl<T> From<Vec<T>> for Variadic<T> {
267    #[inline]
268    fn from(vec: Vec<T>) -> Self {
269        Variadic(vec)
270    }
271}
272
273impl<T> From<Variadic<T>> for Vec<T> {
274    #[inline]
275    fn from(value: Variadic<T>) -> Self {
276        value.0
277    }
278}
279
280impl<T> FromIterator<T> for Variadic<T> {
281    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
282        Variadic(Vec::from_iter(iter))
283    }
284}
285
286impl<T> IntoIterator for Variadic<T> {
287    type Item = T;
288    type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
289
290    fn into_iter(self) -> Self::IntoIter {
291        self.0.into_iter()
292    }
293}
294
295impl<T: IntoLua> IntoLuaMulti for Variadic<T> {
296    #[inline]
297    fn into_lua_multi(self, lua: &Lua) -> Result<MultiValue> {
298        MultiValue::from_lua_iter(lua, self)
299    }
300}
301
302impl<T: FromLua> FromLuaMulti for Variadic<T> {
303    #[inline]
304    fn from_lua_multi(mut values: MultiValue, lua: &Lua) -> Result<Self> {
305        values
306            .drain(..)
307            .map(|val| T::from_lua(val, lua))
308            .collect::<Result<Vec<T>>>()
309            .map(Variadic)
310    }
311}
312
313macro_rules! impl_tuple {
314    () => (
315        impl IntoLuaMulti for () {
316            #[inline]
317            fn into_lua_multi(self, _: &Lua) -> Result<MultiValue> {
318                const { Ok(MultiValue::new()) }
319            }
320
321            #[inline]
322            unsafe fn push_into_stack_multi(self, _lua: &RawLua) -> Result<c_int> {
323                Ok(0)
324            }
325        }
326
327        impl FromLuaMulti for () {
328            #[inline]
329            fn from_lua_multi(_values: MultiValue, _lua: &Lua) -> Result<Self> {
330                Ok(())
331            }
332
333            #[inline]
334            unsafe fn from_stack_multi(_nvals: c_int, _lua: &RawLua) -> Result<Self> {
335                Ok(())
336            }
337        }
338    );
339
340    ($last:ident $($name:ident)*) => (
341        impl<$($name,)* $last> IntoLuaMulti for ($($name,)* $last,)
342            where $($name: IntoLua,)*
343                  $last: IntoLuaMulti
344        {
345            #[allow(unused_mut, non_snake_case)]
346            #[inline]
347            fn into_lua_multi(self, lua: &Lua) -> Result<MultiValue> {
348                let ($($name,)* $last,) = self;
349
350                let mut results = $last.into_lua_multi(lua)?;
351                push_reverse!(results, $($name.into_lua(lua)?,)*);
352                Ok(results)
353            }
354
355            #[allow(non_snake_case)]
356            #[inline]
357            unsafe fn push_into_stack_multi(self, lua: &RawLua) -> Result<c_int> {
358                let ($($name,)* $last,) = self;
359                let mut nresults = 0;
360                $(
361                    _ = $name;
362                    nresults += 1;
363                )*
364                check_stack(lua.state(), nresults + 1)?;
365                $(
366                    $name.push_into_stack(lua)?;
367                )*
368                nresults += $last.push_into_stack_multi(lua)?;
369                Ok(nresults)
370            }
371        }
372
373        impl<$($name,)* $last> FromLuaMulti for ($($name,)* $last,)
374            where $($name: FromLua,)*
375                  $last: FromLuaMulti
376        {
377            #[allow(unused_mut, non_snake_case)]
378            #[inline]
379            fn from_lua_multi(mut values: MultiValue, lua: &Lua) -> Result<Self> {
380                $(let $name = FromLua::from_lua(values.pop_front().unwrap_or(Nil), lua)?;)*
381                let $last = FromLuaMulti::from_lua_multi(values, lua)?;
382                Ok(($($name,)* $last,))
383            }
384
385            #[allow(unused_mut, non_snake_case)]
386            #[inline]
387            fn from_lua_args(mut args: MultiValue, mut i: usize, to: Option<&str>, lua: &Lua) -> Result<Self> {
388                $(
389                    let $name = FromLua::from_lua_arg(args.pop_front().unwrap_or(Nil), i, to, lua)?;
390                    i += 1;
391                )*
392                let $last = FromLuaMulti::from_lua_args(args, i, to, lua)?;
393                Ok(($($name,)* $last,))
394            }
395
396            #[allow(unused_mut, non_snake_case)]
397            #[inline]
398            unsafe fn from_stack_multi(mut nvals: c_int, lua: &RawLua) -> Result<Self> {
399                $(
400                    let $name = if nvals > 0 {
401                        nvals -= 1;
402                        FromLua::from_stack(-(nvals + 1), lua)
403                    } else {
404                        FromLua::from_lua(Nil, lua.lua())
405                    }?;
406                )*
407                let $last = FromLuaMulti::from_stack_multi(nvals, lua)?;
408                Ok(($($name,)* $last,))
409            }
410
411            #[allow(unused_mut, non_snake_case)]
412            #[inline]
413            unsafe fn from_stack_args(mut nargs: c_int, mut i: usize, to: Option<&str>, lua: &RawLua) -> Result<Self> {
414                $(
415                    let $name = if nargs > 0 {
416                        nargs -= 1;
417                        FromLua::from_stack_arg(-(nargs + 1), i, to, lua)
418                    } else {
419                        FromLua::from_lua_arg(Nil, i, to, lua.lua())
420                    }?;
421                    i += 1;
422                )*
423                let $last = FromLuaMulti::from_stack_args(nargs, i, to, lua)?;
424                Ok(($($name,)* $last,))
425            }
426        }
427    );
428}
429
430macro_rules! push_reverse {
431    ($multi_value:expr, $first:expr, $($rest:expr,)*) => (
432        push_reverse!($multi_value, $($rest,)*);
433        $multi_value.push_front($first);
434    );
435
436    ($multi_value:expr, $first:expr) => (
437        $multi_value.push_front($first);
438    );
439
440    ($multi_value:expr,) => ();
441}
442
443impl_tuple!();
444impl_tuple!(A);
445impl_tuple!(A B);
446impl_tuple!(A B C);
447impl_tuple!(A B C D);
448impl_tuple!(A B C D E);
449impl_tuple!(A B C D E F);
450impl_tuple!(A B C D E F G);
451impl_tuple!(A B C D E F G H);
452impl_tuple!(A B C D E F G H I);
453impl_tuple!(A B C D E F G H I J);
454impl_tuple!(A B C D E F G H I J K);
455impl_tuple!(A B C D E F G H I J K L);
456impl_tuple!(A B C D E F G H I J K L M);
457impl_tuple!(A B C D E F G H I J K L M N);
458impl_tuple!(A B C D E F G H I J K L M N O);
459impl_tuple!(A B C D E F G H I J K L M N O P);
460
461#[cfg(test)]
462mod assertions {
463    use super::*;
464
465    #[cfg(not(feature = "send"))]
466    static_assertions::assert_not_impl_any!(MultiValue: Send);
467    #[cfg(feature = "send")]
468    static_assertions::assert_impl_all!(MultiValue: Send, Sync);
469}