1use crate::amx::{Allocator, Amx};
31use crate::cell::{AmxPrimitive, AmxString, Buffer, Ref};
32use crate::error::AmxResult;
33
34pub trait PublicArg<'amx> {
40 fn push_to(self, amx: &'amx Amx, allocator: &Allocator<'amx>) -> AmxResult<()>;
46}
47
48macro_rules! impl_cell_arg {
50 ($($type:ty),* $(,)?) => {
51 $(
52 impl<'amx> PublicArg<'amx> for $type {
53 #[inline]
54 fn push_to(self, amx: &'amx Amx, _allocator: &Allocator<'amx>) -> AmxResult<()> {
55 amx.push(self)
56 }
57 }
58 )*
59 };
60}
61
62impl_cell_arg!(i8, u8, i16, u16, i32, u32, usize, isize, f32, bool);
63
64impl<'amx> PublicArg<'amx> for AmxString<'amx> {
65 #[inline]
66 fn push_to(self, amx: &'amx Amx, _allocator: &Allocator<'amx>) -> AmxResult<()> {
67 amx.push(self)
68 }
69}
70
71impl<'amx> PublicArg<'amx> for Buffer<'amx> {
72 #[inline]
73 fn push_to(self, amx: &'amx Amx, _allocator: &Allocator<'amx>) -> AmxResult<()> {
74 amx.push(self)
75 }
76}
77
78impl<'amx, T: AmxPrimitive> PublicArg<'amx> for Ref<'amx, T> {
79 #[inline]
80 fn push_to(self, amx: &'amx Amx, _allocator: &Allocator<'amx>) -> AmxResult<()> {
81 amx.push(self)
82 }
83}
84
85impl<'amx> PublicArg<'amx> for &str {
87 #[inline]
88 fn push_to(self, amx: &'amx Amx, allocator: &Allocator<'amx>) -> AmxResult<()> {
89 let string = allocator.allot_string(self)?;
90 amx.push(string)
91 }
92}
93
94impl<'amx> PublicArg<'amx> for &String {
95 #[inline]
96 fn push_to(self, amx: &'amx Amx, allocator: &Allocator<'amx>) -> AmxResult<()> {
97 self.as_str().push_to(amx, allocator)
98 }
99}
100
101impl<'amx> PublicArg<'amx> for &[i32] {
103 #[inline]
104 fn push_to(self, amx: &'amx Amx, allocator: &Allocator<'amx>) -> AmxResult<()> {
105 let array = allocator.allot_array(self)?;
106 amx.push(array)
107 }
108}
109
110impl<'amx> PublicArg<'amx> for &Vec<i32> {
111 #[inline]
112 fn push_to(self, amx: &'amx Amx, allocator: &Allocator<'amx>) -> AmxResult<()> {
113 self.as_slice().push_to(amx, allocator)
114 }
115}
116
117pub trait PublicArgs<'amx> {
120 fn push_all(self, amx: &'amx Amx, allocator: &Allocator<'amx>) -> AmxResult<()>;
125}
126
127impl PublicArgs<'_> for () {
128 #[inline]
129 fn push_all(self, _amx: &Amx, _allocator: &Allocator<'_>) -> AmxResult<()> {
130 Ok(())
131 }
132}
133
134macro_rules! impl_args_tuple {
137 ($(($($name:ident),+)),* $(,)?) => {
138 $(
139 #[allow(non_snake_case)]
140 impl<'amx, $($name: PublicArg<'amx>),+> PublicArgs<'amx> for ($($name,)+) {
141 #[inline]
142 fn push_all(self, amx: &'amx Amx, allocator: &Allocator<'amx>) -> AmxResult<()> {
143 let ($($name,)+) = self;
144 impl_args_tuple!(@push amx, allocator, $($name),+);
145 Ok(())
146 }
147 }
148 )*
149 };
150 (@push $amx:ident, $al:ident, $head:ident) => {
151 $head.push_to($amx, $al)?;
152 };
153 (@push $amx:ident, $al:ident, $head:ident, $($tail:ident),+) => {
154 impl_args_tuple!(@push $amx, $al, $($tail),+);
155 $head.push_to($amx, $al)?;
156 };
157}
158
159impl_args_tuple!(
160 (A),
161 (A, B),
162 (A, B, C),
163 (A, B, C, D),
164 (A, B, C, D, E),
165 (A, B, C, D, E, F),
166 (A, B, C, D, E, F, G),
167 (A, B, C, D, E, F, G, H),
168 (A, B, C, D, E, F, G, H, I),
169 (A, B, C, D, E, F, G, H, I, J),
170 (A, B, C, D, E, F, G, H, I, J, K),
171 (A, B, C, D, E, F, G, H, I, J, K, L),
172);