1use crate::DriverError;
9
10pub trait Encode {
27 fn encode_binary(&self, buf: &mut Vec<u8>);
29
30 fn type_oid(&self) -> u32;
32
33 fn is_null(&self) -> bool {
38 false
39 }
40
41 fn encode_at(&self, dst: &mut [u8]) -> bool {
51 let mut tmp = Vec::with_capacity(dst.len());
53 self.encode_binary(&mut tmp);
54 if tmp.len() == dst.len() {
55 dst.copy_from_slice(&tmp);
56 true
57 } else {
58 false
59 }
60 }
61}
62
63impl Encode for bool {
66 #[inline]
67 fn encode_binary(&self, buf: &mut Vec<u8>) {
68 buf.push(if *self { 1 } else { 0 });
69 }
70
71 #[inline]
72 fn type_oid(&self) -> u32 {
73 16 }
75
76 #[inline]
77 fn encode_at(&self, dst: &mut [u8]) -> bool {
78 if dst.len() != 1 {
79 return false;
80 }
81 dst[0] = if *self { 1 } else { 0 };
82 true
83 }
84}
85
86impl Encode for i16 {
87 #[inline]
88 fn encode_binary(&self, buf: &mut Vec<u8>) {
89 buf.extend_from_slice(&self.to_be_bytes());
90 }
91
92 #[inline]
93 fn type_oid(&self) -> u32 {
94 21 }
96
97 #[inline]
98 fn encode_at(&self, dst: &mut [u8]) -> bool {
99 if dst.len() != 2 {
100 return false;
101 }
102 dst.copy_from_slice(&self.to_be_bytes());
103 true
104 }
105}
106
107impl Encode for i32 {
108 #[inline]
109 fn encode_binary(&self, buf: &mut Vec<u8>) {
110 buf.extend_from_slice(&self.to_be_bytes());
111 }
112
113 #[inline]
114 fn type_oid(&self) -> u32 {
115 23 }
117
118 #[inline]
119 fn encode_at(&self, dst: &mut [u8]) -> bool {
120 if dst.len() != 4 {
121 return false;
122 }
123 dst.copy_from_slice(&self.to_be_bytes());
124 true
125 }
126}
127
128impl Encode for i64 {
129 #[inline]
130 fn encode_binary(&self, buf: &mut Vec<u8>) {
131 buf.extend_from_slice(&self.to_be_bytes());
132 }
133
134 #[inline]
135 fn type_oid(&self) -> u32 {
136 20 }
138
139 #[inline]
140 fn encode_at(&self, dst: &mut [u8]) -> bool {
141 if dst.len() != 8 {
142 return false;
143 }
144 dst.copy_from_slice(&self.to_be_bytes());
145 true
146 }
147}
148
149impl Encode for f32 {
150 #[inline]
151 fn encode_binary(&self, buf: &mut Vec<u8>) {
152 buf.extend_from_slice(&self.to_be_bytes());
153 }
154
155 #[inline]
156 fn type_oid(&self) -> u32 {
157 700 }
159
160 #[inline]
161 fn encode_at(&self, dst: &mut [u8]) -> bool {
162 if dst.len() != 4 {
163 return false;
164 }
165 dst.copy_from_slice(&self.to_be_bytes());
166 true
167 }
168}
169
170impl Encode for f64 {
171 #[inline]
172 fn encode_binary(&self, buf: &mut Vec<u8>) {
173 buf.extend_from_slice(&self.to_be_bytes());
174 }
175
176 #[inline]
177 fn type_oid(&self) -> u32 {
178 701 }
180
181 #[inline]
182 fn encode_at(&self, dst: &mut [u8]) -> bool {
183 if dst.len() != 8 {
184 return false;
185 }
186 dst.copy_from_slice(&self.to_be_bytes());
187 true
188 }
189}
190
191impl Encode for &str {
192 #[inline]
193 fn encode_binary(&self, buf: &mut Vec<u8>) {
194 buf.extend_from_slice(self.as_bytes());
195 }
196
197 #[inline]
198 fn type_oid(&self) -> u32 {
199 25 }
201}
202
203impl Encode for String {
204 #[inline]
205 fn encode_binary(&self, buf: &mut Vec<u8>) {
206 buf.extend_from_slice(self.as_bytes());
207 }
208
209 #[inline]
210 fn type_oid(&self) -> u32 {
211 25 }
213}
214
215impl Encode for &[u8] {
216 #[inline]
217 fn encode_binary(&self, buf: &mut Vec<u8>) {
218 buf.extend_from_slice(self);
219 }
220
221 #[inline]
222 fn type_oid(&self) -> u32 {
223 17 }
225}
226
227impl Encode for Vec<u8> {
228 #[inline]
229 fn encode_binary(&self, buf: &mut Vec<u8>) {
230 buf.extend_from_slice(self);
231 }
232
233 #[inline]
234 fn type_oid(&self) -> u32 {
235 17 }
237}
238
239impl Encode for u32 {
240 #[inline]
241 fn encode_binary(&self, buf: &mut Vec<u8>) {
242 buf.extend_from_slice(&self.to_be_bytes());
243 }
244
245 #[inline]
246 fn type_oid(&self) -> u32 {
247 26 }
249
250 #[inline]
251 fn encode_at(&self, dst: &mut [u8]) -> bool {
252 if dst.len() != 4 {
253 return false;
254 }
255 dst.copy_from_slice(&self.to_be_bytes());
256 true
257 }
258}
259
260impl<T: Encode> Encode for Option<T> {
263 #[inline]
264 fn encode_binary(&self, buf: &mut Vec<u8>) {
265 if let Some(val) = self {
266 val.encode_binary(buf);
267 }
268 }
271
272 #[inline]
273 fn type_oid(&self) -> u32 {
274 match self {
279 Some(val) => val.type_oid(),
280 None => 0,
281 }
282 }
283
284 #[inline]
285 fn is_null(&self) -> bool {
286 self.is_none()
287 }
288}
289
290#[cfg(feature = "uuid")]
293impl Encode for uuid::Uuid {
294 #[inline]
295 fn encode_binary(&self, buf: &mut Vec<u8>) {
296 buf.extend_from_slice(self.as_bytes());
297 }
298
299 #[inline]
300 fn type_oid(&self) -> u32 {
301 2950 }
303
304 #[inline]
305 fn encode_at(&self, dst: &mut [u8]) -> bool {
306 if dst.len() != 16 {
307 return false;
308 }
309 dst.copy_from_slice(self.as_bytes());
310 true
311 }
312}
313
314#[cfg(feature = "time")]
315impl Encode for time::OffsetDateTime {
316 #[inline]
317 fn encode_binary(&self, buf: &mut Vec<u8>) {
318 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
319 }
320
321 #[inline]
322 fn type_oid(&self) -> u32 {
323 1184 }
325
326 #[inline]
327 fn encode_at(&self, dst: &mut [u8]) -> bool {
328 if dst.len() != 8 {
329 return false;
330 }
331 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
332 true
333 }
334}
335
336#[cfg(feature = "time")]
337trait OffsetDateTimeExt {
338 fn encode_pg_micros(&self) -> i64;
339}
340
341#[cfg(feature = "time")]
342impl OffsetDateTimeExt for time::OffsetDateTime {
343 #[inline]
344 fn encode_pg_micros(&self) -> i64 {
345 let pg_epoch =
348 time::OffsetDateTime::from_unix_timestamp(946_684_800).expect("PG epoch is valid");
349 let diff = *self - pg_epoch;
350 let micros_128 = diff.whole_microseconds();
351 if micros_128 >= i64::MIN as i128 && micros_128 <= i64::MAX as i128 {
352 micros_128 as i64
353 } else {
354 if micros_128 < 0 { i64::MIN } else { i64::MAX }
355 }
356 }
357}
358
359#[cfg(feature = "time")]
360impl Encode for time::Date {
361 #[inline]
362 fn encode_binary(&self, buf: &mut Vec<u8>) {
363 buf.extend_from_slice(&self.encode_pg_days().to_be_bytes());
364 }
365
366 #[inline]
367 fn type_oid(&self) -> u32 {
368 1082 }
370
371 #[inline]
372 fn encode_at(&self, dst: &mut [u8]) -> bool {
373 if dst.len() != 4 {
374 return false;
375 }
376 dst.copy_from_slice(&self.encode_pg_days().to_be_bytes());
377 true
378 }
379}
380
381#[cfg(feature = "time")]
382trait DateExt {
383 fn encode_pg_days(&self) -> i32;
384}
385
386#[cfg(feature = "time")]
387impl DateExt for time::Date {
388 #[inline]
389 fn encode_pg_days(&self) -> i32 {
390 let pg_epoch = time::Date::from_calendar_date(2000, time::Month::January, 1)
392 .expect("PG epoch date is valid");
393 let days_i64 = (*self - pg_epoch).whole_days();
394 i32::try_from(days_i64).unwrap_or(if days_i64 < 0 { i32::MIN } else { i32::MAX })
395 }
396}
397
398#[cfg(feature = "time")]
399impl Encode for time::Time {
400 #[inline]
401 fn encode_binary(&self, buf: &mut Vec<u8>) {
402 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
403 }
404
405 #[inline]
406 fn type_oid(&self) -> u32 {
407 1083 }
409
410 #[inline]
411 fn encode_at(&self, dst: &mut [u8]) -> bool {
412 if dst.len() != 8 {
413 return false;
414 }
415 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
416 true
417 }
418}
419
420#[cfg(feature = "time")]
421trait TimeExt {
422 fn encode_pg_micros(&self) -> i64;
423}
424
425#[cfg(feature = "time")]
426impl TimeExt for time::Time {
427 #[inline]
428 fn encode_pg_micros(&self) -> i64 {
429 let midnight = time::Time::MIDNIGHT;
431 let diff = *self - midnight;
432 diff.whole_microseconds() as i64
433 }
434}
435
436#[cfg(feature = "time")]
437impl Encode for time::PrimitiveDateTime {
438 #[inline]
439 fn encode_binary(&self, buf: &mut Vec<u8>) {
440 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
441 }
442
443 #[inline]
444 fn type_oid(&self) -> u32 {
445 1114 }
447
448 #[inline]
449 fn encode_at(&self, dst: &mut [u8]) -> bool {
450 if dst.len() != 8 {
451 return false;
452 }
453 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
454 true
455 }
456}
457
458#[cfg(feature = "time")]
459trait PrimitiveDateTimeExt {
460 fn encode_pg_micros(&self) -> i64;
461}
462
463#[cfg(feature = "time")]
464impl PrimitiveDateTimeExt for time::PrimitiveDateTime {
465 #[inline]
466 fn encode_pg_micros(&self) -> i64 {
467 let pg_epoch =
470 time::OffsetDateTime::from_unix_timestamp(946_684_800).expect("PG epoch is valid");
471 let as_utc = self.assume_utc();
472 let diff = as_utc - pg_epoch;
473 let micros_128 = diff.whole_microseconds();
474 if micros_128 >= i64::MIN as i128 && micros_128 <= i64::MAX as i128 {
475 micros_128 as i64
476 } else {
477 if micros_128 < 0 { i64::MIN } else { i64::MAX }
478 }
479 }
480}
481
482#[cfg(feature = "chrono")]
483impl Encode for chrono::NaiveDateTime {
484 #[inline]
485 fn encode_binary(&self, buf: &mut Vec<u8>) {
486 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
487 }
488
489 #[inline]
490 fn type_oid(&self) -> u32 {
491 1114 }
493
494 #[inline]
495 fn encode_at(&self, dst: &mut [u8]) -> bool {
496 if dst.len() != 8 {
497 return false;
498 }
499 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
500 true
501 }
502}
503
504#[cfg(feature = "chrono")]
505trait NaiveDateTimeExt {
506 fn encode_pg_micros(&self) -> i64;
507}
508
509#[cfg(feature = "chrono")]
510impl NaiveDateTimeExt for chrono::NaiveDateTime {
511 #[inline]
512 fn encode_pg_micros(&self) -> i64 {
513 let pg_epoch_unix_micros: i64 = 946_684_800 * 1_000_000;
515 let unix_micros = self.and_utc().timestamp_micros();
516 unix_micros.saturating_sub(pg_epoch_unix_micros)
517 }
518}
519
520#[cfg(feature = "chrono")]
521impl Encode for chrono::DateTime<chrono::Utc> {
522 #[inline]
523 fn encode_binary(&self, buf: &mut Vec<u8>) {
524 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
525 }
526
527 #[inline]
528 fn type_oid(&self) -> u32 {
529 1184 }
531
532 #[inline]
533 fn encode_at(&self, dst: &mut [u8]) -> bool {
534 if dst.len() != 8 {
535 return false;
536 }
537 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
538 true
539 }
540}
541
542#[cfg(feature = "chrono")]
543trait ChronoDateTimeUtcExt {
544 fn encode_pg_micros(&self) -> i64;
545}
546
547#[cfg(feature = "chrono")]
548impl ChronoDateTimeUtcExt for chrono::DateTime<chrono::Utc> {
549 #[inline]
550 fn encode_pg_micros(&self) -> i64 {
551 let pg_epoch_unix_micros: i64 = 946_684_800 * 1_000_000;
553 let unix_micros = self.timestamp_micros();
554 unix_micros.saturating_sub(pg_epoch_unix_micros)
555 }
556}
557
558#[cfg(feature = "chrono")]
559impl Encode for chrono::NaiveDate {
560 #[inline]
561 fn encode_binary(&self, buf: &mut Vec<u8>) {
562 buf.extend_from_slice(&self.encode_pg_days().to_be_bytes());
563 }
564
565 #[inline]
566 fn type_oid(&self) -> u32 {
567 1082 }
569
570 #[inline]
571 fn encode_at(&self, dst: &mut [u8]) -> bool {
572 if dst.len() != 4 {
573 return false;
574 }
575 dst.copy_from_slice(&self.encode_pg_days().to_be_bytes());
576 true
577 }
578}
579
580#[cfg(feature = "chrono")]
581trait ChronoNaiveDateExt {
582 fn encode_pg_days(&self) -> i32;
583}
584
585#[cfg(feature = "chrono")]
586impl ChronoNaiveDateExt for chrono::NaiveDate {
587 #[inline]
588 fn encode_pg_days(&self) -> i32 {
589 let pg_epoch = chrono::NaiveDate::from_ymd_opt(2000, 1, 1).expect("PG epoch date valid");
590 let days_i64 = (*self - pg_epoch).num_days();
591 i32::try_from(days_i64).unwrap_or(if days_i64 < 0 { i32::MIN } else { i32::MAX })
592 }
593}
594
595#[cfg(feature = "chrono")]
596impl Encode for chrono::NaiveTime {
597 #[inline]
598 fn encode_binary(&self, buf: &mut Vec<u8>) {
599 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
600 }
601
602 #[inline]
603 fn type_oid(&self) -> u32 {
604 1083 }
606
607 #[inline]
608 fn encode_at(&self, dst: &mut [u8]) -> bool {
609 if dst.len() != 8 {
610 return false;
611 }
612 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
613 true
614 }
615}
616
617#[cfg(feature = "chrono")]
618trait ChronoNaiveTimeExt {
619 fn encode_pg_micros(&self) -> i64;
620}
621
622#[cfg(feature = "chrono")]
623impl ChronoNaiveTimeExt for chrono::NaiveTime {
624 #[inline]
625 fn encode_pg_micros(&self) -> i64 {
626 let midnight = chrono::NaiveTime::from_hms_opt(0, 0, 0).expect("midnight is always valid");
628 let diff = *self - midnight;
629 diff.num_microseconds()
631 .expect("time-of-day difference always fits i64")
632 }
633}
634
635#[cfg(feature = "decimal")]
636impl Encode for rust_decimal::Decimal {
637 fn encode_binary(&self, buf: &mut Vec<u8>) {
638 if self.is_zero() {
648 let dscale = i16::try_from(self.scale()).unwrap_or(i16::MAX);
650 buf.extend_from_slice(&0i16.to_be_bytes()); buf.extend_from_slice(&0i16.to_be_bytes()); buf.extend_from_slice(&0x0000i16.to_be_bytes()); buf.extend_from_slice(&dscale.to_be_bytes()); return;
655 }
656
657 let sign: i16 = if self.is_sign_negative() {
658 0x4000
659 } else {
660 0x0000
661 };
662 let scale = self.scale();
663
664 let abs = self.abs();
666 let mut mantissa = abs.mantissa().unsigned_abs();
667
668 let mut decimal_digits: smallvec::SmallVec<[i16; 32]> = smallvec::SmallVec::new();
670 while mantissa > 0 {
671 decimal_digits.push((mantissa % 10) as i16);
672 mantissa /= 10;
673 }
674 decimal_digits.reverse();
675
676 let total_digits = decimal_digits.len();
680 let int_len = total_digits.saturating_sub(scale as usize);
681
682 let int_pad = if int_len > 0 {
684 (4 - (int_len % 4)) % 4
685 } else {
686 0
687 };
688 let frac_len = total_digits - int_len;
690 let frac_pad = (4 - (frac_len % 4)) % 4;
691
692 let mut padded: smallvec::SmallVec<[i16; 32]> = smallvec::SmallVec::new();
693 padded.extend(std::iter::repeat_n(0i16, int_pad));
694 padded.extend_from_slice(&decimal_digits);
695 padded.extend(std::iter::repeat_n(0i16, frac_pad));
696
697 let mut pg_digits: smallvec::SmallVec<[i16; 12]> = smallvec::SmallVec::new();
699 for chunk in padded.chunks(4) {
700 let d = chunk[0] * 1000 + chunk[1] * 100 + chunk[2] * 10 + chunk[3];
701 pg_digits.push(d);
702 }
703
704 let int_groups = (int_len + int_pad) / 4;
706 while pg_digits.len() > int_groups && pg_digits.last().copied() == Some(0) {
707 pg_digits.pop();
708 }
709
710 let ndigits = pg_digits.len() as i16;
711
712 let weight: i16 = if int_len > 0 {
715 let w = ((int_len + int_pad) / 4 - 1) as i32;
716 w.clamp(i16::MIN as i32, i16::MAX as i32) as i16
717 } else {
718 let w = -((scale as usize - frac_len + frac_pad) as i32 / 4 + 1);
721 w.clamp(i16::MIN as i32, i16::MAX as i32) as i16
723 };
724
725 let dscale = i16::try_from(scale).unwrap_or(i16::MAX);
726 buf.extend_from_slice(&ndigits.to_be_bytes());
727 buf.extend_from_slice(&weight.to_be_bytes());
728 buf.extend_from_slice(&sign.to_be_bytes());
729 buf.extend_from_slice(&dscale.to_be_bytes());
730 for d in &pg_digits {
731 buf.extend_from_slice(&d.to_be_bytes());
732 }
733 }
734
735 #[inline]
736 fn type_oid(&self) -> u32 {
737 1700 }
739}
740
741#[inline]
749pub fn decode_bool(data: &[u8]) -> Result<bool, DriverError> {
750 if data.len() != 1 {
751 return Err(DriverError::Protocol(format!(
752 "bool: expected 1 byte, got {}",
753 data.len()
754 )));
755 }
756 Ok(data[0] != 0)
757}
758
759#[inline]
761pub fn decode_i16(data: &[u8]) -> Result<i16, DriverError> {
762 if data.len() != 2 {
763 return Err(DriverError::Protocol(format!(
764 "i16: expected 2 bytes, got {}",
765 data.len()
766 )));
767 }
768 Ok(i16::from_be_bytes([data[0], data[1]]))
769}
770
771#[inline]
773pub fn decode_i32(data: &[u8]) -> Result<i32, DriverError> {
774 if data.len() != 4 {
775 return Err(DriverError::Protocol(format!(
776 "i32: expected 4 bytes, got {}",
777 data.len()
778 )));
779 }
780 Ok(i32::from_be_bytes([data[0], data[1], data[2], data[3]]))
781}
782
783#[inline]
785pub fn decode_i64(data: &[u8]) -> Result<i64, DriverError> {
786 if data.len() != 8 {
787 return Err(DriverError::Protocol(format!(
788 "i64: expected 8 bytes, got {}",
789 data.len()
790 )));
791 }
792 Ok(i64::from_be_bytes([
793 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
794 ]))
795}
796
797#[inline]
799pub fn decode_f32(data: &[u8]) -> Result<f32, DriverError> {
800 if data.len() != 4 {
801 return Err(DriverError::Protocol(format!(
802 "f32: expected 4 bytes, got {}",
803 data.len()
804 )));
805 }
806 Ok(f32::from_be_bytes([data[0], data[1], data[2], data[3]]))
807}
808
809#[inline]
811pub fn decode_f64(data: &[u8]) -> Result<f64, DriverError> {
812 if data.len() != 8 {
813 return Err(DriverError::Protocol(format!(
814 "f64: expected 8 bytes, got {}",
815 data.len()
816 )));
817 }
818 Ok(f64::from_be_bytes([
819 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
820 ]))
821}
822
823#[inline]
829pub fn decode_str(data: &[u8]) -> Result<&str, DriverError> {
830 simdutf8::basic::from_utf8(data)
831 .map_err(|e| DriverError::Protocol(format!("invalid UTF-8 in text column: {e}")))
832}
833
834#[inline]
836pub fn decode_bytes(data: &[u8]) -> &[u8] {
837 data
838}
839
840#[inline]
842pub fn decode_uuid(data: &[u8]) -> Result<[u8; 16], DriverError> {
843 if data.len() != 16 {
844 return Err(DriverError::Protocol(format!(
845 "uuid: expected 16 bytes, got {}",
846 data.len()
847 )));
848 }
849 let mut uuid = [0u8; 16];
850 uuid.copy_from_slice(data);
851 Ok(uuid)
852}
853
854pub fn encode_param(buf: &mut Vec<u8>, param: &dyn Encode) {
858 let start = buf.len();
859 buf.extend_from_slice(&[0u8; 4]); param.encode_binary(buf);
861 let data_len = (buf.len() - start - 4) as i32;
862 buf[start..start + 4].copy_from_slice(&data_len.to_be_bytes());
863}
864
865fn encode_array_header(buf: &mut Vec<u8>, n_elements: usize, elem_oid: u32) {
872 if n_elements == 0 {
873 buf.extend_from_slice(&0i32.to_be_bytes()); buf.extend_from_slice(&0i32.to_be_bytes()); buf.extend_from_slice(&(elem_oid as i32).to_be_bytes()); return;
877 }
878 buf.extend_from_slice(&1i32.to_be_bytes()); buf.extend_from_slice(&0i32.to_be_bytes()); buf.extend_from_slice(&(elem_oid as i32).to_be_bytes()); buf.extend_from_slice(&(n_elements as i32).to_be_bytes()); buf.extend_from_slice(&1i32.to_be_bytes()); }
884
885impl Encode for [bool] {
888 fn encode_binary(&self, buf: &mut Vec<u8>) {
889 encode_array_header(buf, self.len(), 16);
890 for val in self {
891 buf.extend_from_slice(&1i32.to_be_bytes()); buf.push(if *val { 1 } else { 0 });
893 }
894 }
895
896 #[inline]
897 fn type_oid(&self) -> u32 {
898 1000 }
900}
901
902impl Encode for &[bool] {
903 #[inline]
904 fn encode_binary(&self, buf: &mut Vec<u8>) {
905 (**self).encode_binary(buf);
906 }
907
908 #[inline]
909 fn type_oid(&self) -> u32 {
910 1000
911 }
912}
913
914impl Encode for Vec<bool> {
915 #[inline]
916 fn encode_binary(&self, buf: &mut Vec<u8>) {
917 self.as_slice().encode_binary(buf);
918 }
919
920 #[inline]
921 fn type_oid(&self) -> u32 {
922 1000
923 }
924}
925
926impl Encode for [i16] {
927 fn encode_binary(&self, buf: &mut Vec<u8>) {
928 encode_array_header(buf, self.len(), 21);
929 for val in self {
930 buf.extend_from_slice(&2i32.to_be_bytes()); buf.extend_from_slice(&val.to_be_bytes());
932 }
933 }
934
935 #[inline]
936 fn type_oid(&self) -> u32 {
937 1005 }
939}
940
941impl Encode for &[i16] {
942 #[inline]
943 fn encode_binary(&self, buf: &mut Vec<u8>) {
944 (**self).encode_binary(buf);
945 }
946
947 #[inline]
948 fn type_oid(&self) -> u32 {
949 1005
950 }
951}
952
953impl Encode for Vec<i16> {
954 #[inline]
955 fn encode_binary(&self, buf: &mut Vec<u8>) {
956 self.as_slice().encode_binary(buf);
957 }
958
959 #[inline]
960 fn type_oid(&self) -> u32 {
961 1005
962 }
963}
964
965impl Encode for [i32] {
966 fn encode_binary(&self, buf: &mut Vec<u8>) {
967 encode_array_header(buf, self.len(), 23);
968 for val in self {
969 buf.extend_from_slice(&4i32.to_be_bytes()); buf.extend_from_slice(&val.to_be_bytes());
971 }
972 }
973
974 #[inline]
975 fn type_oid(&self) -> u32 {
976 1007 }
978}
979
980impl Encode for &[i32] {
981 #[inline]
982 fn encode_binary(&self, buf: &mut Vec<u8>) {
983 (**self).encode_binary(buf);
984 }
985
986 #[inline]
987 fn type_oid(&self) -> u32 {
988 1007
989 }
990}
991
992impl Encode for Vec<i32> {
993 #[inline]
994 fn encode_binary(&self, buf: &mut Vec<u8>) {
995 self.as_slice().encode_binary(buf);
996 }
997
998 #[inline]
999 fn type_oid(&self) -> u32 {
1000 1007
1001 }
1002}
1003
1004impl Encode for [i64] {
1005 fn encode_binary(&self, buf: &mut Vec<u8>) {
1006 encode_array_header(buf, self.len(), 20);
1007 for val in self {
1008 buf.extend_from_slice(&8i32.to_be_bytes()); buf.extend_from_slice(&val.to_be_bytes());
1010 }
1011 }
1012
1013 #[inline]
1014 fn type_oid(&self) -> u32 {
1015 1016 }
1017}
1018
1019impl Encode for &[i64] {
1020 #[inline]
1021 fn encode_binary(&self, buf: &mut Vec<u8>) {
1022 (**self).encode_binary(buf);
1023 }
1024
1025 #[inline]
1026 fn type_oid(&self) -> u32 {
1027 1016
1028 }
1029}
1030
1031impl Encode for Vec<i64> {
1032 #[inline]
1033 fn encode_binary(&self, buf: &mut Vec<u8>) {
1034 self.as_slice().encode_binary(buf);
1035 }
1036
1037 #[inline]
1038 fn type_oid(&self) -> u32 {
1039 1016
1040 }
1041}
1042
1043impl Encode for [f32] {
1044 fn encode_binary(&self, buf: &mut Vec<u8>) {
1045 encode_array_header(buf, self.len(), 700);
1046 for val in self {
1047 buf.extend_from_slice(&4i32.to_be_bytes()); buf.extend_from_slice(&val.to_be_bytes());
1049 }
1050 }
1051
1052 #[inline]
1053 fn type_oid(&self) -> u32 {
1054 1021 }
1056}
1057
1058impl Encode for &[f32] {
1059 #[inline]
1060 fn encode_binary(&self, buf: &mut Vec<u8>) {
1061 (**self).encode_binary(buf);
1062 }
1063
1064 #[inline]
1065 fn type_oid(&self) -> u32 {
1066 1021
1067 }
1068}
1069
1070impl Encode for Vec<f32> {
1071 #[inline]
1072 fn encode_binary(&self, buf: &mut Vec<u8>) {
1073 self.as_slice().encode_binary(buf);
1074 }
1075
1076 #[inline]
1077 fn type_oid(&self) -> u32 {
1078 1021
1079 }
1080}
1081
1082impl Encode for [f64] {
1083 fn encode_binary(&self, buf: &mut Vec<u8>) {
1084 encode_array_header(buf, self.len(), 701);
1085 for val in self {
1086 buf.extend_from_slice(&8i32.to_be_bytes()); buf.extend_from_slice(&val.to_be_bytes());
1088 }
1089 }
1090
1091 #[inline]
1092 fn type_oid(&self) -> u32 {
1093 1022 }
1095}
1096
1097impl Encode for &[f64] {
1098 #[inline]
1099 fn encode_binary(&self, buf: &mut Vec<u8>) {
1100 (**self).encode_binary(buf);
1101 }
1102
1103 #[inline]
1104 fn type_oid(&self) -> u32 {
1105 1022
1106 }
1107}
1108
1109impl Encode for Vec<f64> {
1110 #[inline]
1111 fn encode_binary(&self, buf: &mut Vec<u8>) {
1112 self.as_slice().encode_binary(buf);
1113 }
1114
1115 #[inline]
1116 fn type_oid(&self) -> u32 {
1117 1022
1118 }
1119}
1120
1121impl Encode for [&str] {
1122 fn encode_binary(&self, buf: &mut Vec<u8>) {
1123 encode_array_header(buf, self.len(), 25);
1124 for val in self {
1125 let bytes = val.as_bytes();
1126 buf.extend_from_slice(&(bytes.len() as i32).to_be_bytes());
1127 buf.extend_from_slice(bytes);
1128 }
1129 }
1130
1131 #[inline]
1132 fn type_oid(&self) -> u32 {
1133 1009 }
1135}
1136
1137impl Encode for &[&str] {
1138 #[inline]
1139 fn encode_binary(&self, buf: &mut Vec<u8>) {
1140 (**self).encode_binary(buf);
1141 }
1142
1143 #[inline]
1144 fn type_oid(&self) -> u32 {
1145 1009
1146 }
1147}
1148
1149impl Encode for Vec<String> {
1150 fn encode_binary(&self, buf: &mut Vec<u8>) {
1151 encode_array_header(buf, self.len(), 25);
1152 for val in self {
1153 let bytes = val.as_bytes();
1154 buf.extend_from_slice(&(bytes.len() as i32).to_be_bytes());
1155 buf.extend_from_slice(bytes);
1156 }
1157 }
1158
1159 #[inline]
1160 fn type_oid(&self) -> u32 {
1161 1009 }
1163}
1164
1165impl Encode for [&[u8]] {
1166 fn encode_binary(&self, buf: &mut Vec<u8>) {
1167 encode_array_header(buf, self.len(), 17);
1168 for val in self {
1169 buf.extend_from_slice(&(val.len() as i32).to_be_bytes());
1170 buf.extend_from_slice(val);
1171 }
1172 }
1173
1174 #[inline]
1175 fn type_oid(&self) -> u32 {
1176 1001 }
1178}
1179
1180impl Encode for &[&[u8]] {
1181 #[inline]
1182 fn encode_binary(&self, buf: &mut Vec<u8>) {
1183 (**self).encode_binary(buf);
1184 }
1185
1186 #[inline]
1187 fn type_oid(&self) -> u32 {
1188 1001
1189 }
1190}
1191
1192impl Encode for [Vec<u8>] {
1193 fn encode_binary(&self, buf: &mut Vec<u8>) {
1194 encode_array_header(buf, self.len(), 17);
1195 for val in self {
1196 buf.extend_from_slice(&(val.len() as i32).to_be_bytes());
1197 buf.extend_from_slice(val);
1198 }
1199 }
1200
1201 #[inline]
1202 fn type_oid(&self) -> u32 {
1203 1001 }
1205}
1206
1207impl Encode for &[Vec<u8>] {
1208 #[inline]
1209 fn encode_binary(&self, buf: &mut Vec<u8>) {
1210 (**self).encode_binary(buf);
1211 }
1212
1213 #[inline]
1214 fn type_oid(&self) -> u32 {
1215 1001
1216 }
1217}
1218
1219impl Encode for Vec<Vec<u8>> {
1220 #[inline]
1221 fn encode_binary(&self, buf: &mut Vec<u8>) {
1222 self.as_slice().encode_binary(buf);
1223 }
1224
1225 #[inline]
1226 fn type_oid(&self) -> u32 {
1227 1001 }
1229}
1230
1231fn decode_array_elements(data: &[u8]) -> Result<Vec<&[u8]>, DriverError> {
1242 if data.len() < 12 {
1243 return Err(DriverError::Protocol(format!(
1244 "array: expected >= 12 bytes header, got {}",
1245 data.len()
1246 )));
1247 }
1248 let ndim = i32::from_be_bytes([data[0], data[1], data[2], data[3]]);
1249 if ndim == 0 {
1250 return Ok(Vec::new());
1251 }
1252 if ndim != 1 {
1253 return Err(DriverError::Protocol(format!(
1254 "array: only 1-dimensional arrays supported, got {ndim}"
1255 )));
1256 }
1257 if data.len() < 20 {
1259 return Err(DriverError::Protocol(
1260 "array: truncated dimension header".into(),
1261 ));
1262 }
1263 let n_elements_raw = i32::from_be_bytes([data[12], data[13], data[14], data[15]]);
1264 if n_elements_raw < 0 {
1265 return Err(DriverError::Protocol(
1266 "array: negative element count".into(),
1267 ));
1268 }
1269 let n_elements = n_elements_raw as usize;
1270 const MAX_ARRAY_ELEMENTS: usize = 10_000_000;
1274 if n_elements > MAX_ARRAY_ELEMENTS {
1275 return Err(DriverError::Protocol(format!(
1276 "array element count {n_elements} exceeds limit of {MAX_ARRAY_ELEMENTS}"
1277 )));
1278 }
1279 let mut pos = 20;
1281 let mut elements = Vec::with_capacity(n_elements);
1282 for _ in 0..n_elements {
1283 if pos + 4 > data.len() {
1284 return Err(DriverError::Protocol("array: truncated element".into()));
1285 }
1286 let elem_len = i32::from_be_bytes([data[pos], data[pos + 1], data[pos + 2], data[pos + 3]]);
1287 pos += 4;
1288 if elem_len < 0 {
1289 continue;
1291 }
1292 let elem_len = elem_len as usize;
1293 if pos + elem_len > data.len() {
1294 return Err(DriverError::Protocol(
1295 "array: truncated element data".into(),
1296 ));
1297 }
1298 elements.push(&data[pos..pos + elem_len]);
1299 pos += elem_len;
1300 }
1301 Ok(elements)
1302}
1303
1304pub fn decode_array_i32(data: &[u8]) -> Result<Vec<i32>, DriverError> {
1306 decode_array_elements(data)?
1307 .into_iter()
1308 .map(decode_i32)
1309 .collect()
1310}
1311
1312pub fn decode_array_i16(data: &[u8]) -> Result<Vec<i16>, DriverError> {
1314 decode_array_elements(data)?
1315 .into_iter()
1316 .map(decode_i16)
1317 .collect()
1318}
1319
1320pub fn decode_array_i64(data: &[u8]) -> Result<Vec<i64>, DriverError> {
1322 decode_array_elements(data)?
1323 .into_iter()
1324 .map(decode_i64)
1325 .collect()
1326}
1327
1328pub fn decode_array_f32(data: &[u8]) -> Result<Vec<f32>, DriverError> {
1330 decode_array_elements(data)?
1331 .into_iter()
1332 .map(decode_f32)
1333 .collect()
1334}
1335
1336pub fn decode_array_f64(data: &[u8]) -> Result<Vec<f64>, DriverError> {
1338 decode_array_elements(data)?
1339 .into_iter()
1340 .map(decode_f64)
1341 .collect()
1342}
1343
1344pub fn decode_array_bool(data: &[u8]) -> Result<Vec<bool>, DriverError> {
1346 decode_array_elements(data)?
1347 .into_iter()
1348 .map(decode_bool)
1349 .collect()
1350}
1351
1352pub fn decode_array_str(data: &[u8]) -> Result<Vec<String>, DriverError> {
1354 decode_array_elements(data)?
1355 .into_iter()
1356 .map(|d| decode_str(d).map(|s| s.to_owned()))
1357 .collect()
1358}
1359
1360pub fn decode_array_bytea(data: &[u8]) -> Result<Vec<Vec<u8>>, DriverError> {
1362 Ok(decode_array_elements(data)?
1363 .into_iter()
1364 .map(|d| d.to_vec())
1365 .collect())
1366}
1367
1368#[cfg(feature = "uuid")]
1372#[inline]
1373pub fn decode_uuid_type(data: &[u8]) -> Result<uuid::Uuid, DriverError> {
1374 let bytes = decode_uuid(data)?;
1375 Ok(uuid::Uuid::from_bytes(bytes))
1376}
1377
1378#[cfg(feature = "time")]
1380#[inline]
1381pub fn decode_timestamptz_time(data: &[u8]) -> Result<time::OffsetDateTime, DriverError> {
1382 let micros = decode_i64(data)?;
1383 let unix_micros = micros + 946_684_800i64 * 1_000_000;
1385 let secs = unix_micros.div_euclid(1_000_000);
1386 let nanos = (unix_micros.rem_euclid(1_000_000) * 1000) as i128;
1387 time::OffsetDateTime::from_unix_timestamp_nanos(secs as i128 * 1_000_000_000 + nanos)
1388 .map_err(|e| DriverError::Protocol(format!("timestamptz decode: {e}")))
1389}
1390
1391#[cfg(feature = "time")]
1393#[inline]
1394pub fn decode_date_time(data: &[u8]) -> Result<time::Date, DriverError> {
1395 let days = decode_i32(data)?;
1396 let pg_epoch = time::Date::from_calendar_date(2000, time::Month::January, 1)
1397 .expect("PG epoch date is valid");
1398 pg_epoch
1399 .checked_add(time::Duration::days(days as i64))
1400 .ok_or_else(|| DriverError::Protocol(format!("date out of range: {days} days")))
1401}
1402
1403#[cfg(feature = "time")]
1405#[inline]
1406pub fn decode_time_time(data: &[u8]) -> Result<time::Time, DriverError> {
1407 let micros = decode_i64(data)?;
1408
1409 if !(0..86_400_000_000).contains(µs) {
1411 return Err(DriverError::Protocol(format!(
1412 "time out of range: {micros}us (must be 0..86_400_000_000)"
1413 )));
1414 }
1415 let total_secs = micros / 1_000_000;
1416 let h = (total_secs / 3600) as u8;
1417 let m = ((total_secs % 3600) / 60) as u8;
1418 let s = (total_secs % 60) as u8;
1419 let micro = (micros % 1_000_000) as u32;
1420 time::Time::from_hms_micro(h, m, s, micro)
1421 .map_err(|e| DriverError::Protocol(format!("time decode: {e}")))
1422}
1423
1424#[cfg(feature = "chrono")]
1426#[inline]
1427pub fn decode_timestamptz_chrono(
1428 data: &[u8],
1429) -> Result<chrono::DateTime<chrono::Utc>, DriverError> {
1430 let micros = decode_i64(data)?;
1431 let pg_epoch_unix_micros: i64 = 946_684_800 * 1_000_000;
1432 let unix_micros = micros + pg_epoch_unix_micros;
1433 let secs = unix_micros.div_euclid(1_000_000);
1434 let nsecs = (unix_micros.rem_euclid(1_000_000) * 1000) as u32;
1435 chrono::DateTime::from_timestamp(secs, nsecs)
1436 .ok_or_else(|| DriverError::Protocol(format!("timestamptz out of range: {micros}us")))
1437}
1438
1439#[cfg(feature = "chrono")]
1441#[inline]
1442pub fn decode_date_chrono(data: &[u8]) -> Result<chrono::NaiveDate, DriverError> {
1443 let days = decode_i32(data)?;
1444 let pg_epoch = chrono::NaiveDate::from_ymd_opt(2000, 1, 1).expect("PG epoch valid");
1445
1446 let result = if days >= 0 {
1448 pg_epoch.checked_add_days(chrono::Days::new(days as u64))
1449 } else {
1450 pg_epoch.checked_sub_days(chrono::Days::new(days.unsigned_abs() as u64))
1451 };
1452 result.ok_or_else(|| DriverError::Protocol(format!("date out of range: {days} days")))
1453}
1454
1455#[cfg(feature = "chrono")]
1457#[inline]
1458pub fn decode_time_chrono(data: &[u8]) -> Result<chrono::NaiveTime, DriverError> {
1459 let micros = decode_i64(data)?;
1460
1461 if !(0..86_400_000_000).contains(µs) {
1463 return Err(DriverError::Protocol(format!(
1464 "time out of range: {micros}us (must be 0..86_400_000_000)"
1465 )));
1466 }
1467 let total_secs = (micros / 1_000_000) as u32;
1468 let micro = (micros % 1_000_000) as u32;
1469 chrono::NaiveTime::from_num_seconds_from_midnight_opt(total_secs, micro * 1000)
1470 .ok_or_else(|| DriverError::Protocol(format!("time out of range: {micros}us")))
1471}
1472
1473#[cfg(feature = "decimal")]
1480pub fn decode_numeric_decimal(data: &[u8]) -> Result<rust_decimal::Decimal, DriverError> {
1481 if data.len() < 8 {
1482 return Err(DriverError::Protocol(format!(
1483 "numeric: expected >= 8 bytes header, got {}",
1484 data.len()
1485 )));
1486 }
1487 let ndigits = i16::from_be_bytes([data[0], data[1]]) as usize;
1488 let weight = i16::from_be_bytes([data[2], data[3]]) as i32;
1489 let sign = i16::from_be_bytes([data[4], data[5]]);
1490 let _dscale = i16::from_be_bytes([data[6], data[7]]) as u32;
1491
1492 if data.len() != 8 + ndigits * 2 {
1493 return Err(DriverError::Protocol(format!(
1494 "numeric: expected {} bytes, got {}",
1495 8 + ndigits * 2,
1496 data.len()
1497 )));
1498 }
1499
1500 if ndigits == 0 {
1501 return Ok(rust_decimal::Decimal::ZERO);
1502 }
1503
1504 let mut digits: smallvec::SmallVec<[i64; 16]> = smallvec::SmallVec::with_capacity(ndigits);
1506 for i in 0..ndigits {
1507 let off = 8 + i * 2;
1508 digits.push(i16::from_be_bytes([data[off], data[off + 1]]) as i64);
1509 }
1510
1511 let mut mantissa: u128 = 0;
1514 for &d in &digits {
1515 mantissa = mantissa
1516 .checked_mul(10_000)
1517 .and_then(|m| m.checked_add(d as u128))
1518 .ok_or_else(|| DriverError::Protocol("numeric value too large for Decimal".into()))?;
1519 }
1520
1521 let exponent = 4 * (weight - ndigits as i32 + 1);
1525 let result = if exponent >= 0 {
1526 let factor = 10u128
1528 .checked_pow(exponent as u32)
1529 .ok_or_else(|| DriverError::Protocol("numeric exponent too large".into()))?;
1530 let m = mantissa
1531 .checked_mul(factor)
1532 .ok_or_else(|| DriverError::Protocol("numeric value too large for Decimal".into()))?;
1533 if m > u128::from(u64::MAX) {
1534 let s = m.to_string();
1536 s.parse::<rust_decimal::Decimal>()
1537 .map_err(|e| DriverError::Protocol(format!("numeric parse error: {e}")))?
1538 } else {
1539 rust_decimal::Decimal::from_i128_with_scale(m as i128, 0)
1540 }
1541 } else {
1542 let scale = (-exponent) as u32;
1544 if mantissa <= u128::from(u64::MAX) {
1546 rust_decimal::Decimal::from_i128_with_scale(mantissa as i128, scale)
1547 } else {
1548 let mut s = mantissa.to_string();
1550 if scale as usize >= s.len() {
1551 let zeros = scale as usize - s.len() + 1;
1552 s = format!("0.{}{s}", "0".repeat(zeros));
1553 } else {
1554 let dot_pos = s.len() - scale as usize;
1555 s.insert(dot_pos, '.');
1556 }
1557 s.parse::<rust_decimal::Decimal>()
1558 .map_err(|e| DriverError::Protocol(format!("numeric parse error: {e}")))?
1559 }
1560 };
1561
1562 if sign == 0x4000 {
1563 Ok(-result)
1564 } else {
1565 Ok(result)
1566 }
1567}
1568
1569#[cfg(test)]
1570#[allow(clippy::approx_constant)]
1571mod tests {
1572 use super::*;
1573
1574 #[test]
1577 fn bool_roundtrip() {
1578 let mut buf = Vec::new();
1579 true.encode_binary(&mut buf);
1580 assert!(decode_bool(&buf).unwrap());
1581
1582 buf.clear();
1583 false.encode_binary(&mut buf);
1584 assert!(!decode_bool(&buf).unwrap());
1585 }
1586
1587 #[test]
1588 fn i16_roundtrip() {
1589 let mut buf = Vec::new();
1590 12345i16.encode_binary(&mut buf);
1591 assert_eq!(decode_i16(&buf).unwrap(), 12345);
1592
1593 buf.clear();
1594 (-1i16).encode_binary(&mut buf);
1595 assert_eq!(decode_i16(&buf).unwrap(), -1);
1596
1597 buf.clear();
1598 i16::MIN.encode_binary(&mut buf);
1599 assert_eq!(decode_i16(&buf).unwrap(), i16::MIN);
1600
1601 buf.clear();
1602 i16::MAX.encode_binary(&mut buf);
1603 assert_eq!(decode_i16(&buf).unwrap(), i16::MAX);
1604 }
1605
1606 #[test]
1607 fn i32_roundtrip() {
1608 let mut buf = Vec::new();
1609 42i32.encode_binary(&mut buf);
1610 assert_eq!(buf, &[0, 0, 0, 42]);
1611 assert_eq!(decode_i32(&buf).unwrap(), 42);
1612
1613 buf.clear();
1614 i32::MAX.encode_binary(&mut buf);
1615 assert_eq!(decode_i32(&buf).unwrap(), i32::MAX);
1616
1617 buf.clear();
1618 i32::MIN.encode_binary(&mut buf);
1619 assert_eq!(decode_i32(&buf).unwrap(), i32::MIN);
1620 }
1621
1622 #[test]
1623 fn i64_roundtrip() {
1624 let mut buf = Vec::new();
1625 1234567890123i64.encode_binary(&mut buf);
1626 assert_eq!(decode_i64(&buf).unwrap(), 1234567890123);
1627 }
1628
1629 #[test]
1630 fn f32_roundtrip() {
1631 let mut buf = Vec::new();
1632 3.14f32.encode_binary(&mut buf);
1633 let decoded = decode_f32(&buf).unwrap();
1634 assert!((decoded - 3.14).abs() < f32::EPSILON);
1635 }
1636
1637 #[test]
1638 fn f64_roundtrip() {
1639 let mut buf = Vec::new();
1640 std::f64::consts::PI.encode_binary(&mut buf);
1641 let decoded = decode_f64(&buf).unwrap();
1642 assert!((decoded - std::f64::consts::PI).abs() < f64::EPSILON);
1643 }
1644
1645 #[test]
1646 fn str_roundtrip() {
1647 let mut buf = Vec::new();
1648 "hello world".encode_binary(&mut buf);
1649 assert_eq!(decode_str(&buf).unwrap(), "hello world");
1650 }
1651
1652 #[test]
1653 fn string_roundtrip() {
1654 let mut buf = Vec::new();
1655 let s = String::from("test string");
1656 s.encode_binary(&mut buf);
1657 assert_eq!(decode_str(&buf).unwrap(), "test string");
1658 }
1659
1660 #[test]
1661 fn bytes_roundtrip() {
1662 let mut buf = Vec::new();
1663 let data: &[u8] = &[0xDE, 0xAD, 0xBE, 0xEF];
1664 data.encode_binary(&mut buf);
1665 assert_eq!(decode_bytes(&buf), data);
1666 }
1667
1668 #[test]
1669 fn vec_u8_roundtrip() {
1670 let mut buf = Vec::new();
1671 let data = vec![1u8, 2, 3, 4, 5];
1672 data.encode_binary(&mut buf);
1673 assert_eq!(decode_bytes(&buf), &[1, 2, 3, 4, 5]);
1674 }
1675
1676 #[test]
1677 fn u32_encode() {
1678 let mut buf = Vec::new();
1679 42u32.encode_binary(&mut buf);
1680 assert_eq!(buf, &[0, 0, 0, 42]);
1681 }
1682
1683 #[test]
1684 fn uuid_roundtrip() {
1685 let uuid_bytes: [u8; 16] = [
1686 0x55, 0x0e, 0x84, 0x00, 0xe2, 0x9b, 0x41, 0xd4, 0xa7, 0x16, 0x44, 0x66, 0x55, 0x44,
1687 0x00, 0x00,
1688 ];
1689 let decoded = decode_uuid(&uuid_bytes).unwrap();
1690 assert_eq!(decoded, uuid_bytes);
1691 }
1692
1693 #[test]
1696 fn decode_bool_wrong_length() {
1697 assert!(decode_bool(&[]).is_err());
1698 assert!(decode_bool(&[0, 0]).is_err());
1699 }
1700
1701 #[test]
1702 fn decode_i32_wrong_length() {
1703 assert!(decode_i32(&[0, 0, 0]).is_err());
1704 assert!(decode_i32(&[0, 0, 0, 0, 0]).is_err());
1705 }
1706
1707 #[test]
1708 fn decode_i64_wrong_length() {
1709 assert!(decode_i64(&[0; 7]).is_err());
1710 assert!(decode_i64(&[0; 9]).is_err());
1711 }
1712
1713 #[test]
1714 fn decode_f32_wrong_length() {
1715 assert!(decode_f32(&[0; 3]).is_err());
1716 }
1717
1718 #[test]
1719 fn decode_f64_wrong_length() {
1720 assert!(decode_f64(&[0; 7]).is_err());
1721 }
1722
1723 #[test]
1724 fn decode_str_invalid_utf8() {
1725 assert!(decode_str(&[0xFF, 0xFE]).is_err());
1726 }
1727
1728 #[test]
1729 fn decode_uuid_wrong_length() {
1730 assert!(decode_uuid(&[0; 15]).is_err());
1731 assert!(decode_uuid(&[0; 17]).is_err());
1732 }
1733
1734 #[test]
1735 fn empty_str_decode() {
1736 assert_eq!(decode_str(&[]).unwrap(), "");
1737 }
1738
1739 #[test]
1740 fn empty_bytes_decode() {
1741 assert_eq!(decode_bytes(&[]).len(), 0);
1742 }
1743
1744 #[test]
1747 fn type_oids_correct() {
1748 assert_eq!(true.type_oid(), 16);
1749 assert_eq!(0i16.type_oid(), 21);
1750 assert_eq!(0i32.type_oid(), 23);
1751 assert_eq!(0i64.type_oid(), 20);
1752 assert_eq!(0f32.type_oid(), 700);
1753 assert_eq!(0f64.type_oid(), 701);
1754 assert_eq!("".type_oid(), 25);
1755 assert_eq!(String::new().type_oid(), 25);
1756 let b: &[u8] = &[];
1757 assert_eq!(b.type_oid(), 17);
1758 assert_eq!(Vec::<u8>::new().type_oid(), 17);
1759 assert_eq!(0u32.type_oid(), 26);
1760 }
1761
1762 #[test]
1765 fn encode_param_i32() {
1766 let mut buf = Vec::new();
1767 encode_param(&mut buf, &42i32);
1768 assert_eq!(buf.len(), 8);
1770 let len = i32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]);
1771 assert_eq!(len, 4);
1772 let val = i32::from_be_bytes([buf[4], buf[5], buf[6], buf[7]]);
1773 assert_eq!(val, 42);
1774 }
1775
1776 #[test]
1777 fn encode_param_str() {
1778 let mut buf = Vec::new();
1779 encode_param(&mut buf, &"hello");
1780 assert_eq!(buf.len(), 9);
1782 let len = i32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]);
1783 assert_eq!(len, 5);
1784 assert_eq!(&buf[4..], b"hello");
1785 }
1786
1787 #[test]
1788 fn option_none_is_null() {
1789 let val: Option<i32> = None;
1790 assert!(val.is_null());
1791 assert_eq!(val.type_oid(), 0);
1792 }
1793
1794 #[test]
1795 fn option_some_encodes() {
1796 let val: Option<i32> = Some(42);
1797 assert!(!val.is_null());
1798 assert_eq!(val.type_oid(), 23);
1799 let mut buf = Vec::new();
1800 val.encode_binary(&mut buf);
1801 assert_eq!(buf, &[0, 0, 0, 42]);
1802 }
1803
1804 #[test]
1805 fn option_none_encode_is_noop() {
1806 let val: Option<i32> = None;
1807 let mut buf = Vec::new();
1808 val.encode_binary(&mut buf);
1809 assert!(buf.is_empty(), "None encode should produce no bytes");
1810 }
1811
1812 #[test]
1816 fn decode_i16_wrong_length() {
1817 assert!(decode_i16(&[]).is_err());
1818 assert!(decode_i16(&[0]).is_err());
1819 assert!(decode_i16(&[0, 0, 0]).is_err());
1820 }
1821
1822 #[test]
1824 fn f32_nan_roundtrip() {
1825 let mut buf = Vec::new();
1826 f32::NAN.encode_binary(&mut buf);
1827 let decoded = decode_f32(&buf).unwrap();
1828 assert!(decoded.is_nan(), "NaN should survive roundtrip");
1829 }
1830
1831 #[test]
1833 fn f64_nan_roundtrip() {
1834 let mut buf = Vec::new();
1835 f64::NAN.encode_binary(&mut buf);
1836 let decoded = decode_f64(&buf).unwrap();
1837 assert!(decoded.is_nan(), "NaN should survive roundtrip");
1838 }
1839
1840 #[test]
1842 fn f32_infinity_roundtrip() {
1843 let mut buf = Vec::new();
1844 f32::INFINITY.encode_binary(&mut buf);
1845 assert_eq!(decode_f32(&buf).unwrap(), f32::INFINITY);
1846
1847 buf.clear();
1848 f32::NEG_INFINITY.encode_binary(&mut buf);
1849 assert_eq!(decode_f32(&buf).unwrap(), f32::NEG_INFINITY);
1850 }
1851
1852 #[test]
1854 fn f64_infinity_roundtrip() {
1855 let mut buf = Vec::new();
1856 f64::INFINITY.encode_binary(&mut buf);
1857 assert_eq!(decode_f64(&buf).unwrap(), f64::INFINITY);
1858
1859 buf.clear();
1860 f64::NEG_INFINITY.encode_binary(&mut buf);
1861 assert_eq!(decode_f64(&buf).unwrap(), f64::NEG_INFINITY);
1862 }
1863
1864 #[test]
1866 fn f32_signed_zero_roundtrip() {
1867 let mut buf = Vec::new();
1868 0.0f32.encode_binary(&mut buf);
1869 let decoded = decode_f32(&buf).unwrap();
1870 assert_eq!(decoded.to_bits(), 0.0f32.to_bits(), "+0.0 bits must match");
1871
1872 buf.clear();
1873 (-0.0f32).encode_binary(&mut buf);
1874 let decoded = decode_f32(&buf).unwrap();
1875 assert_eq!(
1876 decoded.to_bits(),
1877 (-0.0f32).to_bits(),
1878 "-0.0 bits must match"
1879 );
1880 }
1881
1882 #[test]
1884 fn f64_signed_zero_roundtrip() {
1885 let mut buf = Vec::new();
1886 0.0f64.encode_binary(&mut buf);
1887 let decoded = decode_f64(&buf).unwrap();
1888 assert_eq!(decoded.to_bits(), 0.0f64.to_bits(), "+0.0 bits must match");
1889
1890 buf.clear();
1891 (-0.0f64).encode_binary(&mut buf);
1892 let decoded = decode_f64(&buf).unwrap();
1893 assert_eq!(
1894 decoded.to_bits(),
1895 (-0.0f64).to_bits(),
1896 "-0.0 bits must match"
1897 );
1898 }
1899
1900 #[test]
1902 fn i64_boundary_roundtrip() {
1903 let mut buf = Vec::new();
1904 i64::MIN.encode_binary(&mut buf);
1905 assert_eq!(decode_i64(&buf).unwrap(), i64::MIN);
1906
1907 buf.clear();
1908 i64::MAX.encode_binary(&mut buf);
1909 assert_eq!(decode_i64(&buf).unwrap(), i64::MAX);
1910 }
1911
1912 #[test]
1914 fn i16_boundary_standalone() {
1915 let mut buf = Vec::new();
1916 i16::MIN.encode_binary(&mut buf);
1917 assert_eq!(decode_i16(&buf).unwrap(), i16::MIN);
1918
1919 buf.clear();
1920 i16::MAX.encode_binary(&mut buf);
1921 assert_eq!(decode_i16(&buf).unwrap(), i16::MAX);
1922 }
1923
1924 #[cfg(feature = "chrono")]
1926 #[test]
1927 fn decode_date_chrono_negative_days() {
1928 let data = (-365i32).to_be_bytes();
1930 let date = decode_date_chrono(&data).unwrap();
1931 assert_eq!(date, chrono::NaiveDate::from_ymd_opt(1999, 1, 1).unwrap());
1932 }
1933
1934 #[cfg(feature = "chrono")]
1936 #[test]
1937 fn decode_date_chrono_day_zero() {
1938 let data = 0i32.to_be_bytes();
1939 let date = decode_date_chrono(&data).unwrap();
1940 assert_eq!(date, chrono::NaiveDate::from_ymd_opt(2000, 1, 1).unwrap());
1941 }
1942
1943 #[cfg(feature = "time")]
1945 #[test]
1946 fn decode_date_time_negative_days() {
1947 let data = (-1i32).to_be_bytes();
1948 let date = decode_date_time(&data).unwrap();
1949 let expected = time::Date::from_calendar_date(1999, time::Month::December, 31).unwrap();
1950 assert_eq!(date, expected);
1951 }
1952
1953 #[cfg(feature = "time")]
1955 #[test]
1956 fn decode_time_time_midnight() {
1957 let data = 0i64.to_be_bytes();
1958 let t = decode_time_time(&data).unwrap();
1959 assert_eq!(t, time::Time::MIDNIGHT);
1960 }
1961
1962 #[cfg(feature = "time")]
1964 #[test]
1965 fn decode_time_time_max_value() {
1966 let micros: i64 = 86_400_000_000 - 1; let data = micros.to_be_bytes();
1968 let t = decode_time_time(&data).unwrap();
1969 assert_eq!(t.hour(), 23);
1970 assert_eq!(t.minute(), 59);
1971 assert_eq!(t.second(), 59);
1972 assert_eq!(t.microsecond(), 999999);
1973 }
1974
1975 #[cfg(feature = "time")]
1977 #[test]
1978 fn decode_time_time_negative_micros_error() {
1979 let data = (-1i64).to_be_bytes();
1980 let result = decode_time_time(&data);
1981 assert!(result.is_err(), "negative microseconds should error");
1982 }
1983
1984 #[cfg(feature = "time")]
1986 #[test]
1987 fn decode_time_time_overflow_error() {
1988 let data = 86_400_000_000i64.to_be_bytes();
1989 let result = decode_time_time(&data);
1990 assert!(result.is_err(), ">= 24h microseconds should error");
1991 }
1992
1993 #[cfg(feature = "time")]
1995 #[test]
1996 fn decode_timestamptz_time_pg_epoch() {
1997 let data = 0i64.to_be_bytes();
1998 let dt = decode_timestamptz_time(&data).unwrap();
1999 assert_eq!(dt.year(), 2000);
2001 assert_eq!(dt.month(), time::Month::January);
2002 assert_eq!(dt.day(), 1);
2003 assert_eq!(dt.hour(), 0);
2004 assert_eq!(dt.minute(), 0);
2005 assert_eq!(dt.second(), 0);
2006 }
2007
2008 #[cfg(feature = "decimal")]
2010 #[test]
2011 fn decode_numeric_decimal_zero() {
2012 let mut data = Vec::new();
2014 data.extend_from_slice(&0i16.to_be_bytes()); data.extend_from_slice(&0i16.to_be_bytes()); data.extend_from_slice(&0i16.to_be_bytes()); data.extend_from_slice(&0i16.to_be_bytes()); let dec = decode_numeric_decimal(&data).unwrap();
2019 assert!(dec.is_zero());
2020 }
2021
2022 #[cfg(feature = "decimal")]
2024 #[test]
2025 fn decode_numeric_decimal_negative() {
2026 let mut data = Vec::new();
2028 data.extend_from_slice(&1i16.to_be_bytes()); data.extend_from_slice(&0i16.to_be_bytes()); data.extend_from_slice(&0x4000i16.to_be_bytes()); data.extend_from_slice(&0i16.to_be_bytes()); data.extend_from_slice(&42i16.to_be_bytes()); let dec = decode_numeric_decimal(&data).unwrap();
2034 assert_eq!(dec, rust_decimal::Decimal::new(-42, 0));
2035 }
2036
2037 #[cfg(feature = "decimal")]
2039 #[test]
2040 fn decode_numeric_decimal_pure_fractional() {
2041 let mut data = Vec::new();
2046 data.extend_from_slice(&1i16.to_be_bytes()); data.extend_from_slice(&(-1i16).to_be_bytes()); data.extend_from_slice(&0i16.to_be_bytes()); data.extend_from_slice(&3i16.to_be_bytes()); data.extend_from_slice(&10i16.to_be_bytes()); let dec = decode_numeric_decimal(&data).unwrap();
2052 let dec_normalized = dec.normalize();
2054 assert_eq!(dec_normalized.to_string(), "0.001");
2055 }
2056
2057 #[test]
2059 fn decode_array_empty() {
2060 let mut data = Vec::new();
2062 data.extend_from_slice(&0i32.to_be_bytes()); data.extend_from_slice(&0i32.to_be_bytes()); data.extend_from_slice(&23i32.to_be_bytes()); let elems = decode_array_i32(&data).unwrap();
2066 assert!(elems.is_empty());
2067 }
2068
2069 #[test]
2071 fn decode_array_multidim_error() {
2072 let mut data = Vec::new();
2073 data.extend_from_slice(&2i32.to_be_bytes()); data.extend_from_slice(&0i32.to_be_bytes()); data.extend_from_slice(&23i32.to_be_bytes()); data.extend_from_slice(&0i32.to_be_bytes());
2078 data.extend_from_slice(&0i32.to_be_bytes());
2079 data.extend_from_slice(&0i32.to_be_bytes());
2080 data.extend_from_slice(&0i32.to_be_bytes());
2081 let result = decode_array_i32(&data);
2082 assert!(result.is_err(), "multi-dimensional should error");
2083 }
2084
2085 #[test]
2087 fn decode_array_truncated_error() {
2088 let mut data = Vec::new();
2090 data.extend_from_slice(&1i32.to_be_bytes()); data.extend_from_slice(&0i32.to_be_bytes()); data.extend_from_slice(&23i32.to_be_bytes()); data.extend_from_slice(&1i32.to_be_bytes()); data.extend_from_slice(&1i32.to_be_bytes()); let result = decode_array_i32(&data);
2097 assert!(result.is_err(), "truncated array should error");
2098 }
2099
2100 #[test]
2102 fn option_some_i32_produces_data() {
2103 let val: Option<i32> = Some(42);
2104 assert!(!val.is_null());
2105 let mut buf = Vec::new();
2106 val.encode_binary(&mut buf);
2107 assert_eq!(decode_i32(&buf).unwrap(), 42);
2108 }
2109
2110 #[test]
2112 fn option_none_i32_is_null() {
2113 let val: Option<i32> = None;
2114 assert!(val.is_null());
2115 let mut buf = Vec::new();
2116 val.encode_binary(&mut buf);
2117 assert!(buf.is_empty());
2118 }
2119
2120 #[test]
2122 fn empty_string_encode_decode() {
2123 let mut buf = Vec::new();
2124 "".encode_binary(&mut buf);
2125 assert!(buf.is_empty());
2126 assert_eq!(decode_str(&buf).unwrap(), "");
2127
2128 buf.clear();
2129 String::new().encode_binary(&mut buf);
2130 assert!(buf.is_empty());
2131 assert_eq!(decode_str(&buf).unwrap(), "");
2132 }
2133
2134 #[test]
2136 fn empty_bytes_encode_decode() {
2137 let mut buf = Vec::new();
2138 let empty: &[u8] = &[];
2139 empty.encode_binary(&mut buf);
2140 assert!(buf.is_empty());
2141 assert_eq!(decode_bytes(&buf).len(), 0);
2142
2143 buf.clear();
2144 Vec::<u8>::new().encode_binary(&mut buf);
2145 assert!(buf.is_empty());
2146 }
2147
2148 #[test]
2150 fn large_string_encode_decode() {
2151 let big = "x".repeat(1_000_000);
2152 let mut buf = Vec::new();
2153 big.as_str().encode_binary(&mut buf);
2154 assert_eq!(buf.len(), 1_000_000);
2155 assert_eq!(decode_str(&buf).unwrap(), big);
2156 }
2157
2158 #[test]
2160 fn uuid_nil() {
2161 let nil = [0u8; 16];
2162 let decoded = decode_uuid(&nil).unwrap();
2163 assert_eq!(decoded, [0u8; 16]);
2164 }
2165
2166 #[test]
2168 fn uuid_max() {
2169 let max = [0xFF; 16];
2170 let decoded = decode_uuid(&max).unwrap();
2171 assert_eq!(decoded, [0xFF; 16]);
2172 }
2173
2174 #[cfg(feature = "uuid")]
2176 #[test]
2177 fn uuid_type_nil_and_max() {
2178 let nil = [0u8; 16];
2179 let uuid = decode_uuid_type(&nil).unwrap();
2180 assert_eq!(uuid, uuid::Uuid::nil());
2181
2182 let max = [0xFF; 16];
2183 let uuid = decode_uuid_type(&max).unwrap();
2184 assert_eq!(uuid, uuid::Uuid::max());
2185 }
2186
2187 #[test]
2191 fn encode_array_bool_empty() {
2192 let arr: &[bool] = &[];
2193 let mut buf = Vec::new();
2194 arr.encode_binary(&mut buf);
2195 let decoded = decode_array_bool(&buf).unwrap();
2196 assert!(decoded.is_empty());
2197 }
2198
2199 #[test]
2200 fn encode_array_bool_single() {
2201 let arr: &[bool] = &[true];
2202 let mut buf = Vec::new();
2203 arr.encode_binary(&mut buf);
2204 let decoded = decode_array_bool(&buf).unwrap();
2205 assert_eq!(decoded, vec![true]);
2206 }
2207
2208 #[test]
2209 fn encode_array_bool_multi() {
2210 let arr: &[bool] = &[true, false, true, false];
2211 let mut buf = Vec::new();
2212 arr.encode_binary(&mut buf);
2213 let decoded = decode_array_bool(&buf).unwrap();
2214 assert_eq!(decoded, vec![true, false, true, false]);
2215 }
2216
2217 #[test]
2218 fn encode_array_bool_vec_delegate() {
2219 let v = vec![false, true];
2220 let mut buf = Vec::new();
2221 v.encode_binary(&mut buf);
2222 let decoded = decode_array_bool(&buf).unwrap();
2223 assert_eq!(decoded, vec![false, true]);
2224 assert_eq!(v.type_oid(), 1000);
2225 }
2226
2227 #[test]
2229 fn encode_array_i16_empty() {
2230 let arr: &[i16] = &[];
2231 let mut buf = Vec::new();
2232 arr.encode_binary(&mut buf);
2233 let decoded = decode_array_i16(&buf).unwrap();
2234 assert!(decoded.is_empty());
2235 }
2236
2237 #[test]
2238 fn encode_array_i16_single() {
2239 let arr: &[i16] = &[42];
2240 let mut buf = Vec::new();
2241 arr.encode_binary(&mut buf);
2242 let decoded = decode_array_i16(&buf).unwrap();
2243 assert_eq!(decoded, vec![42i16]);
2244 }
2245
2246 #[test]
2247 fn encode_array_i16_multi_boundary() {
2248 let arr: &[i16] = &[i16::MIN, -1, 0, 1, i16::MAX];
2249 let mut buf = Vec::new();
2250 arr.encode_binary(&mut buf);
2251 let decoded = decode_array_i16(&buf).unwrap();
2252 assert_eq!(decoded, vec![i16::MIN, -1, 0, 1, i16::MAX]);
2253 }
2254
2255 #[test]
2256 fn encode_array_i16_vec_delegate() {
2257 let v = vec![100i16, 200];
2258 let mut buf = Vec::new();
2259 v.encode_binary(&mut buf);
2260 let decoded = decode_array_i16(&buf).unwrap();
2261 assert_eq!(decoded, vec![100i16, 200]);
2262 assert_eq!(v.type_oid(), 1005);
2263 }
2264
2265 #[test]
2267 fn encode_array_i32_empty() {
2268 let arr: &[i32] = &[];
2269 let mut buf = Vec::new();
2270 arr.encode_binary(&mut buf);
2271 let decoded = decode_array_i32(&buf).unwrap();
2272 assert!(decoded.is_empty());
2273 }
2274
2275 #[test]
2276 fn encode_array_i32_single() {
2277 let arr: &[i32] = &[42];
2278 let mut buf = Vec::new();
2279 arr.encode_binary(&mut buf);
2280 let decoded = decode_array_i32(&buf).unwrap();
2281 assert_eq!(decoded, vec![42]);
2282 }
2283
2284 #[test]
2285 fn encode_array_i32_multi_boundary() {
2286 let arr: &[i32] = &[i32::MIN, -1, 0, 1, i32::MAX];
2287 let mut buf = Vec::new();
2288 arr.encode_binary(&mut buf);
2289 let decoded = decode_array_i32(&buf).unwrap();
2290 assert_eq!(decoded, vec![i32::MIN, -1, 0, 1, i32::MAX]);
2291 }
2292
2293 #[test]
2294 fn encode_array_i32_vec_delegate() {
2295 let v = vec![10, 20, 30];
2296 let mut buf = Vec::new();
2297 v.encode_binary(&mut buf);
2298 let decoded = decode_array_i32(&buf).unwrap();
2299 assert_eq!(decoded, vec![10, 20, 30]);
2300 assert_eq!(v.type_oid(), 1007);
2301 }
2302
2303 #[test]
2305 fn encode_array_i64_empty() {
2306 let arr: &[i64] = &[];
2307 let mut buf = Vec::new();
2308 arr.encode_binary(&mut buf);
2309 let decoded = decode_array_i64(&buf).unwrap();
2310 assert!(decoded.is_empty());
2311 }
2312
2313 #[test]
2314 fn encode_array_i64_single() {
2315 let arr: &[i64] = &[9999999999i64];
2316 let mut buf = Vec::new();
2317 arr.encode_binary(&mut buf);
2318 let decoded = decode_array_i64(&buf).unwrap();
2319 assert_eq!(decoded, vec![9999999999i64]);
2320 }
2321
2322 #[test]
2323 fn encode_array_i64_multi_boundary() {
2324 let arr: &[i64] = &[i64::MIN, -1, 0, 1, i64::MAX];
2325 let mut buf = Vec::new();
2326 arr.encode_binary(&mut buf);
2327 let decoded = decode_array_i64(&buf).unwrap();
2328 assert_eq!(decoded, vec![i64::MIN, -1, 0, 1, i64::MAX]);
2329 }
2330
2331 #[test]
2332 fn encode_array_i64_vec_delegate() {
2333 let v = vec![1i64, 2, 3];
2334 let mut buf = Vec::new();
2335 v.encode_binary(&mut buf);
2336 let decoded = decode_array_i64(&buf).unwrap();
2337 assert_eq!(decoded, vec![1i64, 2, 3]);
2338 assert_eq!(v.type_oid(), 1016);
2339 }
2340
2341 #[test]
2343 fn encode_array_f32_empty() {
2344 let arr: &[f32] = &[];
2345 let mut buf = Vec::new();
2346 arr.encode_binary(&mut buf);
2347 let decoded = decode_array_f32(&buf).unwrap();
2348 assert!(decoded.is_empty());
2349 }
2350
2351 #[test]
2352 fn encode_array_f32_single() {
2353 let arr: &[f32] = &[3.14];
2354 let mut buf = Vec::new();
2355 arr.encode_binary(&mut buf);
2356 let decoded = decode_array_f32(&buf).unwrap();
2357 assert!((decoded[0] - 3.14).abs() < f32::EPSILON);
2358 }
2359
2360 #[test]
2361 fn encode_array_f32_multi_boundary() {
2362 let arr: &[f32] = &[
2363 f32::MIN,
2364 -0.0,
2365 0.0,
2366 f32::MAX,
2367 f32::INFINITY,
2368 f32::NEG_INFINITY,
2369 ];
2370 let mut buf = Vec::new();
2371 arr.encode_binary(&mut buf);
2372 let decoded = decode_array_f32(&buf).unwrap();
2373 assert_eq!(decoded[0], f32::MIN);
2374 assert_eq!(decoded[1].to_bits(), (-0.0f32).to_bits());
2375 assert_eq!(decoded[2].to_bits(), 0.0f32.to_bits());
2376 assert_eq!(decoded[3], f32::MAX);
2377 assert_eq!(decoded[4], f32::INFINITY);
2378 assert_eq!(decoded[5], f32::NEG_INFINITY);
2379 }
2380
2381 #[test]
2382 fn encode_array_f32_vec_delegate() {
2383 let v = vec![1.0f32, 2.0];
2384 let mut buf = Vec::new();
2385 v.encode_binary(&mut buf);
2386 let decoded = decode_array_f32(&buf).unwrap();
2387 assert_eq!(decoded, vec![1.0f32, 2.0]);
2388 assert_eq!(v.type_oid(), 1021);
2389 }
2390
2391 #[test]
2393 fn encode_array_f64_empty() {
2394 let arr: &[f64] = &[];
2395 let mut buf = Vec::new();
2396 arr.encode_binary(&mut buf);
2397 let decoded = decode_array_f64(&buf).unwrap();
2398 assert!(decoded.is_empty());
2399 }
2400
2401 #[test]
2402 fn encode_array_f64_single() {
2403 let arr: &[f64] = &[std::f64::consts::PI];
2404 let mut buf = Vec::new();
2405 arr.encode_binary(&mut buf);
2406 let decoded = decode_array_f64(&buf).unwrap();
2407 assert!((decoded[0] - std::f64::consts::PI).abs() < f64::EPSILON);
2408 }
2409
2410 #[test]
2411 fn encode_array_f64_multi_boundary() {
2412 let arr: &[f64] = &[
2413 f64::MIN,
2414 -0.0,
2415 0.0,
2416 f64::MAX,
2417 f64::INFINITY,
2418 f64::NEG_INFINITY,
2419 ];
2420 let mut buf = Vec::new();
2421 arr.encode_binary(&mut buf);
2422 let decoded = decode_array_f64(&buf).unwrap();
2423 assert_eq!(decoded[0], f64::MIN);
2424 assert_eq!(decoded[1].to_bits(), (-0.0f64).to_bits());
2425 assert_eq!(decoded[2].to_bits(), 0.0f64.to_bits());
2426 assert_eq!(decoded[3], f64::MAX);
2427 assert_eq!(decoded[4], f64::INFINITY);
2428 assert_eq!(decoded[5], f64::NEG_INFINITY);
2429 }
2430
2431 #[test]
2432 fn encode_array_f64_vec_delegate() {
2433 let v = vec![1.0f64, 2.0];
2434 let mut buf = Vec::new();
2435 v.encode_binary(&mut buf);
2436 let decoded = decode_array_f64(&buf).unwrap();
2437 assert_eq!(decoded, vec![1.0f64, 2.0]);
2438 assert_eq!(v.type_oid(), 1022);
2439 }
2440
2441 #[test]
2443 fn encode_array_str_empty() {
2444 let arr: &[&str] = &[];
2445 let mut buf = Vec::new();
2446 arr.encode_binary(&mut buf);
2447 let decoded = decode_array_str(&buf).unwrap();
2448 assert!(decoded.is_empty());
2449 }
2450
2451 #[test]
2452 fn encode_array_str_single() {
2453 let arr: &[&str] = &["hello"];
2454 let mut buf = Vec::new();
2455 arr.encode_binary(&mut buf);
2456 let decoded = decode_array_str(&buf).unwrap();
2457 assert_eq!(decoded, vec!["hello".to_string()]);
2458 }
2459
2460 #[test]
2461 fn encode_array_str_multi() {
2462 let arr: &[&str] = &["hello", "", "world"];
2463 let mut buf = Vec::new();
2464 arr.encode_binary(&mut buf);
2465 let decoded = decode_array_str(&buf).unwrap();
2466 assert_eq!(
2467 decoded,
2468 vec!["hello".to_string(), "".to_string(), "world".to_string()]
2469 );
2470 }
2471
2472 #[test]
2473 fn encode_array_str_boundary_unicode() {
2474 let arr: &[&str] = &["\u{1F600}", "\u{00E9}"];
2475 let mut buf = Vec::new();
2476 arr.encode_binary(&mut buf);
2477 let decoded = decode_array_str(&buf).unwrap();
2478 assert_eq!(
2479 decoded,
2480 vec!["\u{1F600}".to_string(), "\u{00E9}".to_string()]
2481 );
2482 }
2483
2484 #[test]
2485 fn encode_array_vec_string() {
2486 let v = vec!["foo".to_string(), "bar".to_string()];
2487 let mut buf = Vec::new();
2488 v.encode_binary(&mut buf);
2489 let decoded = decode_array_str(&buf).unwrap();
2490 assert_eq!(decoded, vec!["foo".to_string(), "bar".to_string()]);
2491 assert_eq!(v.type_oid(), 1009);
2492 }
2493
2494 #[test]
2495 fn encode_array_vec_string_empty() {
2496 let v: Vec<String> = vec![];
2497 let mut buf = Vec::new();
2498 v.encode_binary(&mut buf);
2499 let decoded = decode_array_str(&buf).unwrap();
2500 assert!(decoded.is_empty());
2501 }
2502
2503 #[test]
2505 fn encode_array_bytea_empty() {
2506 let arr: &[&[u8]] = &[];
2507 let mut buf = Vec::new();
2508 arr.encode_binary(&mut buf);
2509 let decoded = decode_array_bytea(&buf).unwrap();
2510 assert!(decoded.is_empty());
2511 }
2512
2513 #[test]
2514 fn encode_array_bytea_single() {
2515 let data: &[u8] = &[0xDE, 0xAD];
2516 let arr: &[&[u8]] = &[data];
2517 let mut buf = Vec::new();
2518 arr.encode_binary(&mut buf);
2519 let decoded = decode_array_bytea(&buf).unwrap();
2520 assert_eq!(decoded, vec![vec![0xDE, 0xAD]]);
2521 }
2522
2523 #[test]
2524 fn encode_array_bytea_multi() {
2525 let a: &[u8] = &[1, 2, 3];
2526 let b: &[u8] = &[];
2527 let c: &[u8] = &[0xFF];
2528 let arr: &[&[u8]] = &[a, b, c];
2529 let mut buf = Vec::new();
2530 arr.encode_binary(&mut buf);
2531 let decoded = decode_array_bytea(&buf).unwrap();
2532 assert_eq!(decoded, vec![vec![1, 2, 3], vec![], vec![0xFF]]);
2533 }
2534
2535 #[test]
2536 fn encode_array_vec_vec_u8() {
2537 let v = vec![vec![10u8, 20], vec![30]];
2538 let mut buf = Vec::new();
2539 v.encode_binary(&mut buf);
2540 let decoded = decode_array_bytea(&buf).unwrap();
2541 assert_eq!(decoded, vec![vec![10u8, 20], vec![30]]);
2542 assert_eq!(v.type_oid(), 1001);
2543 }
2544
2545 #[test]
2546 fn encode_array_vec_vec_u8_empty() {
2547 let v: Vec<Vec<u8>> = vec![];
2548 let mut buf = Vec::new();
2549 v.encode_binary(&mut buf);
2550 let decoded = decode_array_bytea(&buf).unwrap();
2551 assert!(decoded.is_empty());
2552 }
2553
2554 #[test]
2556 fn array_type_oids_correct() {
2557 let b: &[bool] = &[];
2558 assert_eq!(b.type_oid(), 1000);
2559 let i2: &[i16] = &[];
2560 assert_eq!(i2.type_oid(), 1005);
2561 let i4: &[i32] = &[];
2562 assert_eq!(i4.type_oid(), 1007);
2563 let i8: &[i64] = &[];
2564 assert_eq!(i8.type_oid(), 1016);
2565 let f4: &[f32] = &[];
2566 assert_eq!(f4.type_oid(), 1021);
2567 let f8: &[f64] = &[];
2568 assert_eq!(f8.type_oid(), 1022);
2569 let t: &[&str] = &[];
2570 assert_eq!(t.type_oid(), 1009);
2571 let by: &[&[u8]] = &[];
2572 assert_eq!(by.type_oid(), 1001);
2573
2574 assert_eq!(Vec::<bool>::new().type_oid(), 1000);
2575 assert_eq!(Vec::<i16>::new().type_oid(), 1005);
2576 assert_eq!(Vec::<i32>::new().type_oid(), 1007);
2577 assert_eq!(Vec::<i64>::new().type_oid(), 1016);
2578 assert_eq!(Vec::<f32>::new().type_oid(), 1021);
2579 assert_eq!(Vec::<f64>::new().type_oid(), 1022);
2580 assert_eq!(Vec::<String>::new().type_oid(), 1009);
2581 assert_eq!(Vec::<Vec<u8>>::new().type_oid(), 1001);
2582 }
2583
2584 #[test]
2586 fn encode_array_empty_ndim_zero() {
2587 let arr: &[i32] = &[];
2588 let mut buf = Vec::new();
2589 arr.encode_binary(&mut buf);
2590 assert_eq!(buf.len(), 12);
2592 let ndim = i32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]);
2593 assert_eq!(ndim, 0, "empty array must have ndim=0");
2594 let elem_oid = i32::from_be_bytes([buf[8], buf[9], buf[10], buf[11]]);
2595 assert_eq!(
2596 elem_oid, 23,
2597 "element OID must be preserved for empty arrays"
2598 );
2599 }
2600
2601 #[test]
2604 fn encode_at_bool() {
2605 let mut dst = [0u8; 1];
2606 assert!(true.encode_at(&mut dst));
2607 assert_eq!(dst[0], 1);
2608 assert!(false.encode_at(&mut dst));
2609 assert_eq!(dst[0], 0);
2610 assert!(!true.encode_at(&mut [0u8; 2]));
2612 }
2613
2614 #[test]
2615 fn encode_at_i16() {
2616 let mut dst = [0u8; 2];
2617 assert!(0x1234i16.encode_at(&mut dst));
2618 assert_eq!(dst, [0x12, 0x34]);
2619 assert!(!42i16.encode_at(&mut [0u8; 4]));
2620 }
2621
2622 #[test]
2623 fn encode_at_i32() {
2624 let mut dst = [0u8; 4];
2625 assert!(42i32.encode_at(&mut dst));
2626 assert_eq!(dst, [0, 0, 0, 42]);
2627 assert!(!42i32.encode_at(&mut [0u8; 8]));
2628 }
2629
2630 #[test]
2631 fn encode_at_i64() {
2632 let mut dst = [0u8; 8];
2633 assert!(1234567890123i64.encode_at(&mut dst));
2634 assert_eq!(dst, 1234567890123i64.to_be_bytes());
2635 assert!(!42i64.encode_at(&mut [0u8; 4]));
2636 }
2637
2638 #[test]
2639 fn encode_at_f32() {
2640 let mut dst = [0u8; 4];
2641 assert!(3.14f32.encode_at(&mut dst));
2642 assert_eq!(dst, 3.14f32.to_be_bytes());
2643 assert!(!3.14f32.encode_at(&mut [0u8; 8]));
2644 }
2645
2646 #[test]
2647 fn encode_at_f64() {
2648 let mut dst = [0u8; 8];
2649 assert!(3.14f64.encode_at(&mut dst));
2650 assert_eq!(dst, 3.14f64.to_be_bytes());
2651 assert!(!3.14f64.encode_at(&mut [0u8; 4]));
2652 }
2653
2654 #[test]
2655 fn encode_at_u32() {
2656 let mut dst = [0u8; 4];
2657 assert!(42u32.encode_at(&mut dst));
2658 assert_eq!(dst, 42u32.to_be_bytes());
2659 }
2660
2661 #[test]
2662 fn encode_at_str_default_fallback() {
2663 let s: &str = "hello";
2665 let mut dst = [0u8; 5];
2666 assert!(s.encode_at(&mut dst));
2667 assert_eq!(&dst, b"hello");
2668 assert!(!s.encode_at(&mut [0u8; 3]));
2670 }
2671
2672 #[test]
2673 fn encode_at_matches_encode_binary() {
2674 fn check<T: Encode>(val: T, expected_len: usize) {
2677 let mut buf = Vec::new();
2678 val.encode_binary(&mut buf);
2679 assert_eq!(buf.len(), expected_len);
2680 let mut dst = vec![0u8; expected_len];
2681 assert!(val.encode_at(&mut dst));
2682 assert_eq!(
2683 buf, dst,
2684 "encode_at must produce same bytes as encode_binary"
2685 );
2686 }
2687 check(true, 1);
2688 check(false, 1);
2689 check(42i16, 2);
2690 check(i16::MAX, 2);
2691 check(42i32, 4);
2692 check(i32::MIN, 4);
2693 check(42i64, 8);
2694 check(3.14f32, 4);
2695 check(3.14f64, 8);
2696 check(42u32, 4);
2697 }
2698
2699 #[test]
2702 fn str_10kb_roundtrip() {
2703 let big = "A".repeat(10 * 1024);
2704 let mut buf = Vec::new();
2705 big.as_str().encode_binary(&mut buf);
2706 assert_eq!(buf.len(), 10 * 1024);
2707 assert_eq!(decode_str(&buf).unwrap(), big);
2708 }
2709
2710 #[test]
2713 fn empty_vec_u8_encode_roundtrip() {
2714 let mut buf = Vec::new();
2715 Vec::<u8>::new().encode_binary(&mut buf);
2716 assert!(buf.is_empty(), "empty Vec<u8> should produce no bytes");
2717 assert_eq!(decode_bytes(&buf).len(), 0);
2718 }
2719
2720 #[test]
2723 fn f32_min_max_roundtrip() {
2724 let mut buf = Vec::new();
2725 f32::MIN.encode_binary(&mut buf);
2726 assert_eq!(decode_f32(&buf).unwrap(), f32::MIN);
2727
2728 buf.clear();
2729 f32::MAX.encode_binary(&mut buf);
2730 assert_eq!(decode_f32(&buf).unwrap(), f32::MAX);
2731 }
2732
2733 #[test]
2736 fn f64_min_max_roundtrip() {
2737 let mut buf = Vec::new();
2738 f64::MIN.encode_binary(&mut buf);
2739 assert_eq!(decode_f64(&buf).unwrap(), f64::MIN);
2740
2741 buf.clear();
2742 f64::MAX.encode_binary(&mut buf);
2743 assert_eq!(decode_f64(&buf).unwrap(), f64::MAX);
2744 }
2745
2746 #[test]
2749 fn i32_zero_roundtrip() {
2750 let mut buf = Vec::new();
2751 0i32.encode_binary(&mut buf);
2752 assert_eq!(decode_i32(&buf).unwrap(), 0);
2753 }
2754
2755 #[test]
2758 fn i64_zero_roundtrip() {
2759 let mut buf = Vec::new();
2760 0i64.encode_binary(&mut buf);
2761 assert_eq!(decode_i64(&buf).unwrap(), 0);
2762 }
2763
2764 #[test]
2767 fn i16_zero_roundtrip() {
2768 let mut buf = Vec::new();
2769 0i16.encode_binary(&mut buf);
2770 assert_eq!(decode_i16(&buf).unwrap(), 0);
2771 }
2772
2773 #[test]
2776 fn f32_subnormal_roundtrip() {
2777 let mut buf = Vec::new();
2778 f32::MIN_POSITIVE.encode_binary(&mut buf);
2779 assert_eq!(decode_f32(&buf).unwrap(), f32::MIN_POSITIVE);
2780 }
2781
2782 #[test]
2785 fn f64_subnormal_roundtrip() {
2786 let mut buf = Vec::new();
2787 f64::MIN_POSITIVE.encode_binary(&mut buf);
2788 assert_eq!(decode_f64(&buf).unwrap(), f64::MIN_POSITIVE);
2789 }
2790
2791 #[test]
2794 fn f32_nan_bit_preservation() {
2795 let mut buf = Vec::new();
2796 f32::NAN.encode_binary(&mut buf);
2797 let decoded = decode_f32(&buf).unwrap();
2798 assert!(decoded.is_nan());
2799 assert_eq!(decoded.to_bits(), f32::NAN.to_bits());
2801 }
2802
2803 #[test]
2806 fn f64_nan_bit_preservation() {
2807 let mut buf = Vec::new();
2808 f64::NAN.encode_binary(&mut buf);
2809 let decoded = decode_f64(&buf).unwrap();
2810 assert!(decoded.is_nan());
2811 assert_eq!(decoded.to_bits(), f64::NAN.to_bits());
2812 }
2813
2814 mod proptest_fuzz {
2815 use super::*;
2816 use proptest::prelude::*;
2817
2818 proptest! {
2819 #[test]
2820 fn i32_roundtrip(val: i32) {
2821 let mut buf = Vec::new();
2822 val.encode_binary(&mut buf);
2823 let decoded = decode_i32(&buf).unwrap();
2824 prop_assert_eq!(decoded, val);
2825 }
2826
2827 #[test]
2828 fn i64_roundtrip(val: i64) {
2829 let mut buf = Vec::new();
2830 val.encode_binary(&mut buf);
2831 let decoded = decode_i64(&buf).unwrap();
2832 prop_assert_eq!(decoded, val);
2833 }
2834
2835 #[test]
2836 fn i16_roundtrip(val: i16) {
2837 let mut buf = Vec::new();
2838 val.encode_binary(&mut buf);
2839 let decoded = decode_i16(&buf).unwrap();
2840 prop_assert_eq!(decoded, val);
2841 }
2842
2843 #[test]
2844 fn f32_roundtrip(val: f32) {
2845 let mut buf = Vec::new();
2846 val.encode_binary(&mut buf);
2847 let decoded = decode_f32(&buf).unwrap();
2848 if val.is_nan() {
2849 prop_assert!(decoded.is_nan());
2850 } else {
2851 prop_assert_eq!(decoded, val);
2852 }
2853 }
2854
2855 #[test]
2856 fn f64_roundtrip(val: f64) {
2857 let mut buf = Vec::new();
2858 val.encode_binary(&mut buf);
2859 let decoded = decode_f64(&buf).unwrap();
2860 if val.is_nan() {
2861 prop_assert!(decoded.is_nan());
2862 } else {
2863 prop_assert_eq!(decoded, val);
2864 }
2865 }
2866
2867 #[test]
2868 fn bool_roundtrip(val: bool) {
2869 let mut buf = Vec::new();
2870 val.encode_binary(&mut buf);
2871 let decoded = decode_bool(&buf).unwrap();
2872 prop_assert_eq!(decoded, val);
2873 }
2874
2875 #[test]
2876 fn str_roundtrip(val in "\\PC*") {
2877 let mut buf = Vec::new();
2878 val.as_str().encode_binary(&mut buf);
2879 let decoded = decode_str(&buf).unwrap();
2880 prop_assert_eq!(decoded, val.as_str());
2881 }
2882
2883 #[test]
2884 fn decode_i32_arbitrary_never_panics(data in proptest::collection::vec(any::<u8>(), 0..16)) {
2885 let _ = decode_i32(&data);
2886 }
2887
2888 #[test]
2889 fn decode_str_arbitrary_never_panics(data in proptest::collection::vec(any::<u8>(), 0..1024)) {
2890 let _ = decode_str(&data);
2891 }
2892 }
2893 }
2894}