zero_mysql/protocol/trait/
param.rs1use auto_impl::auto_impl;
2
3use crate::constant::ColumnType;
4use crate::error::Result;
5use crate::protocol::primitive::*;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11#[repr(u8)]
12pub enum ParamIndicator {
13 None = 0,
15 Null = 1,
17 Default = 2,
19 Ignore = 3,
21}
22
23pub trait Param {
24 fn is_null(&self) -> bool;
25 fn encode_type(&self, out: &mut Vec<u8>);
26 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()>;
27}
28
29pub trait TypedParam {
30 fn is_null(&self) -> bool {
31 false
32 }
33 fn encode_type(out: &mut Vec<u8>);
34 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()>;
35}
36
37impl TypedParam for bool {
38 fn encode_type(out: &mut Vec<u8>) {
39 out.push(ColumnType::MYSQL_TYPE_TINY as u8);
40 out.push(0x00);
41 }
42
43 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()> {
44 write_int_1(out, u8::from(*self));
45 Ok(())
46 }
47}
48
49impl TypedParam for i8 {
50 fn encode_type(out: &mut Vec<u8>) {
51 out.push(ColumnType::MYSQL_TYPE_TINY as u8);
52 out.push(0x00);
53 }
54
55 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()> {
56 write_int_1(out, *self as u8);
57 Ok(())
58 }
59}
60
61impl TypedParam for i16 {
62 fn encode_type(out: &mut Vec<u8>) {
63 out.push(ColumnType::MYSQL_TYPE_SHORT as u8);
64 out.push(0x00);
65 }
66
67 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()> {
68 write_int_2(out, *self as u16);
69 Ok(())
70 }
71}
72
73impl TypedParam for i32 {
74 fn encode_type(out: &mut Vec<u8>) {
75 out.push(ColumnType::MYSQL_TYPE_LONG as u8);
76 out.push(0x00);
77 }
78
79 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()> {
80 write_int_4(out, *self as u32);
81 Ok(())
82 }
83}
84
85impl TypedParam for i64 {
86 fn encode_type(out: &mut Vec<u8>) {
87 out.push(ColumnType::MYSQL_TYPE_LONGLONG as u8);
88 out.push(0x00);
89 }
90
91 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()> {
92 write_int_8(out, *self as u64);
93 Ok(())
94 }
95}
96
97impl TypedParam for u8 {
98 fn encode_type(out: &mut Vec<u8>) {
99 out.push(ColumnType::MYSQL_TYPE_TINY as u8);
100 out.push(0x80);
101 }
102
103 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()> {
104 write_int_1(out, *self);
105 Ok(())
106 }
107}
108
109impl TypedParam for u16 {
110 fn encode_type(out: &mut Vec<u8>) {
111 out.push(ColumnType::MYSQL_TYPE_SHORT as u8);
112 out.push(0x80);
113 }
114
115 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()> {
116 write_int_2(out, *self);
117 Ok(())
118 }
119}
120
121impl TypedParam for u32 {
122 fn encode_type(out: &mut Vec<u8>) {
123 out.push(ColumnType::MYSQL_TYPE_LONG as u8);
124 out.push(0x80);
125 }
126
127 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()> {
128 write_int_4(out, *self);
129 Ok(())
130 }
131}
132
133impl TypedParam for u64 {
134 fn encode_type(out: &mut Vec<u8>) {
135 out.push(ColumnType::MYSQL_TYPE_LONGLONG as u8);
136 out.push(0x80);
137 }
138
139 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()> {
140 write_int_8(out, *self);
141 Ok(())
142 }
143}
144
145impl TypedParam for f32 {
146 fn encode_type(out: &mut Vec<u8>) {
147 out.push(ColumnType::MYSQL_TYPE_FLOAT as u8);
148 out.push(0x00);
149 }
150
151 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()> {
152 write_int_4(out, self.to_bits());
153 Ok(())
154 }
155}
156
157impl TypedParam for f64 {
158 fn encode_type(out: &mut Vec<u8>) {
159 out.push(ColumnType::MYSQL_TYPE_DOUBLE as u8);
160 out.push(0x00);
161 }
162
163 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()> {
164 write_int_8(out, self.to_bits());
165 Ok(())
166 }
167}
168
169impl TypedParam for &str {
170 fn encode_type(out: &mut Vec<u8>) {
171 out.push(ColumnType::MYSQL_TYPE_VAR_STRING as u8);
172 out.push(0x00);
173 }
174
175 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()> {
176 write_string_lenenc(out, self);
177 Ok(())
178 }
179}
180
181impl TypedParam for String {
182 fn encode_type(out: &mut Vec<u8>) {
183 out.push(ColumnType::MYSQL_TYPE_VAR_STRING as u8);
184 out.push(0x00);
185 }
186
187 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()> {
188 write_string_lenenc(out, self);
189 Ok(())
190 }
191}
192
193impl TypedParam for &String {
194 fn encode_type(out: &mut Vec<u8>) {
195 out.push(ColumnType::MYSQL_TYPE_VAR_STRING as u8);
196 out.push(0x00);
197 }
198
199 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()> {
200 write_string_lenenc(out, self);
201 Ok(())
202 }
203}
204
205impl TypedParam for &[u8] {
206 fn encode_type(out: &mut Vec<u8>) {
207 out.push(ColumnType::MYSQL_TYPE_BLOB as u8);
208 out.push(0x00);
209 }
210
211 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()> {
212 write_bytes_lenenc(out, self);
213 Ok(())
214 }
215}
216
217impl TypedParam for Vec<u8> {
218 fn encode_type(out: &mut Vec<u8>) {
219 out.push(ColumnType::MYSQL_TYPE_BLOB as u8);
220 out.push(0x00);
221 }
222
223 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()> {
224 write_bytes_lenenc(out, self);
225 Ok(())
226 }
227}
228
229impl TypedParam for &Vec<u8> {
230 fn encode_type(out: &mut Vec<u8>) {
231 out.push(ColumnType::MYSQL_TYPE_BLOB as u8);
232 out.push(0x00);
233 }
234
235 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()> {
236 write_bytes_lenenc(out, self);
237 Ok(())
238 }
239}
240
241impl<T: TypedParam> TypedParam for Option<T> {
242 fn is_null(&self) -> bool {
243 self.is_none()
244 }
245
246 fn encode_type(out: &mut Vec<u8>) {
247 T::encode_type(out);
248 }
249
250 fn encode_value(&self, out: &mut Vec<u8>) -> Result<()> {
251 match self {
252 Some(value) => value.encode_value(out),
253 None => Ok(()),
254 }
255 }
256}
257
258pub trait Params {
266 fn len(&self) -> usize;
268
269 fn is_empty(&self) -> bool {
270 self.len() == 0
271 }
272
273 fn encode_null_bitmap(&self, out: &mut Vec<u8>);
278
279 fn encode_types(&self, out: &mut Vec<u8>);
285
286 fn encode_values(&self, out: &mut Vec<u8>) -> Result<()>;
291
292 fn encode_values_for_bulk(&self, out: &mut Vec<u8>) -> Result<()>;
300}
301
302#[auto_impl(&)]
303pub trait TypedParams {
304 fn len(&self) -> usize;
305 fn is_empty(&self) -> bool {
306 self.len() == 0
307 }
308 fn encode_null_bitmap(&self, out: &mut Vec<u8>);
309 fn encode_types(out: &mut Vec<u8>);
310 fn encode_values(&self, out: &mut Vec<u8>) -> Result<()>;
311 fn encode_values_for_bulk(&self, out: &mut Vec<u8>) -> Result<()>;
312}
313
314impl<T: TypedParams> Params for T {
315 fn len(&self) -> usize {
316 TypedParams::len(self)
317 }
318 fn encode_null_bitmap(&self, out: &mut Vec<u8>) {
319 TypedParams::encode_null_bitmap(self, out)
320 }
321 fn encode_types(&self, out: &mut Vec<u8>) {
322 T::encode_types(out)
323 }
324 fn encode_values(&self, out: &mut Vec<u8>) -> Result<()> {
325 TypedParams::encode_values(self, out)
326 }
327 fn encode_values_for_bulk(&self, out: &mut Vec<u8>) -> Result<()> {
328 TypedParams::encode_values_for_bulk(self, out)
329 }
330}
331
332impl TypedParams for () {
333 fn len(&self) -> usize {
334 0
335 }
336 fn encode_null_bitmap(&self, _out: &mut Vec<u8>) {}
337 fn encode_types(_out: &mut Vec<u8>) {}
338 fn encode_values(&self, _out: &mut Vec<u8>) -> Result<()> {
339 Ok(())
340 }
341 fn encode_values_for_bulk(&self, _out: &mut Vec<u8>) -> Result<()> {
342 Ok(())
343 }
344}
345
346macro_rules! impl_params_for_tuple {
351 ($($T:ident : $idx:tt),+) => {
352 impl<$($T: TypedParam),+> TypedParams for ($($T,)+) {
353 fn len(&self) -> usize {
354 let mut count = 0;
355 $(
356 let _ = &self.$idx;
357 count += 1;
358 )+
359 count
360 }
361
362 fn encode_null_bitmap(&self, out: &mut Vec<u8>) {
363 let num_bytes = TypedParams::len(self).div_ceil(8);
364 let start_len = out.len();
365 out.resize(start_len + num_bytes, 0);
366
367 $(
368 if self.$idx.is_null() {
369 let byte_pos = start_len + ($idx >> 3);
370 let bit_offset = $idx & 7;
371 out[byte_pos] |= 1 << bit_offset;
372 }
373 )+
374 }
375
376 fn encode_types(out: &mut Vec<u8>) {
377 $(
378 $T::encode_type(out);
379 )+
380 }
381
382 fn encode_values(&self, out: &mut Vec<u8>) -> Result<()> {
383 $(
384 if !self.$idx.is_null() {
385 self.$idx.encode_value(out)?;
386 }
387 )+
388 Ok(())
389 }
390
391 fn encode_values_for_bulk(&self, out: &mut Vec<u8>) -> Result<()> {
392 $(
393 if self.$idx.is_null() {
394 out.push(ParamIndicator::Null as u8);
395 } else {
396 out.push(ParamIndicator::None as u8);
397 self.$idx.encode_value(out)?;
398 }
399 )+
400 Ok(())
401 }
402 }
403 };
404}
405
406impl_params_for_tuple!(T0: 0);
408impl_params_for_tuple!(T0: 0, T1: 1);
409impl_params_for_tuple!(T0: 0, T1: 1, T2: 2);
410impl_params_for_tuple!(T0: 0, T1: 1, T2: 2, T3: 3);
411impl_params_for_tuple!(T0: 0, T1: 1, T2: 2, T3: 3, T4: 4);
412impl_params_for_tuple!(T0: 0, T1: 1, T2: 2, T3: 3, T4: 4, T5: 5);
413impl_params_for_tuple!(T0: 0, T1: 1, T2: 2, T3: 3, T4: 4, T5: 5, T6: 6);
414impl_params_for_tuple!(T0: 0, T1: 1, T2: 2, T3: 3, T4: 4, T5: 5, T6: 6, T7: 7);
415impl_params_for_tuple!(T0: 0, T1: 1, T2: 2, T3: 3, T4: 4, T5: 5, T6: 6, T7: 7, T8: 8);
416impl_params_for_tuple!(T0: 0, T1: 1, T2: 2, T3: 3, T4: 4, T5: 5, T6: 6, T7: 7, T8: 8, T9: 9);
417impl_params_for_tuple!(T0: 0, T1: 1, T2: 2, T3: 3, T4: 4, T5: 5, T6: 6, T7: 7, T8: 8, T9: 9, T10: 10);
418impl_params_for_tuple!(T0: 0, T1: 1, T2: 2, T3: 3, T4: 4, T5: 5, T6: 6, T7: 7, T8: 8, T9: 9, T10: 10, T11: 11);