1use crate::constants::type_;
3use bytes::{BufMut, BytesMut};
4use thiserror::Error;
5
6#[derive(Error, Debug)]
8pub enum BindError {
9 #[error("to many arguments given")]
11 TooManyArgumentsBound,
12 #[error("missing argument")]
14 TooFewArgumentsBound,
15 #[error("try from int")]
17 TryFromInt(#[from] std::num::TryFromIntError),
18}
19
20const _: () = {
21 assert!(size_of::<BindError>() <= 8);
22};
23
24pub type BindResult<T> = Result<T, BindError>;
26
27pub struct Writer<'a>(&'a mut BytesMut);
29
30impl<'a> Writer<'a> {
31 #[allow(unused)]
33 pub(crate) fn new(w: &'a mut BytesMut) -> Self {
34 Writer(w)
35 }
36
37 #[inline]
39 pub fn put_u8(&mut self, v: u8) {
40 self.0.put_u8(v);
41 }
42
43 #[inline]
45 pub fn put_u16(&mut self, v: u16) {
46 self.0.put_u16_le(v);
47 }
48
49 #[inline]
51 pub fn put_u24(&mut self, v: u32) {
52 self.0.put_u8((v & 0xFF) as u8);
53 self.0.put_u8(((v >> 8) & 0xFF) as u8);
54 self.0.put_u8(((v >> 16) & 0xFF) as u8);
55 }
56
57 #[inline]
59 pub fn put_u32(&mut self, v: u32) {
60 self.0.put_u32_le(v);
61 }
62
63 #[inline]
65 pub fn put_u64(&mut self, v: u64) {
66 self.0.put_u64_le(v);
67 }
68
69 #[inline]
71 pub fn put_i8(&mut self, v: i8) {
72 self.0.put_i8(v);
73 }
74
75 #[inline]
77 pub fn put_i16(&mut self, v: i16) {
78 self.0.put_i16_le(v);
79 }
80
81 #[inline]
83 pub fn put_i32(&mut self, v: i32) {
84 self.0.put_i32_le(v);
85 }
86
87 #[inline]
89 pub fn put_i64(&mut self, v: i64) {
90 self.0.put_i64_le(v);
91 }
92
93 #[inline]
95 pub fn put_f32(&mut self, v: f32) {
96 self.0.put_f32_le(v);
97 }
98
99 #[inline]
101 pub fn put_f64(&mut self, v: f64) {
102 self.0.put_f64_le(v);
103 }
104
105 #[inline]
109 pub fn put_lenenc(&mut self, v: u64) {
110 if v < 0xFB {
111 self.put_u8(v as u8);
112 } else if v <= 0xFFFF {
113 self.put_u8(0xFC);
114 self.put_u16(v as u16);
115 } else if v <= 0xFFFFFF {
116 self.put_u8(0xFD);
117 self.put_u24(v as u32);
118 } else {
119 self.put_u8(0xFE);
120 self.put_u64(v);
121 }
122 }
123
124 pub fn put_slice(&mut self, src: &[u8]) {
126 self.0.put_slice(src);
127 }
128}
129
130pub trait Bind {
135 const UNSIGNED: bool = false;
137 const TYPE: u8;
139 fn bind(&self, writer: &mut Writer<'_>) -> BindResult<bool>;
143}
144
145impl Bind for u8 {
147 const UNSIGNED: bool = true;
148 const TYPE: u8 = type_::TINY;
149 #[inline]
150 fn bind(&self, writer: &mut Writer<'_>) -> BindResult<bool> {
151 writer.put_u8(*self);
152 Ok(true)
153 }
154}
155
156impl Bind for i8 {
158 const TYPE: u8 = type_::TINY;
159 #[inline]
160 fn bind(&self, writer: &mut Writer<'_>) -> BindResult<bool> {
161 writer.put_i8(*self);
162 Ok(true)
163 }
164}
165
166impl Bind for u16 {
168 const UNSIGNED: bool = true;
169 const TYPE: u8 = type_::SHORT;
170 #[inline]
171 fn bind(&self, writer: &mut Writer<'_>) -> BindResult<bool> {
172 writer.put_u16(*self);
173 Ok(true)
174 }
175}
176
177impl Bind for i16 {
179 const TYPE: u8 = type_::SHORT;
180 #[inline]
181 fn bind(&self, writer: &mut Writer<'_>) -> BindResult<bool> {
182 writer.put_i16(*self);
183 Ok(true)
184 }
185}
186
187impl Bind for u32 {
189 const UNSIGNED: bool = true;
190 const TYPE: u8 = type_::LONG;
191 #[inline]
192 fn bind(&self, writer: &mut Writer<'_>) -> BindResult<bool> {
193 writer.put_u32(*self);
194 Ok(true)
195 }
196}
197
198impl Bind for i32 {
200 const TYPE: u8 = type_::LONG;
201 #[inline]
202 fn bind(&self, writer: &mut Writer<'_>) -> BindResult<bool> {
203 writer.put_i32(*self);
204 Ok(true)
205 }
206}
207
208impl Bind for u64 {
210 const UNSIGNED: bool = true;
211 const TYPE: u8 = type_::LONG_LONG;
212 #[inline]
213 fn bind(&self, writer: &mut Writer<'_>) -> BindResult<bool> {
214 writer.put_u64(*self);
215 Ok(true)
216 }
217}
218
219impl Bind for i64 {
221 const TYPE: u8 = type_::LONG_LONG;
222 #[inline]
223 fn bind(&self, writer: &mut Writer<'_>) -> BindResult<bool> {
224 writer.put_i64(*self);
225 Ok(true)
226 }
227}
228
229impl Bind for f32 {
231 const TYPE: u8 = type_::FLOAT;
232 #[inline]
233 fn bind(&self, writer: &mut Writer<'_>) -> BindResult<bool> {
234 writer.put_f32(*self);
235 Ok(true)
236 }
237}
238
239impl Bind for f64 {
241 const TYPE: u8 = type_::DOUBLE;
242 #[inline]
243 fn bind(&self, writer: &mut Writer<'_>) -> BindResult<bool> {
244 writer.put_f64(*self);
245 Ok(true)
246 }
247}
248
249impl Bind for bool {
251 const UNSIGNED: bool = true;
252 const TYPE: u8 = type_::TINY;
253 #[inline]
254 fn bind(&self, writer: &mut Writer<'_>) -> BindResult<bool> {
255 writer.put_u8(*self as u8);
256 Ok(true)
257 }
258}
259
260impl Bind for String {
262 const TYPE: u8 = type_::STRING;
263 #[inline]
264 fn bind(&self, writer: &mut Writer<'_>) -> BindResult<bool> {
265 writer.put_lenenc(self.len() as u64);
266 writer.put_slice(self.as_bytes());
267 Ok(true)
268 }
269}
270
271impl Bind for str {
273 const TYPE: u8 = type_::STRING;
274 #[inline]
275 fn bind(&self, writer: &mut Writer<'_>) -> BindResult<bool> {
276 writer.put_lenenc(self.len() as u64);
277 writer.put_slice(self.as_bytes());
278 Ok(true)
279 }
280}
281
282impl Bind for Vec<u8> {
284 const TYPE: u8 = type_::BLOB;
285 #[inline]
286 fn bind(&self, writer: &mut Writer<'_>) -> BindResult<bool> {
287 writer.put_lenenc(self.len() as u64);
288 writer.put_slice(self);
289 Ok(true)
290 }
291}
292
293impl Bind for [u8] {
295 const TYPE: u8 = type_::BLOB;
296 #[inline]
297 fn bind(&self, writer: &mut Writer<'_>) -> BindResult<bool> {
298 writer.put_lenenc(self.len() as u64);
299 writer.put_slice(self);
300 Ok(true)
301 }
302}
303
304impl<T: Bind> Bind for Option<T> {
306 const TYPE: u8 = T::TYPE;
307 const UNSIGNED: bool = T::UNSIGNED;
308
309 #[inline]
310 fn bind(&self, writer: &mut Writer<'_>) -> BindResult<bool> {
311 match self {
312 Some(v) => v.bind(writer),
313 None => Ok(false),
314 }
315 }
316}
317
318impl<T: Bind + ?Sized> Bind for &T {
320 const TYPE: u8 = T::TYPE;
321 const UNSIGNED: bool = T::UNSIGNED;
322
323 #[inline]
324 fn bind(&self, writer: &mut Writer<'_>) -> BindResult<bool> {
325 (*self).bind(writer)
326 }
327}
328
329pub trait ListBind {
331 type T: Bind + ?Sized;
333
334 fn single(&self) -> &Self::T;
337
338 fn get(&self, idx: usize) -> &Self::T;
340
341 fn list_length(&self) -> Option<usize>;
343}
344
345impl<T: Bind + ?Sized> ListBind for T {
346 type T = T;
347
348 #[inline]
349 fn single(&self) -> &Self::T {
350 self
351 }
352
353 #[inline]
354 fn get(&self, _: usize) -> &Self::T {
355 panic!("Singular")
356 }
357
358 #[inline]
359 fn list_length(&self) -> Option<usize> {
360 None
361 }
362}
363
364pub struct List<'a, T> {
366 inner: &'a [T],
368}
369
370impl<'a, T: Bind> ListBind for List<'a, T> {
371 type T = T;
372
373 #[inline]
374 fn single(&self) -> &Self::T {
375 panic!("List")
376 }
377
378 #[inline]
379 fn get(&self, idx: usize) -> &Self::T {
380 &self.inner[idx]
381 }
382
383 #[inline]
384 fn list_length(&self) -> Option<usize> {
385 Some(self.inner.len())
386 }
387}
388
389impl<'a, T: Bind> ListBind for &List<'a, T> {
390 type T = T;
391
392 #[inline]
393 fn single(&self) -> &Self::T {
394 panic!("List")
395 }
396
397 #[inline]
398 fn get(&self, idx: usize) -> &Self::T {
399 &self.inner[idx]
400 }
401
402 #[inline]
403 fn list_length(&self) -> Option<usize> {
404 Some(self.inner.len())
405 }
406}
407
408#[cfg(feature = "list_hack")]
421pub fn list<'a, T: Bind>(v: &'a [T]) -> List<'a, T> {
422 List { inner: v }
423}
424
425#[cfg(not(feature = "list_hack"))]
428pub fn list<'a, T: Bind>(_: &'a [T]) -> std::convert::Infallible {
429 panic!("The list_hack feature is not")
430}