1#![allow(clippy::wrong_self_convention)]
2
3use std::iter::FromIterator;
4use std::ops::{Deref, DerefMut};
5use std::result::Result as StdResult;
6
7use crate::error::Result;
8use crate::lua::Lua;
9use crate::value::{FromLua, FromLuaMulti, MultiValue, Nil, ToLua, ToLuaMulti};
10
11impl<'lua, T: ToLua<'lua>, E: ToLua<'lua>> ToLuaMulti<'lua> for StdResult<T, E> {
14 #[inline]
15 fn to_lua_multi(self, lua: &'lua Lua) -> Result<MultiValue<'lua>> {
16 let mut result = MultiValue::new_or_cached(lua);
17 match self {
18 Ok(v) => result.push_front(v.to_lua(lua)?),
19 Err(e) => {
20 result.push_front(e.to_lua(lua)?);
21 result.push_front(Nil);
22 }
23 }
24 Ok(result)
25 }
26}
27
28impl<'lua, T: ToLua<'lua>> ToLuaMulti<'lua> for T {
29 #[inline]
30 fn to_lua_multi(self, lua: &'lua Lua) -> Result<MultiValue<'lua>> {
31 let mut v = MultiValue::new_or_cached(lua);
32 v.push_front(self.to_lua(lua)?);
33 Ok(v)
34 }
35}
36
37impl<'lua, T: FromLua<'lua>> FromLuaMulti<'lua> for T {
38 #[inline]
39 fn from_lua_multi(mut values: MultiValue<'lua>, lua: &'lua Lua) -> Result<Self> {
40 let res = T::from_lua(values.pop_front().unwrap_or(Nil), lua);
41 lua.cache_multivalue(values);
42 res
43 }
44}
45
46impl<'lua> ToLuaMulti<'lua> for MultiValue<'lua> {
47 #[inline]
48 fn to_lua_multi(self, _: &'lua Lua) -> Result<MultiValue<'lua>> {
49 Ok(self)
50 }
51}
52
53impl<'lua> FromLuaMulti<'lua> for MultiValue<'lua> {
54 #[inline]
55 fn from_lua_multi(values: MultiValue<'lua>, _: &'lua Lua) -> Result<Self> {
56 Ok(values)
57 }
58}
59
60#[derive(Debug, Clone)]
87pub struct Variadic<T>(Vec<T>);
88
89impl<T> Variadic<T> {
90 pub const fn new() -> Variadic<T> {
92 Variadic(Vec::new())
93 }
94}
95
96impl<T> Default for Variadic<T> {
97 fn default() -> Variadic<T> {
98 Variadic::new()
99 }
100}
101
102impl<T> FromIterator<T> for Variadic<T> {
103 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
104 Variadic(Vec::from_iter(iter))
105 }
106}
107
108impl<T> IntoIterator for Variadic<T> {
109 type Item = T;
110 type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
111
112 fn into_iter(self) -> Self::IntoIter {
113 self.0.into_iter()
114 }
115}
116
117impl<T> Deref for Variadic<T> {
118 type Target = Vec<T>;
119
120 fn deref(&self) -> &Self::Target {
121 &self.0
122 }
123}
124
125impl<T> DerefMut for Variadic<T> {
126 fn deref_mut(&mut self) -> &mut Self::Target {
127 &mut self.0
128 }
129}
130
131impl<'lua, T: ToLua<'lua>> ToLuaMulti<'lua> for Variadic<T> {
132 #[inline]
133 fn to_lua_multi(self, lua: &'lua Lua) -> Result<MultiValue<'lua>> {
134 let mut values = MultiValue::new_or_cached(lua);
135 values.refill(self.0.into_iter().map(|e| e.to_lua(lua)))?;
136 Ok(values)
137 }
138}
139
140impl<'lua, T: FromLua<'lua>> FromLuaMulti<'lua> for Variadic<T> {
141 #[inline]
142 fn from_lua_multi(mut values: MultiValue<'lua>, lua: &'lua Lua) -> Result<Self> {
143 let res = values
144 .drain_all()
145 .map(|e| T::from_lua(e, lua))
146 .collect::<Result<Vec<T>>>()
147 .map(Variadic);
148 lua.cache_multivalue(values);
149 res
150 }
151}
152
153macro_rules! impl_tuple {
154 () => (
155 impl<'lua> ToLuaMulti<'lua> for () {
156 #[inline]
157 fn to_lua_multi(self, lua: &'lua Lua) -> Result<MultiValue<'lua>> {
158 Ok(MultiValue::new_or_cached(lua))
159 }
160 }
161
162 impl<'lua> FromLuaMulti<'lua> for () {
163 #[inline]
164 fn from_lua_multi(values: MultiValue<'lua>, lua: &'lua Lua) -> Result<Self> {
165 lua.cache_multivalue(values);
166 Ok(())
167 }
168 }
169 );
170
171 ($last:ident $($name:ident)*) => (
172 impl<'lua, $($name,)* $last> ToLuaMulti<'lua> for ($($name,)* $last,)
173 where $($name: ToLua<'lua>,)*
174 $last: ToLuaMulti<'lua>
175 {
176 #[allow(unused_mut)]
177 #[allow(non_snake_case)]
178 #[inline]
179 fn to_lua_multi(self, lua: &'lua Lua) -> Result<MultiValue<'lua>> {
180 let ($($name,)* $last,) = self;
181
182 let mut results = $last.to_lua_multi(lua)?;
183 push_reverse!(results, $($name.to_lua(lua)?,)*);
184 Ok(results)
185 }
186 }
187
188 impl<'lua, $($name,)* $last> FromLuaMulti<'lua> for ($($name,)* $last,)
189 where $($name: FromLua<'lua>,)*
190 $last: FromLuaMulti<'lua>
191 {
192 #[allow(unused_mut)]
193 #[allow(non_snake_case)]
194 #[inline]
195 fn from_lua_multi(mut values: MultiValue<'lua>, lua: &'lua Lua) -> Result<Self> {
196 $(let $name = values.pop_front().unwrap_or(Nil);)*
197 let $last = FromLuaMulti::from_lua_multi(values, lua)?;
198 Ok(($(FromLua::from_lua($name, lua)?,)* $last,))
199 }
200 }
201 );
202}
203
204macro_rules! push_reverse {
205 ($multi_value:expr, $first:expr, $($rest:expr,)*) => (
206 push_reverse!($multi_value, $($rest,)*);
207 $multi_value.push_front($first);
208 );
209
210 ($multi_value:expr, $first:expr) => (
211 $multi_value.push_front($first);
212 );
213
214 ($multi_value:expr,) => ();
215}
216
217impl_tuple!();
218impl_tuple!(A);
219impl_tuple!(A B);
220impl_tuple!(A B C);
221impl_tuple!(A B C D);
222impl_tuple!(A B C D E);
223impl_tuple!(A B C D E F);
224impl_tuple!(A B C D E F G);
225impl_tuple!(A B C D E F G H);
226impl_tuple!(A B C D E F G H I);
227impl_tuple!(A B C D E F G H I J);
228impl_tuple!(A B C D E F G H I J K);
229impl_tuple!(A B C D E F G H I J K L);
230impl_tuple!(A B C D E F G H I J K L M);
231impl_tuple!(A B C D E F G H I J K L M N);
232impl_tuple!(A B C D E F G H I J K L M N O);
233impl_tuple!(A B C D E F G H I J K L M N O P);