1use AsMutLua;
2use AsLua;
3
4use Push;
5use PushOne;
6use PushGuard;
7use LuaRead;
8use Void;
9
10macro_rules! tuple_impl {
11 ($ty:ident) => (
12 impl<'lua, LU, $ty> Push<LU> for ($ty,) where LU: AsMutLua<'lua>, $ty: Push<LU> {
13 type Err = <$ty as Push<LU>>::Err;
14
15 #[inline]
16 fn push_to_lua(self, lua: LU) -> Result<PushGuard<LU>, (Self::Err, LU)> {
17 self.0.push_to_lua(lua)
18 }
19 }
20
21 impl<'lua, LU, $ty> PushOne<LU> for ($ty,) where LU: AsMutLua<'lua>, $ty: PushOne<LU> {
22 }
23
24 impl<'lua, LU, $ty> LuaRead<LU> for ($ty,) where LU: AsMutLua<'lua>, $ty: LuaRead<LU> {
25 #[inline]
26 fn lua_read_at_position(lua: LU, index: i32) -> Result<($ty,), LU> {
27 LuaRead::lua_read_at_position(lua, index).map(|v| (v,))
28 }
29 }
30 );
31
32 ($first:ident, $($other:ident),+) => (
33 #[allow(non_snake_case)]
34 impl<'lua, LU, FE, OE, $first, $($other),+> Push<LU> for ($first, $($other),+)
35 where LU: AsMutLua<'lua>,
36 $first: for<'a> Push<&'a mut LU, Err = FE>,
37 ($($other,)+): for<'a> Push<&'a mut LU, Err = OE>
38 {
39 type Err = TuplePushError<FE, OE>;
40
41 #[inline]
42 fn push_to_lua(self, mut lua: LU) -> Result<PushGuard<LU>, (Self::Err, LU)> {
43 match self {
44 ($first, $($other),+) => {
45 let mut total = 0;
46
47 let first_err = match $first.push_to_lua(&mut lua) {
48 Ok(pushed) => { total += pushed.forget_internal(); None },
49 Err((err, _)) => Some(err),
50 };
51
52 if let Some(err) = first_err {
53 return Err((TuplePushError::First(err), lua));
54 }
55
56 let rest = ($($other,)+);
57 let other_err = match rest.push_to_lua(&mut lua) {
58 Ok(pushed) => { total += pushed.forget_internal(); None },
59 Err((err, _)) => Some(err),
60 };
61
62 if let Some(err) = other_err {
63 return Err((TuplePushError::Other(err), lua));
64 }
65
66 let raw_lua = lua.as_lua();
67 Ok(PushGuard { lua: lua, size: total, raw_lua: raw_lua })
68 }
69 }
70 }
71 }
72
73 #[allow(unused_assignments)]
75 #[allow(non_snake_case)]
76 impl<'lua, LU, $first: for<'a> LuaRead<&'a mut LU>, $($other: for<'a> LuaRead<&'a mut LU>),+>
77 LuaRead<LU> for ($first, $($other),+) where LU: AsLua<'lua>
78 {
79 #[inline]
80 fn lua_read_at_position(mut lua: LU, index: i32) -> Result<($first, $($other),+), LU> {
81 let mut i = index;
82
83 let $first: $first = match LuaRead::lua_read_at_position(&mut lua, i) {
84 Ok(v) => v,
85 Err(_) => return Err(lua)
86 };
87
88 i += 1;
89
90 $(
91 let $other: $other = match LuaRead::lua_read_at_position(&mut lua, i) {
92 Ok(v) => v,
93 Err(_) => return Err(lua)
94 };
95 i += 1;
96 )+
97
98 Ok(($first, $($other),+))
99
100 }
101 }
102
103 tuple_impl!($($other),+);
104 );
105}
106
107tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M);
108
109#[derive(Debug, Copy, Clone)]
112pub enum TuplePushError<C, O> {
113 First(C),
114 Other(O),
115}
116
117impl From<TuplePushError<Void, Void>> for Void {
118 #[inline]
119 fn from(_: TuplePushError<Void, Void>) -> Void {
120 unreachable!()
121 }
122}