1use crate::DriverError;
9#[cfg(feature = "chrono")]
10use chrono::{Datelike, Timelike};
11
12#[cfg(any(feature = "time", feature = "chrono"))]
19const PG_EPOCH_UNIX_SECS: i64 = 946_684_800;
20
21#[cfg(any(feature = "time", feature = "chrono"))]
23const PG_EPOCH_UNIX_MICROS: i64 = PG_EPOCH_UNIX_SECS * 1_000_000;
24
25#[cfg(feature = "time")]
27const PG_EPOCH_JULIAN_DAY: i32 = 2_451_545;
28
29pub trait Encode {
46 fn encode_binary(&self, buf: &mut Vec<u8>);
48
49 fn type_oid(&self) -> u32;
51
52 fn is_null(&self) -> bool {
57 false
58 }
59
60 fn encode_at(&self, dst: &mut [u8]) -> bool {
70 let mut tmp = Vec::with_capacity(dst.len());
72 self.encode_binary(&mut tmp);
73 if tmp.len() == dst.len() {
74 dst.copy_from_slice(&tmp);
75 true
76 } else {
77 false
78 }
79 }
80}
81
82impl Encode for bool {
85 #[inline]
86 fn encode_binary(&self, buf: &mut Vec<u8>) {
87 buf.push(if *self { 1 } else { 0 });
88 }
89
90 #[inline]
91 fn type_oid(&self) -> u32 {
92 16 }
94
95 #[inline]
96 fn encode_at(&self, dst: &mut [u8]) -> bool {
97 if dst.len() != 1 {
98 return false;
99 }
100 dst[0] = if *self { 1 } else { 0 };
101 true
102 }
103}
104
105impl Encode for i16 {
106 #[inline]
107 fn encode_binary(&self, buf: &mut Vec<u8>) {
108 buf.extend_from_slice(&self.to_be_bytes());
109 }
110
111 #[inline]
112 fn type_oid(&self) -> u32 {
113 21 }
115
116 #[inline]
117 fn encode_at(&self, dst: &mut [u8]) -> bool {
118 if dst.len() != 2 {
119 return false;
120 }
121 dst.copy_from_slice(&self.to_be_bytes());
122 true
123 }
124}
125
126impl Encode for i32 {
127 #[inline]
128 fn encode_binary(&self, buf: &mut Vec<u8>) {
129 buf.extend_from_slice(&self.to_be_bytes());
130 }
131
132 #[inline]
133 fn type_oid(&self) -> u32 {
134 23 }
136
137 #[inline]
138 fn encode_at(&self, dst: &mut [u8]) -> bool {
139 if dst.len() != 4 {
140 return false;
141 }
142 dst.copy_from_slice(&self.to_be_bytes());
143 true
144 }
145}
146
147impl Encode for i64 {
148 #[inline]
149 fn encode_binary(&self, buf: &mut Vec<u8>) {
150 buf.extend_from_slice(&self.to_be_bytes());
151 }
152
153 #[inline]
154 fn type_oid(&self) -> u32 {
155 20 }
157
158 #[inline]
159 fn encode_at(&self, dst: &mut [u8]) -> bool {
160 if dst.len() != 8 {
161 return false;
162 }
163 dst.copy_from_slice(&self.to_be_bytes());
164 true
165 }
166}
167
168impl Encode for f32 {
169 #[inline]
170 fn encode_binary(&self, buf: &mut Vec<u8>) {
171 buf.extend_from_slice(&self.to_be_bytes());
172 }
173
174 #[inline]
175 fn type_oid(&self) -> u32 {
176 700 }
178
179 #[inline]
180 fn encode_at(&self, dst: &mut [u8]) -> bool {
181 if dst.len() != 4 {
182 return false;
183 }
184 dst.copy_from_slice(&self.to_be_bytes());
185 true
186 }
187}
188
189impl Encode for f64 {
190 #[inline]
191 fn encode_binary(&self, buf: &mut Vec<u8>) {
192 buf.extend_from_slice(&self.to_be_bytes());
193 }
194
195 #[inline]
196 fn type_oid(&self) -> u32 {
197 701 }
199
200 #[inline]
201 fn encode_at(&self, dst: &mut [u8]) -> bool {
202 if dst.len() != 8 {
203 return false;
204 }
205 dst.copy_from_slice(&self.to_be_bytes());
206 true
207 }
208}
209
210impl Encode for &str {
211 #[inline]
212 fn encode_binary(&self, buf: &mut Vec<u8>) {
213 buf.extend_from_slice(self.as_bytes());
214 }
215
216 #[inline]
217 fn type_oid(&self) -> u32 {
218 25 }
220
221 #[inline]
222 fn encode_at(&self, dst: &mut [u8]) -> bool {
223 let bytes = self.as_bytes();
224 if bytes.len() != dst.len() {
225 return false;
226 }
227 dst.copy_from_slice(bytes);
228 true
229 }
230}
231
232impl Encode for String {
233 #[inline]
234 fn encode_binary(&self, buf: &mut Vec<u8>) {
235 buf.extend_from_slice(self.as_bytes());
236 }
237
238 #[inline]
239 fn type_oid(&self) -> u32 {
240 25 }
242
243 #[inline]
244 fn encode_at(&self, dst: &mut [u8]) -> bool {
245 self.as_str().encode_at(dst)
246 }
247}
248
249impl Encode for &[u8] {
250 #[inline]
251 fn encode_binary(&self, buf: &mut Vec<u8>) {
252 buf.extend_from_slice(self);
253 }
254
255 #[inline]
256 fn type_oid(&self) -> u32 {
257 17 }
259
260 #[inline]
261 fn encode_at(&self, dst: &mut [u8]) -> bool {
262 if self.len() != dst.len() {
263 return false;
264 }
265 dst.copy_from_slice(self);
266 true
267 }
268}
269
270impl Encode for Vec<u8> {
271 #[inline]
272 fn encode_binary(&self, buf: &mut Vec<u8>) {
273 buf.extend_from_slice(self);
274 }
275
276 #[inline]
277 fn type_oid(&self) -> u32 {
278 17 }
280
281 #[inline]
282 fn encode_at(&self, dst: &mut [u8]) -> bool {
283 if self.len() != dst.len() {
284 return false;
285 }
286 dst.copy_from_slice(self);
287 true
288 }
289}
290
291impl Encode for u32 {
292 #[inline]
293 fn encode_binary(&self, buf: &mut Vec<u8>) {
294 buf.extend_from_slice(&self.to_be_bytes());
295 }
296
297 #[inline]
298 fn type_oid(&self) -> u32 {
299 26 }
301
302 #[inline]
303 fn encode_at(&self, dst: &mut [u8]) -> bool {
304 if dst.len() != 4 {
305 return false;
306 }
307 dst.copy_from_slice(&self.to_be_bytes());
308 true
309 }
310}
311
312impl<T: Encode> Encode for Option<T> {
315 #[inline]
316 fn encode_binary(&self, buf: &mut Vec<u8>) {
317 if let Some(val) = self {
318 val.encode_binary(buf);
319 }
320 }
323
324 #[inline]
325 fn type_oid(&self) -> u32 {
326 match self {
331 Some(val) => val.type_oid(),
332 None => 0,
333 }
334 }
335
336 #[inline]
337 fn is_null(&self) -> bool {
338 self.is_none()
339 }
340}
341
342#[cfg(feature = "uuid")]
345impl Encode for uuid::Uuid {
346 #[inline]
347 fn encode_binary(&self, buf: &mut Vec<u8>) {
348 buf.extend_from_slice(self.as_bytes());
349 }
350
351 #[inline]
352 fn type_oid(&self) -> u32 {
353 2950 }
355
356 #[inline]
357 fn encode_at(&self, dst: &mut [u8]) -> bool {
358 if dst.len() != 16 {
359 return false;
360 }
361 dst.copy_from_slice(self.as_bytes());
362 true
363 }
364}
365
366#[cfg(feature = "time")]
367impl Encode for time::OffsetDateTime {
368 #[inline]
369 fn encode_binary(&self, buf: &mut Vec<u8>) {
370 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
371 }
372
373 #[inline]
374 fn type_oid(&self) -> u32 {
375 1184 }
377
378 #[inline]
379 fn encode_at(&self, dst: &mut [u8]) -> bool {
380 if dst.len() != 8 {
381 return false;
382 }
383 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
384 true
385 }
386}
387
388#[cfg(feature = "time")]
389trait OffsetDateTimeExt {
390 fn encode_pg_micros(&self) -> i64;
391}
392
393#[cfg(feature = "time")]
394impl OffsetDateTimeExt for time::OffsetDateTime {
395 #[inline]
396 fn encode_pg_micros(&self) -> i64 {
397 let unix_nanos = self.unix_timestamp_nanos();
400 let unix_micros = (unix_nanos / 1000) as i64;
401 unix_micros.saturating_sub(PG_EPOCH_UNIX_MICROS)
402 }
403}
404
405#[cfg(feature = "time")]
406impl Encode for time::Date {
407 #[inline]
408 fn encode_binary(&self, buf: &mut Vec<u8>) {
409 buf.extend_from_slice(&self.encode_pg_days().to_be_bytes());
410 }
411
412 #[inline]
413 fn type_oid(&self) -> u32 {
414 1082 }
416
417 #[inline]
418 fn encode_at(&self, dst: &mut [u8]) -> bool {
419 if dst.len() != 4 {
420 return false;
421 }
422 dst.copy_from_slice(&self.encode_pg_days().to_be_bytes());
423 true
424 }
425}
426
427#[cfg(feature = "time")]
428trait DateExt {
429 fn encode_pg_days(&self) -> i32;
430}
431
432#[cfg(feature = "time")]
433impl DateExt for time::Date {
434 #[inline]
435 fn encode_pg_days(&self) -> i32 {
436 self.to_julian_day() - PG_EPOCH_JULIAN_DAY
439 }
440}
441
442#[cfg(feature = "time")]
443impl Encode for time::Time {
444 #[inline]
445 fn encode_binary(&self, buf: &mut Vec<u8>) {
446 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
447 }
448
449 #[inline]
450 fn type_oid(&self) -> u32 {
451 1083 }
453
454 #[inline]
455 fn encode_at(&self, dst: &mut [u8]) -> bool {
456 if dst.len() != 8 {
457 return false;
458 }
459 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
460 true
461 }
462}
463
464#[cfg(feature = "time")]
465trait TimeExt {
466 fn encode_pg_micros(&self) -> i64;
467}
468
469#[cfg(feature = "time")]
470impl TimeExt for time::Time {
471 #[inline]
472 fn encode_pg_micros(&self) -> i64 {
473 let midnight = time::Time::MIDNIGHT;
475 let diff = *self - midnight;
476 diff.whole_microseconds() as i64
477 }
478}
479
480#[cfg(feature = "time")]
481impl Encode for time::PrimitiveDateTime {
482 #[inline]
483 fn encode_binary(&self, buf: &mut Vec<u8>) {
484 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
485 }
486
487 #[inline]
488 fn type_oid(&self) -> u32 {
489 1114 }
491
492 #[inline]
493 fn encode_at(&self, dst: &mut [u8]) -> bool {
494 if dst.len() != 8 {
495 return false;
496 }
497 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
498 true
499 }
500}
501
502#[cfg(feature = "time")]
503trait PrimitiveDateTimeExt {
504 fn encode_pg_micros(&self) -> i64;
505}
506
507#[cfg(feature = "time")]
508impl PrimitiveDateTimeExt for time::PrimitiveDateTime {
509 #[inline]
510 fn encode_pg_micros(&self) -> i64 {
511 let unix_nanos = self.assume_utc().unix_timestamp_nanos();
515 let unix_micros = (unix_nanos / 1000) as i64;
516 unix_micros.saturating_sub(PG_EPOCH_UNIX_MICROS)
517 }
518}
519
520#[cfg(feature = "chrono")]
521impl Encode for chrono::NaiveDateTime {
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 1114 }
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 NaiveDateTimeExt {
544 fn encode_pg_micros(&self) -> i64;
545}
546
547#[cfg(feature = "chrono")]
548impl NaiveDateTimeExt for chrono::NaiveDateTime {
549 #[inline]
550 fn encode_pg_micros(&self) -> i64 {
551 let unix_micros = self.and_utc().timestamp_micros();
553 unix_micros.saturating_sub(PG_EPOCH_UNIX_MICROS)
554 }
555}
556
557#[cfg(feature = "chrono")]
558impl Encode for chrono::DateTime<chrono::Utc> {
559 #[inline]
560 fn encode_binary(&self, buf: &mut Vec<u8>) {
561 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
562 }
563
564 #[inline]
565 fn type_oid(&self) -> u32 {
566 1184 }
568
569 #[inline]
570 fn encode_at(&self, dst: &mut [u8]) -> bool {
571 if dst.len() != 8 {
572 return false;
573 }
574 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
575 true
576 }
577}
578
579#[cfg(feature = "chrono")]
580trait ChronoDateTimeUtcExt {
581 fn encode_pg_micros(&self) -> i64;
582}
583
584#[cfg(feature = "chrono")]
585impl ChronoDateTimeUtcExt for chrono::DateTime<chrono::Utc> {
586 #[inline]
587 fn encode_pg_micros(&self) -> i64 {
588 let unix_micros = self.timestamp_micros();
590 unix_micros.saturating_sub(PG_EPOCH_UNIX_MICROS)
591 }
592}
593
594#[cfg(feature = "chrono")]
595impl Encode for chrono::NaiveDate {
596 #[inline]
597 fn encode_binary(&self, buf: &mut Vec<u8>) {
598 buf.extend_from_slice(&self.encode_pg_days().to_be_bytes());
599 }
600
601 #[inline]
602 fn type_oid(&self) -> u32 {
603 1082 }
605
606 #[inline]
607 fn encode_at(&self, dst: &mut [u8]) -> bool {
608 if dst.len() != 4 {
609 return false;
610 }
611 dst.copy_from_slice(&self.encode_pg_days().to_be_bytes());
612 true
613 }
614}
615
616#[cfg(feature = "chrono")]
617trait ChronoNaiveDateExt {
618 fn encode_pg_days(&self) -> i32;
619}
620
621#[cfg(feature = "chrono")]
622impl ChronoNaiveDateExt for chrono::NaiveDate {
623 #[inline]
624 fn encode_pg_days(&self) -> i32 {
625 const PG_EPOCH_CE_DAYS: i32 = 730_120;
629 let days_i64 = (self.num_days_from_ce() - PG_EPOCH_CE_DAYS) as i64;
630 i32::try_from(days_i64).unwrap_or(if days_i64 < 0 { i32::MIN } else { i32::MAX })
631 }
632}
633
634#[cfg(feature = "chrono")]
635impl Encode for chrono::NaiveTime {
636 #[inline]
637 fn encode_binary(&self, buf: &mut Vec<u8>) {
638 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
639 }
640
641 #[inline]
642 fn type_oid(&self) -> u32 {
643 1083 }
645
646 #[inline]
647 fn encode_at(&self, dst: &mut [u8]) -> bool {
648 if dst.len() != 8 {
649 return false;
650 }
651 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
652 true
653 }
654}
655
656#[cfg(feature = "chrono")]
657trait ChronoNaiveTimeExt {
658 fn encode_pg_micros(&self) -> i64;
659}
660
661#[cfg(feature = "chrono")]
662impl ChronoNaiveTimeExt for chrono::NaiveTime {
663 #[inline]
664 fn encode_pg_micros(&self) -> i64 {
665 let secs = self.num_seconds_from_midnight() as i64;
667 let nanos = self.nanosecond() % 1_000_000_000; let micros_in_sec = (nanos / 1000) as i64;
669 secs * 1_000_000 + micros_in_sec
670 }
671}
672
673#[cfg(feature = "decimal")]
674impl Encode for rust_decimal::Decimal {
675 fn encode_binary(&self, buf: &mut Vec<u8>) {
676 if self.is_zero() {
686 let dscale = i16::try_from(self.scale()).unwrap_or(i16::MAX);
688 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;
693 }
694
695 let sign: i16 = if self.is_sign_negative() {
696 0x4000
697 } else {
698 0x0000
699 };
700 let scale = self.scale();
701
702 let abs = self.abs();
704 let mut mantissa = abs.mantissa().unsigned_abs();
705
706 let mut decimal_digits: smallvec::SmallVec<[i16; 32]> = smallvec::SmallVec::new();
708 while mantissa > 0 {
709 decimal_digits.push((mantissa % 10) as i16);
710 mantissa /= 10;
711 }
712 decimal_digits.reverse();
713
714 let total_digits = decimal_digits.len();
718 let scale_usize = scale as usize;
719 let int_len = total_digits.saturating_sub(scale_usize);
720 let sig_frac_len = total_digits - int_len; let mut padded: smallvec::SmallVec<[i16; 32]> = smallvec::SmallVec::new();
725
726 let int_pad = if int_len > 0 {
728 (4 - (int_len % 4)) % 4
729 } else {
730 0
731 };
732 padded.extend(std::iter::repeat(0i16).take(int_pad));
733 padded.extend_from_slice(&decimal_digits[..int_len]);
734
735 let implicit_zeros = scale_usize.saturating_sub(sig_frac_len);
739 padded.extend(std::iter::repeat(0i16).take(implicit_zeros));
740 padded.extend_from_slice(&decimal_digits[int_len..]);
741 let frac_total = implicit_zeros + sig_frac_len; let frac_pad = (4 - (frac_total % 4)) % 4;
743 padded.extend(std::iter::repeat(0i16).take(frac_pad));
744
745 let mut pg_digits: smallvec::SmallVec<[i16; 12]> = smallvec::SmallVec::new();
747 for chunk in padded.chunks(4) {
748 let d = chunk[0] * 1000 + chunk[1] * 100 + chunk[2] * 10 + chunk[3];
749 pg_digits.push(d);
750 }
751
752 let int_groups = if int_len > 0 {
754 (int_len + int_pad) / 4
755 } else {
756 0
757 };
758
759 let mut leading_frac_zeros = 0usize;
761 for i in int_groups..pg_digits.len() {
762 if pg_digits[i] == 0 {
763 leading_frac_zeros += 1;
764 } else {
765 break;
766 }
767 }
768
769 while pg_digits.len() > int_groups + leading_frac_zeros
771 && pg_digits.last().copied() == Some(0)
772 {
773 pg_digits.pop();
774 }
775
776 if leading_frac_zeros > 0 {
778 pg_digits.drain(int_groups..int_groups + leading_frac_zeros);
779 }
780
781 let ndigits = pg_digits.len() as i16;
782
783 let weight: i16 = if int_groups > 0 {
785 let w = (int_groups - 1) as i32;
786 w.clamp(i16::MIN as i32, i16::MAX as i32) as i16
787 } else {
788 let w = -(leading_frac_zeros as i32 + 1);
790 w.clamp(i16::MIN as i32, i16::MAX as i32) as i16
791 };
792
793 let dscale = i16::try_from(scale).unwrap_or(i16::MAX);
794 buf.extend_from_slice(&ndigits.to_be_bytes());
795 buf.extend_from_slice(&weight.to_be_bytes());
796 buf.extend_from_slice(&sign.to_be_bytes());
797 buf.extend_from_slice(&dscale.to_be_bytes());
798 for d in &pg_digits {
799 buf.extend_from_slice(&d.to_be_bytes());
800 }
801 }
802
803 #[inline]
804 fn type_oid(&self) -> u32 {
805 1700 }
807}
808
809#[inline]
817pub fn decode_bool(data: &[u8]) -> Result<bool, DriverError> {
818 if data.len() != 1 {
819 return Err(DriverError::Protocol(format!(
820 "bool: expected 1 byte, got {}",
821 data.len()
822 )));
823 }
824 Ok(data[0] != 0)
825}
826
827#[inline]
829pub fn decode_i16(data: &[u8]) -> Result<i16, DriverError> {
830 if data.len() != 2 {
831 return Err(DriverError::Protocol(format!(
832 "i16: expected 2 bytes, got {}",
833 data.len()
834 )));
835 }
836 Ok(i16::from_be_bytes([data[0], data[1]]))
837}
838
839#[inline]
841pub fn decode_i32(data: &[u8]) -> Result<i32, DriverError> {
842 if data.len() != 4 {
843 return Err(DriverError::Protocol(format!(
844 "i32: expected 4 bytes, got {}",
845 data.len()
846 )));
847 }
848 Ok(i32::from_be_bytes([data[0], data[1], data[2], data[3]]))
849}
850
851#[inline]
853pub fn decode_i64(data: &[u8]) -> Result<i64, DriverError> {
854 if data.len() != 8 {
855 return Err(DriverError::Protocol(format!(
856 "i64: expected 8 bytes, got {}",
857 data.len()
858 )));
859 }
860 Ok(i64::from_be_bytes([
861 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
862 ]))
863}
864
865#[inline]
867pub fn decode_f32(data: &[u8]) -> Result<f32, DriverError> {
868 if data.len() != 4 {
869 return Err(DriverError::Protocol(format!(
870 "f32: expected 4 bytes, got {}",
871 data.len()
872 )));
873 }
874 Ok(f32::from_be_bytes([data[0], data[1], data[2], data[3]]))
875}
876
877#[inline]
879pub fn decode_f64(data: &[u8]) -> Result<f64, DriverError> {
880 if data.len() != 8 {
881 return Err(DriverError::Protocol(format!(
882 "f64: expected 8 bytes, got {}",
883 data.len()
884 )));
885 }
886 Ok(f64::from_be_bytes([
887 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
888 ]))
889}
890
891#[inline]
897pub fn decode_str(data: &[u8]) -> Result<&str, DriverError> {
898 simdutf8::basic::from_utf8(data)
899 .map_err(|e| DriverError::Protocol(format!("invalid UTF-8 in text column: {e}")))
900}
901
902#[inline]
904pub fn decode_bytes(data: &[u8]) -> &[u8] {
905 data
906}
907
908#[inline]
910pub fn decode_uuid(data: &[u8]) -> Result<[u8; 16], DriverError> {
911 if data.len() != 16 {
912 return Err(DriverError::Protocol(format!(
913 "uuid: expected 16 bytes, got {}",
914 data.len()
915 )));
916 }
917 let mut uuid = [0u8; 16];
918 uuid.copy_from_slice(data);
919 Ok(uuid)
920}
921
922pub fn encode_param(buf: &mut Vec<u8>, param: &dyn Encode) {
926 let start = buf.len();
927 buf.extend_from_slice(&[0u8; 4]); param.encode_binary(buf);
929 let data_len = (buf.len() - start - 4) as i32;
930 buf[start..start + 4].copy_from_slice(&data_len.to_be_bytes());
931}
932
933fn encode_array_header(buf: &mut Vec<u8>, n_elements: usize, elem_oid: u32) {
940 if n_elements == 0 {
941 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;
945 }
946 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()); }
952
953impl Encode for [bool] {
956 fn encode_binary(&self, buf: &mut Vec<u8>) {
957 encode_array_header(buf, self.len(), 16);
958 buf.reserve(self.len() * 5);
960 for val in self {
961 let tmp = [0u8, 0, 0, 1, if *val { 1 } else { 0 }];
962 buf.extend_from_slice(&tmp);
963 }
964 }
965
966 #[inline]
967 fn type_oid(&self) -> u32 {
968 1000 }
970}
971
972impl Encode for &[bool] {
973 #[inline]
974 fn encode_binary(&self, buf: &mut Vec<u8>) {
975 (**self).encode_binary(buf);
976 }
977
978 #[inline]
979 fn type_oid(&self) -> u32 {
980 1000
981 }
982}
983
984impl Encode for Vec<bool> {
985 #[inline]
986 fn encode_binary(&self, buf: &mut Vec<u8>) {
987 self.as_slice().encode_binary(buf);
988 }
989
990 #[inline]
991 fn type_oid(&self) -> u32 {
992 1000
993 }
994}
995
996impl Encode for [i16] {
997 fn encode_binary(&self, buf: &mut Vec<u8>) {
998 encode_array_header(buf, self.len(), 21);
999 buf.reserve(self.len() * 6);
1001 for val in self {
1002 let mut tmp = [0u8; 6];
1003 tmp[0..4].copy_from_slice(&2i32.to_be_bytes());
1004 tmp[4..6].copy_from_slice(&val.to_be_bytes());
1005 buf.extend_from_slice(&tmp);
1006 }
1007 }
1008
1009 #[inline]
1010 fn type_oid(&self) -> u32 {
1011 1005 }
1013}
1014
1015impl Encode for &[i16] {
1016 #[inline]
1017 fn encode_binary(&self, buf: &mut Vec<u8>) {
1018 (**self).encode_binary(buf);
1019 }
1020
1021 #[inline]
1022 fn type_oid(&self) -> u32 {
1023 1005
1024 }
1025}
1026
1027impl Encode for Vec<i16> {
1028 #[inline]
1029 fn encode_binary(&self, buf: &mut Vec<u8>) {
1030 self.as_slice().encode_binary(buf);
1031 }
1032
1033 #[inline]
1034 fn type_oid(&self) -> u32 {
1035 1005
1036 }
1037}
1038
1039impl Encode for [i32] {
1040 fn encode_binary(&self, buf: &mut Vec<u8>) {
1041 encode_array_header(buf, self.len(), 23);
1042 buf.reserve(self.len() * 8);
1044 for val in self {
1045 let mut tmp = [0u8; 8];
1046 tmp[0..4].copy_from_slice(&4i32.to_be_bytes());
1047 tmp[4..8].copy_from_slice(&val.to_be_bytes());
1048 buf.extend_from_slice(&tmp);
1049 }
1050 }
1051
1052 #[inline]
1053 fn type_oid(&self) -> u32 {
1054 1007 }
1056}
1057
1058impl Encode for &[i32] {
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 1007
1067 }
1068}
1069
1070impl Encode for Vec<i32> {
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 1007
1079 }
1080}
1081
1082impl Encode for [i64] {
1083 fn encode_binary(&self, buf: &mut Vec<u8>) {
1084 encode_array_header(buf, self.len(), 20);
1085 buf.reserve(self.len() * 12);
1087 for val in self {
1088 let mut tmp = [0u8; 12];
1089 tmp[0..4].copy_from_slice(&8i32.to_be_bytes());
1090 tmp[4..12].copy_from_slice(&val.to_be_bytes());
1091 buf.extend_from_slice(&tmp);
1092 }
1093 }
1094
1095 #[inline]
1096 fn type_oid(&self) -> u32 {
1097 1016 }
1099}
1100
1101impl Encode for &[i64] {
1102 #[inline]
1103 fn encode_binary(&self, buf: &mut Vec<u8>) {
1104 (**self).encode_binary(buf);
1105 }
1106
1107 #[inline]
1108 fn type_oid(&self) -> u32 {
1109 1016
1110 }
1111}
1112
1113impl Encode for Vec<i64> {
1114 #[inline]
1115 fn encode_binary(&self, buf: &mut Vec<u8>) {
1116 self.as_slice().encode_binary(buf);
1117 }
1118
1119 #[inline]
1120 fn type_oid(&self) -> u32 {
1121 1016
1122 }
1123}
1124
1125impl Encode for [f32] {
1126 fn encode_binary(&self, buf: &mut Vec<u8>) {
1127 encode_array_header(buf, self.len(), 700);
1128 buf.reserve(self.len() * 8);
1130 for val in self {
1131 let mut tmp = [0u8; 8];
1132 tmp[0..4].copy_from_slice(&4i32.to_be_bytes());
1133 tmp[4..8].copy_from_slice(&val.to_be_bytes());
1134 buf.extend_from_slice(&tmp);
1135 }
1136 }
1137
1138 #[inline]
1139 fn type_oid(&self) -> u32 {
1140 1021 }
1142}
1143
1144impl Encode for &[f32] {
1145 #[inline]
1146 fn encode_binary(&self, buf: &mut Vec<u8>) {
1147 (**self).encode_binary(buf);
1148 }
1149
1150 #[inline]
1151 fn type_oid(&self) -> u32 {
1152 1021
1153 }
1154}
1155
1156impl Encode for Vec<f32> {
1157 #[inline]
1158 fn encode_binary(&self, buf: &mut Vec<u8>) {
1159 self.as_slice().encode_binary(buf);
1160 }
1161
1162 #[inline]
1163 fn type_oid(&self) -> u32 {
1164 1021
1165 }
1166}
1167
1168impl Encode for [f64] {
1169 fn encode_binary(&self, buf: &mut Vec<u8>) {
1170 encode_array_header(buf, self.len(), 701);
1171 buf.reserve(self.len() * 12);
1173 for val in self {
1174 let mut tmp = [0u8; 12];
1175 tmp[0..4].copy_from_slice(&8i32.to_be_bytes());
1176 tmp[4..12].copy_from_slice(&val.to_be_bytes());
1177 buf.extend_from_slice(&tmp);
1178 }
1179 }
1180
1181 #[inline]
1182 fn type_oid(&self) -> u32 {
1183 1022 }
1185}
1186
1187impl Encode for &[f64] {
1188 #[inline]
1189 fn encode_binary(&self, buf: &mut Vec<u8>) {
1190 (**self).encode_binary(buf);
1191 }
1192
1193 #[inline]
1194 fn type_oid(&self) -> u32 {
1195 1022
1196 }
1197}
1198
1199impl Encode for Vec<f64> {
1200 #[inline]
1201 fn encode_binary(&self, buf: &mut Vec<u8>) {
1202 self.as_slice().encode_binary(buf);
1203 }
1204
1205 #[inline]
1206 fn type_oid(&self) -> u32 {
1207 1022
1208 }
1209}
1210
1211impl Encode for [&str] {
1212 fn encode_binary(&self, buf: &mut Vec<u8>) {
1213 encode_array_header(buf, self.len(), 25);
1214 for val in self {
1215 let bytes = val.as_bytes();
1216 buf.extend_from_slice(&(bytes.len() as i32).to_be_bytes());
1217 buf.extend_from_slice(bytes);
1218 }
1219 }
1220
1221 #[inline]
1222 fn type_oid(&self) -> u32 {
1223 1009 }
1225}
1226
1227impl Encode for &[&str] {
1228 #[inline]
1229 fn encode_binary(&self, buf: &mut Vec<u8>) {
1230 (**self).encode_binary(buf);
1231 }
1232
1233 #[inline]
1234 fn type_oid(&self) -> u32 {
1235 1009
1236 }
1237}
1238
1239impl Encode for Vec<String> {
1240 fn encode_binary(&self, buf: &mut Vec<u8>) {
1241 encode_array_header(buf, self.len(), 25);
1242 for val in self {
1243 let bytes = val.as_bytes();
1244 buf.extend_from_slice(&(bytes.len() as i32).to_be_bytes());
1245 buf.extend_from_slice(bytes);
1246 }
1247 }
1248
1249 #[inline]
1250 fn type_oid(&self) -> u32 {
1251 1009 }
1253}
1254
1255impl Encode for [String] {
1256 fn encode_binary(&self, buf: &mut Vec<u8>) {
1257 encode_array_header(buf, self.len(), 25); for val in self {
1259 let bytes = val.as_bytes();
1260 buf.extend_from_slice(&(bytes.len() as i32).to_be_bytes());
1261 buf.extend_from_slice(bytes);
1262 }
1263 }
1264
1265 #[inline]
1266 fn type_oid(&self) -> u32 {
1267 1009
1268 }
1269}
1270
1271impl Encode for &[String] {
1272 #[inline]
1273 fn encode_binary(&self, buf: &mut Vec<u8>) {
1274 (**self).encode_binary(buf);
1275 }
1276
1277 #[inline]
1278 fn type_oid(&self) -> u32 {
1279 1009
1280 }
1281}
1282
1283impl Encode for [&[u8]] {
1284 fn encode_binary(&self, buf: &mut Vec<u8>) {
1285 encode_array_header(buf, self.len(), 17);
1286 for val in self {
1287 buf.extend_from_slice(&(val.len() as i32).to_be_bytes());
1288 buf.extend_from_slice(val);
1289 }
1290 }
1291
1292 #[inline]
1293 fn type_oid(&self) -> u32 {
1294 1001 }
1296}
1297
1298impl Encode for &[&[u8]] {
1299 #[inline]
1300 fn encode_binary(&self, buf: &mut Vec<u8>) {
1301 (**self).encode_binary(buf);
1302 }
1303
1304 #[inline]
1305 fn type_oid(&self) -> u32 {
1306 1001
1307 }
1308}
1309
1310impl Encode for [Vec<u8>] {
1311 fn encode_binary(&self, buf: &mut Vec<u8>) {
1312 encode_array_header(buf, self.len(), 17);
1313 for val in self {
1314 buf.extend_from_slice(&(val.len() as i32).to_be_bytes());
1315 buf.extend_from_slice(val);
1316 }
1317 }
1318
1319 #[inline]
1320 fn type_oid(&self) -> u32 {
1321 1001 }
1323}
1324
1325impl Encode for &[Vec<u8>] {
1326 #[inline]
1327 fn encode_binary(&self, buf: &mut Vec<u8>) {
1328 (**self).encode_binary(buf);
1329 }
1330
1331 #[inline]
1332 fn type_oid(&self) -> u32 {
1333 1001
1334 }
1335}
1336
1337impl Encode for Vec<Vec<u8>> {
1338 #[inline]
1339 fn encode_binary(&self, buf: &mut Vec<u8>) {
1340 self.as_slice().encode_binary(buf);
1341 }
1342
1343 #[inline]
1344 fn type_oid(&self) -> u32 {
1345 1001 }
1347}
1348
1349fn decode_array_elements(data: &[u8]) -> Result<Vec<&[u8]>, DriverError> {
1360 if data.len() < 12 {
1361 return Err(DriverError::Protocol(format!(
1362 "array: expected >= 12 bytes header, got {}",
1363 data.len()
1364 )));
1365 }
1366 let ndim = i32::from_be_bytes([data[0], data[1], data[2], data[3]]);
1367 if ndim == 0 {
1368 return Ok(Vec::new());
1369 }
1370 if ndim != 1 {
1371 return Err(DriverError::Protocol(format!(
1372 "array: only 1-dimensional arrays supported, got {ndim}"
1373 )));
1374 }
1375 if data.len() < 20 {
1377 return Err(DriverError::Protocol(
1378 "array: truncated dimension header".into(),
1379 ));
1380 }
1381 let n_elements_raw = i32::from_be_bytes([data[12], data[13], data[14], data[15]]);
1382 if n_elements_raw < 0 {
1383 return Err(DriverError::Protocol(
1384 "array: negative element count".into(),
1385 ));
1386 }
1387 let n_elements = n_elements_raw as usize;
1388 const MAX_ARRAY_ELEMENTS: usize = 10_000_000;
1392 if n_elements > MAX_ARRAY_ELEMENTS {
1393 return Err(DriverError::Protocol(format!(
1394 "array element count {n_elements} exceeds limit of {MAX_ARRAY_ELEMENTS}"
1395 )));
1396 }
1397 let mut pos = 20;
1399 let mut elements = Vec::with_capacity(n_elements);
1400 for _ in 0..n_elements {
1401 if pos + 4 > data.len() {
1402 return Err(DriverError::Protocol("array: truncated element".into()));
1403 }
1404 let elem_len = i32::from_be_bytes([data[pos], data[pos + 1], data[pos + 2], data[pos + 3]]);
1405 pos += 4;
1406 if elem_len < 0 {
1407 continue;
1409 }
1410 let elem_len = elem_len as usize;
1411 if pos + elem_len > data.len() {
1412 return Err(DriverError::Protocol(
1413 "array: truncated element data".into(),
1414 ));
1415 }
1416 elements.push(&data[pos..pos + elem_len]);
1417 pos += elem_len;
1418 }
1419 Ok(elements)
1420}
1421
1422pub fn decode_array_i32(data: &[u8]) -> Result<Vec<i32>, DriverError> {
1424 decode_array_elements(data)?
1425 .into_iter()
1426 .map(decode_i32)
1427 .collect()
1428}
1429
1430pub fn decode_array_i16(data: &[u8]) -> Result<Vec<i16>, DriverError> {
1432 decode_array_elements(data)?
1433 .into_iter()
1434 .map(decode_i16)
1435 .collect()
1436}
1437
1438pub fn decode_array_i64(data: &[u8]) -> Result<Vec<i64>, DriverError> {
1440 decode_array_elements(data)?
1441 .into_iter()
1442 .map(decode_i64)
1443 .collect()
1444}
1445
1446pub fn decode_array_f32(data: &[u8]) -> Result<Vec<f32>, DriverError> {
1448 decode_array_elements(data)?
1449 .into_iter()
1450 .map(decode_f32)
1451 .collect()
1452}
1453
1454pub fn decode_array_f64(data: &[u8]) -> Result<Vec<f64>, DriverError> {
1456 decode_array_elements(data)?
1457 .into_iter()
1458 .map(decode_f64)
1459 .collect()
1460}
1461
1462pub fn decode_array_bool(data: &[u8]) -> Result<Vec<bool>, DriverError> {
1464 decode_array_elements(data)?
1465 .into_iter()
1466 .map(decode_bool)
1467 .collect()
1468}
1469
1470pub fn decode_array_str(data: &[u8]) -> Result<Vec<String>, DriverError> {
1472 decode_array_elements(data)?
1473 .into_iter()
1474 .map(|d| decode_str(d).map(|s| s.to_owned()))
1475 .collect()
1476}
1477
1478pub fn decode_array_bytea(data: &[u8]) -> Result<Vec<Vec<u8>>, DriverError> {
1480 Ok(decode_array_elements(data)?
1481 .into_iter()
1482 .map(|d| d.to_vec())
1483 .collect())
1484}
1485
1486#[cfg(feature = "uuid")]
1490#[inline]
1491pub fn decode_uuid_type(data: &[u8]) -> Result<uuid::Uuid, DriverError> {
1492 let bytes = decode_uuid(data)?;
1493 Ok(uuid::Uuid::from_bytes(bytes))
1494}
1495
1496#[cfg(feature = "time")]
1498#[inline]
1499pub fn decode_timestamptz_time(data: &[u8]) -> Result<time::OffsetDateTime, DriverError> {
1500 let micros = decode_i64(data)?;
1501 let unix_micros = micros + 946_684_800i64 * 1_000_000;
1503 let secs = unix_micros.div_euclid(1_000_000);
1504 let nanos = (unix_micros.rem_euclid(1_000_000) * 1000) as i128;
1505 time::OffsetDateTime::from_unix_timestamp_nanos(secs as i128 * 1_000_000_000 + nanos)
1506 .map_err(|e| DriverError::Protocol(format!("timestamptz decode: {e}")))
1507}
1508
1509#[cfg(feature = "time")]
1511#[inline]
1512pub fn decode_date_time(data: &[u8]) -> Result<time::Date, DriverError> {
1513 let days = decode_i32(data)?;
1514 let julian_day = PG_EPOCH_JULIAN_DAY as i64 + days as i64;
1516 if julian_day < i32::MIN as i64 || julian_day > i32::MAX as i64 {
1517 return Err(DriverError::Protocol(format!(
1518 "date out of range: {days} days"
1519 )));
1520 }
1521 time::Date::from_julian_day(julian_day as i32)
1522 .map_err(|_| DriverError::Protocol(format!("date out of range: {days} days")))
1523}
1524
1525#[cfg(feature = "time")]
1527#[inline]
1528pub fn decode_time_time(data: &[u8]) -> Result<time::Time, DriverError> {
1529 let micros = decode_i64(data)?;
1530
1531 if !(0..86_400_000_000).contains(µs) {
1533 return Err(DriverError::Protocol(format!(
1534 "time out of range: {micros}us (must be 0..86_400_000_000)"
1535 )));
1536 }
1537 let total_secs = micros / 1_000_000;
1538 let h = (total_secs / 3600) as u8;
1539 let m = ((total_secs % 3600) / 60) as u8;
1540 let s = (total_secs % 60) as u8;
1541 let micro = (micros % 1_000_000) as u32;
1542 time::Time::from_hms_micro(h, m, s, micro)
1543 .map_err(|e| DriverError::Protocol(format!("time decode: {e}")))
1544}
1545
1546#[cfg(feature = "chrono")]
1548#[inline]
1549pub fn decode_timestamptz_chrono(
1550 data: &[u8],
1551) -> Result<chrono::DateTime<chrono::Utc>, DriverError> {
1552 let micros = decode_i64(data)?;
1553 let pg_epoch_unix_micros: i64 = 946_684_800 * 1_000_000;
1554 let unix_micros = micros + pg_epoch_unix_micros;
1555 let secs = unix_micros.div_euclid(1_000_000);
1556 let nsecs = (unix_micros.rem_euclid(1_000_000) * 1000) as u32;
1557 chrono::DateTime::from_timestamp(secs, nsecs)
1558 .ok_or_else(|| DriverError::Protocol(format!("timestamptz out of range: {micros}us")))
1559}
1560
1561#[cfg(feature = "chrono")]
1563#[inline]
1564pub fn decode_date_chrono(data: &[u8]) -> Result<chrono::NaiveDate, DriverError> {
1565 let days = decode_i32(data)?;
1566 const PG_EPOCH_CE_DAYS: i32 = 730_120;
1568 let ce_days = PG_EPOCH_CE_DAYS as i64 + days as i64;
1569 if ce_days < i32::MIN as i64 || ce_days > i32::MAX as i64 {
1570 return Err(DriverError::Protocol(format!(
1571 "date out of range: {days} days"
1572 )));
1573 }
1574 chrono::NaiveDate::from_num_days_from_ce_opt(ce_days as i32)
1575 .ok_or_else(|| DriverError::Protocol(format!("date out of range: {days} days")))
1576}
1577
1578#[cfg(feature = "chrono")]
1580#[inline]
1581pub fn decode_time_chrono(data: &[u8]) -> Result<chrono::NaiveTime, DriverError> {
1582 let micros = decode_i64(data)?;
1583
1584 if !(0..86_400_000_000).contains(µs) {
1586 return Err(DriverError::Protocol(format!(
1587 "time out of range: {micros}us (must be 0..86_400_000_000)"
1588 )));
1589 }
1590 let total_secs = (micros / 1_000_000) as u32;
1591 let micro = (micros % 1_000_000) as u32;
1592 chrono::NaiveTime::from_num_seconds_from_midnight_opt(total_secs, micro * 1000)
1593 .ok_or_else(|| DriverError::Protocol(format!("time out of range: {micros}us")))
1594}
1595
1596#[cfg(feature = "decimal")]
1603pub fn decode_numeric_decimal(data: &[u8]) -> Result<rust_decimal::Decimal, DriverError> {
1604 if data.len() < 8 {
1605 return Err(DriverError::Protocol(format!(
1606 "numeric: expected >= 8 bytes header, got {}",
1607 data.len()
1608 )));
1609 }
1610 let ndigits = i16::from_be_bytes([data[0], data[1]]) as usize;
1611 let weight = i16::from_be_bytes([data[2], data[3]]) as i32;
1612 let sign = i16::from_be_bytes([data[4], data[5]]);
1613 let _dscale = i16::from_be_bytes([data[6], data[7]]) as u32;
1614
1615 if data.len() != 8 + ndigits * 2 {
1616 return Err(DriverError::Protocol(format!(
1617 "numeric: expected {} bytes, got {}",
1618 8 + ndigits * 2,
1619 data.len()
1620 )));
1621 }
1622
1623 if ndigits == 0 {
1624 return Ok(rust_decimal::Decimal::ZERO);
1625 }
1626
1627 let mut digits: smallvec::SmallVec<[i64; 16]> = smallvec::SmallVec::with_capacity(ndigits);
1629 for i in 0..ndigits {
1630 let off = 8 + i * 2;
1631 digits.push(i16::from_be_bytes([data[off], data[off + 1]]) as i64);
1632 }
1633
1634 let mut mantissa: u128 = 0;
1637 for &d in &digits {
1638 mantissa = mantissa
1639 .checked_mul(10_000)
1640 .and_then(|m| m.checked_add(d as u128))
1641 .ok_or_else(|| DriverError::Protocol("numeric value too large for Decimal".into()))?;
1642 }
1643
1644 let exponent = 4 * (weight - ndigits as i32 + 1);
1648 let result = if exponent >= 0 {
1649 let factor = 10u128
1651 .checked_pow(exponent as u32)
1652 .ok_or_else(|| DriverError::Protocol("numeric exponent too large".into()))?;
1653 let m = mantissa
1654 .checked_mul(factor)
1655 .ok_or_else(|| DriverError::Protocol("numeric value too large for Decimal".into()))?;
1656 if m > u128::from(u64::MAX) {
1657 let s = m.to_string();
1659 s.parse::<rust_decimal::Decimal>()
1660 .map_err(|e| DriverError::Protocol(format!("numeric parse error: {e}")))?
1661 } else {
1662 rust_decimal::Decimal::from_i128_with_scale(m as i128, 0)
1663 }
1664 } else {
1665 let scale = (-exponent) as u32;
1667 if mantissa <= u128::from(u64::MAX) {
1669 rust_decimal::Decimal::from_i128_with_scale(mantissa as i128, scale)
1670 } else {
1671 let mut s = mantissa.to_string();
1673 if scale as usize >= s.len() {
1674 let zeros = scale as usize - s.len() + 1;
1675 s = format!("0.{}{s}", "0".repeat(zeros));
1676 } else {
1677 let dot_pos = s.len() - scale as usize;
1678 s.insert(dot_pos, '.');
1679 }
1680 s.parse::<rust_decimal::Decimal>()
1681 .map_err(|e| DriverError::Protocol(format!("numeric parse error: {e}")))?
1682 }
1683 };
1684
1685 if sign == 0x4000 {
1686 Ok(-result)
1687 } else {
1688 Ok(result)
1689 }
1690}
1691
1692#[cfg(test)]
1693#[allow(clippy::approx_constant)]
1694mod tests {
1695 use super::*;
1696
1697 #[test]
1700 fn bool_roundtrip() {
1701 let mut buf = Vec::new();
1702 true.encode_binary(&mut buf);
1703 assert!(decode_bool(&buf).unwrap());
1704
1705 buf.clear();
1706 false.encode_binary(&mut buf);
1707 assert!(!decode_bool(&buf).unwrap());
1708 }
1709
1710 #[test]
1711 fn i16_roundtrip() {
1712 let mut buf = Vec::new();
1713 12345i16.encode_binary(&mut buf);
1714 assert_eq!(decode_i16(&buf).unwrap(), 12345);
1715
1716 buf.clear();
1717 (-1i16).encode_binary(&mut buf);
1718 assert_eq!(decode_i16(&buf).unwrap(), -1);
1719
1720 buf.clear();
1721 i16::MIN.encode_binary(&mut buf);
1722 assert_eq!(decode_i16(&buf).unwrap(), i16::MIN);
1723
1724 buf.clear();
1725 i16::MAX.encode_binary(&mut buf);
1726 assert_eq!(decode_i16(&buf).unwrap(), i16::MAX);
1727 }
1728
1729 #[test]
1730 fn i32_roundtrip() {
1731 let mut buf = Vec::new();
1732 42i32.encode_binary(&mut buf);
1733 assert_eq!(buf, &[0, 0, 0, 42]);
1734 assert_eq!(decode_i32(&buf).unwrap(), 42);
1735
1736 buf.clear();
1737 i32::MAX.encode_binary(&mut buf);
1738 assert_eq!(decode_i32(&buf).unwrap(), i32::MAX);
1739
1740 buf.clear();
1741 i32::MIN.encode_binary(&mut buf);
1742 assert_eq!(decode_i32(&buf).unwrap(), i32::MIN);
1743 }
1744
1745 #[test]
1746 fn i64_roundtrip() {
1747 let mut buf = Vec::new();
1748 1234567890123i64.encode_binary(&mut buf);
1749 assert_eq!(decode_i64(&buf).unwrap(), 1234567890123);
1750 }
1751
1752 #[test]
1753 fn f32_roundtrip() {
1754 let mut buf = Vec::new();
1755 3.14f32.encode_binary(&mut buf);
1756 let decoded = decode_f32(&buf).unwrap();
1757 assert!((decoded - 3.14).abs() < f32::EPSILON);
1758 }
1759
1760 #[test]
1761 fn f64_roundtrip() {
1762 let mut buf = Vec::new();
1763 std::f64::consts::PI.encode_binary(&mut buf);
1764 let decoded = decode_f64(&buf).unwrap();
1765 assert!((decoded - std::f64::consts::PI).abs() < f64::EPSILON);
1766 }
1767
1768 #[test]
1769 fn str_roundtrip() {
1770 let mut buf = Vec::new();
1771 "hello world".encode_binary(&mut buf);
1772 assert_eq!(decode_str(&buf).unwrap(), "hello world");
1773 }
1774
1775 #[test]
1776 fn string_roundtrip() {
1777 let mut buf = Vec::new();
1778 let s = String::from("test string");
1779 s.encode_binary(&mut buf);
1780 assert_eq!(decode_str(&buf).unwrap(), "test string");
1781 }
1782
1783 #[test]
1784 fn bytes_roundtrip() {
1785 let mut buf = Vec::new();
1786 let data: &[u8] = &[0xDE, 0xAD, 0xBE, 0xEF];
1787 data.encode_binary(&mut buf);
1788 assert_eq!(decode_bytes(&buf), data);
1789 }
1790
1791 #[test]
1792 fn vec_u8_roundtrip() {
1793 let mut buf = Vec::new();
1794 let data = vec![1u8, 2, 3, 4, 5];
1795 data.encode_binary(&mut buf);
1796 assert_eq!(decode_bytes(&buf), &[1, 2, 3, 4, 5]);
1797 }
1798
1799 #[test]
1800 fn u32_encode() {
1801 let mut buf = Vec::new();
1802 42u32.encode_binary(&mut buf);
1803 assert_eq!(buf, &[0, 0, 0, 42]);
1804 }
1805
1806 #[test]
1807 fn uuid_roundtrip() {
1808 let uuid_bytes: [u8; 16] = [
1809 0x55, 0x0e, 0x84, 0x00, 0xe2, 0x9b, 0x41, 0xd4, 0xa7, 0x16, 0x44, 0x66, 0x55, 0x44,
1810 0x00, 0x00,
1811 ];
1812 let decoded = decode_uuid(&uuid_bytes).unwrap();
1813 assert_eq!(decoded, uuid_bytes);
1814 }
1815
1816 #[test]
1819 fn decode_bool_wrong_length() {
1820 assert!(decode_bool(&[]).is_err());
1821 assert!(decode_bool(&[0, 0]).is_err());
1822 }
1823
1824 #[test]
1825 fn decode_i32_wrong_length() {
1826 assert!(decode_i32(&[0, 0, 0]).is_err());
1827 assert!(decode_i32(&[0, 0, 0, 0, 0]).is_err());
1828 }
1829
1830 #[test]
1831 fn decode_i64_wrong_length() {
1832 assert!(decode_i64(&[0; 7]).is_err());
1833 assert!(decode_i64(&[0; 9]).is_err());
1834 }
1835
1836 #[test]
1837 fn decode_f32_wrong_length() {
1838 assert!(decode_f32(&[0; 3]).is_err());
1839 }
1840
1841 #[test]
1842 fn decode_f64_wrong_length() {
1843 assert!(decode_f64(&[0; 7]).is_err());
1844 }
1845
1846 #[test]
1847 fn decode_str_invalid_utf8() {
1848 assert!(decode_str(&[0xFF, 0xFE]).is_err());
1849 }
1850
1851 #[test]
1852 fn decode_uuid_wrong_length() {
1853 assert!(decode_uuid(&[0; 15]).is_err());
1854 assert!(decode_uuid(&[0; 17]).is_err());
1855 }
1856
1857 #[test]
1858 fn empty_str_decode() {
1859 assert_eq!(decode_str(&[]).unwrap(), "");
1860 }
1861
1862 #[test]
1863 fn empty_bytes_decode() {
1864 assert_eq!(decode_bytes(&[]).len(), 0);
1865 }
1866
1867 #[test]
1870 fn type_oids_correct() {
1871 assert_eq!(true.type_oid(), 16);
1872 assert_eq!(0i16.type_oid(), 21);
1873 assert_eq!(0i32.type_oid(), 23);
1874 assert_eq!(0i64.type_oid(), 20);
1875 assert_eq!(0f32.type_oid(), 700);
1876 assert_eq!(0f64.type_oid(), 701);
1877 assert_eq!("".type_oid(), 25);
1878 assert_eq!(String::new().type_oid(), 25);
1879 let b: &[u8] = &[];
1880 assert_eq!(b.type_oid(), 17);
1881 assert_eq!(Vec::<u8>::new().type_oid(), 17);
1882 assert_eq!(0u32.type_oid(), 26);
1883 }
1884
1885 #[test]
1888 fn encode_param_i32() {
1889 let mut buf = Vec::new();
1890 encode_param(&mut buf, &42i32);
1891 assert_eq!(buf.len(), 8);
1893 let len = i32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]);
1894 assert_eq!(len, 4);
1895 let val = i32::from_be_bytes([buf[4], buf[5], buf[6], buf[7]]);
1896 assert_eq!(val, 42);
1897 }
1898
1899 #[test]
1900 fn encode_param_str() {
1901 let mut buf = Vec::new();
1902 encode_param(&mut buf, &"hello");
1903 assert_eq!(buf.len(), 9);
1905 let len = i32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]);
1906 assert_eq!(len, 5);
1907 assert_eq!(&buf[4..], b"hello");
1908 }
1909
1910 #[test]
1911 fn option_none_is_null() {
1912 let val: Option<i32> = None;
1913 assert!(val.is_null());
1914 assert_eq!(val.type_oid(), 0);
1915 }
1916
1917 #[test]
1918 fn option_some_encodes() {
1919 let val: Option<i32> = Some(42);
1920 assert!(!val.is_null());
1921 assert_eq!(val.type_oid(), 23);
1922 let mut buf = Vec::new();
1923 val.encode_binary(&mut buf);
1924 assert_eq!(buf, &[0, 0, 0, 42]);
1925 }
1926
1927 #[test]
1928 fn option_none_encode_is_noop() {
1929 let val: Option<i32> = None;
1930 let mut buf = Vec::new();
1931 val.encode_binary(&mut buf);
1932 assert!(buf.is_empty(), "None encode should produce no bytes");
1933 }
1934
1935 #[test]
1939 fn decode_i16_wrong_length() {
1940 assert!(decode_i16(&[]).is_err());
1941 assert!(decode_i16(&[0]).is_err());
1942 assert!(decode_i16(&[0, 0, 0]).is_err());
1943 }
1944
1945 #[test]
1947 fn f32_nan_roundtrip() {
1948 let mut buf = Vec::new();
1949 f32::NAN.encode_binary(&mut buf);
1950 let decoded = decode_f32(&buf).unwrap();
1951 assert!(decoded.is_nan(), "NaN should survive roundtrip");
1952 }
1953
1954 #[test]
1956 fn f64_nan_roundtrip() {
1957 let mut buf = Vec::new();
1958 f64::NAN.encode_binary(&mut buf);
1959 let decoded = decode_f64(&buf).unwrap();
1960 assert!(decoded.is_nan(), "NaN should survive roundtrip");
1961 }
1962
1963 #[test]
1965 fn f32_infinity_roundtrip() {
1966 let mut buf = Vec::new();
1967 f32::INFINITY.encode_binary(&mut buf);
1968 assert_eq!(decode_f32(&buf).unwrap(), f32::INFINITY);
1969
1970 buf.clear();
1971 f32::NEG_INFINITY.encode_binary(&mut buf);
1972 assert_eq!(decode_f32(&buf).unwrap(), f32::NEG_INFINITY);
1973 }
1974
1975 #[test]
1977 fn f64_infinity_roundtrip() {
1978 let mut buf = Vec::new();
1979 f64::INFINITY.encode_binary(&mut buf);
1980 assert_eq!(decode_f64(&buf).unwrap(), f64::INFINITY);
1981
1982 buf.clear();
1983 f64::NEG_INFINITY.encode_binary(&mut buf);
1984 assert_eq!(decode_f64(&buf).unwrap(), f64::NEG_INFINITY);
1985 }
1986
1987 #[test]
1989 fn f32_signed_zero_roundtrip() {
1990 let mut buf = Vec::new();
1991 0.0f32.encode_binary(&mut buf);
1992 let decoded = decode_f32(&buf).unwrap();
1993 assert_eq!(decoded.to_bits(), 0.0f32.to_bits(), "+0.0 bits must match");
1994
1995 buf.clear();
1996 (-0.0f32).encode_binary(&mut buf);
1997 let decoded = decode_f32(&buf).unwrap();
1998 assert_eq!(
1999 decoded.to_bits(),
2000 (-0.0f32).to_bits(),
2001 "-0.0 bits must match"
2002 );
2003 }
2004
2005 #[test]
2007 fn f64_signed_zero_roundtrip() {
2008 let mut buf = Vec::new();
2009 0.0f64.encode_binary(&mut buf);
2010 let decoded = decode_f64(&buf).unwrap();
2011 assert_eq!(decoded.to_bits(), 0.0f64.to_bits(), "+0.0 bits must match");
2012
2013 buf.clear();
2014 (-0.0f64).encode_binary(&mut buf);
2015 let decoded = decode_f64(&buf).unwrap();
2016 assert_eq!(
2017 decoded.to_bits(),
2018 (-0.0f64).to_bits(),
2019 "-0.0 bits must match"
2020 );
2021 }
2022
2023 #[test]
2025 fn i64_boundary_roundtrip() {
2026 let mut buf = Vec::new();
2027 i64::MIN.encode_binary(&mut buf);
2028 assert_eq!(decode_i64(&buf).unwrap(), i64::MIN);
2029
2030 buf.clear();
2031 i64::MAX.encode_binary(&mut buf);
2032 assert_eq!(decode_i64(&buf).unwrap(), i64::MAX);
2033 }
2034
2035 #[test]
2037 fn i16_boundary_standalone() {
2038 let mut buf = Vec::new();
2039 i16::MIN.encode_binary(&mut buf);
2040 assert_eq!(decode_i16(&buf).unwrap(), i16::MIN);
2041
2042 buf.clear();
2043 i16::MAX.encode_binary(&mut buf);
2044 assert_eq!(decode_i16(&buf).unwrap(), i16::MAX);
2045 }
2046
2047 #[cfg(feature = "chrono")]
2049 #[test]
2050 fn decode_date_chrono_negative_days() {
2051 let data = (-365i32).to_be_bytes();
2053 let date = decode_date_chrono(&data).unwrap();
2054 assert_eq!(date, chrono::NaiveDate::from_ymd_opt(1999, 1, 1).unwrap());
2055 }
2056
2057 #[cfg(feature = "chrono")]
2059 #[test]
2060 fn decode_date_chrono_day_zero() {
2061 let data = 0i32.to_be_bytes();
2062 let date = decode_date_chrono(&data).unwrap();
2063 assert_eq!(date, chrono::NaiveDate::from_ymd_opt(2000, 1, 1).unwrap());
2064 }
2065
2066 #[cfg(feature = "time")]
2068 #[test]
2069 fn decode_date_time_negative_days() {
2070 let data = (-1i32).to_be_bytes();
2071 let date = decode_date_time(&data).unwrap();
2072 let expected = time::Date::from_calendar_date(1999, time::Month::December, 31).unwrap();
2073 assert_eq!(date, expected);
2074 }
2075
2076 #[cfg(feature = "time")]
2078 #[test]
2079 fn decode_time_time_midnight() {
2080 let data = 0i64.to_be_bytes();
2081 let t = decode_time_time(&data).unwrap();
2082 assert_eq!(t, time::Time::MIDNIGHT);
2083 }
2084
2085 #[cfg(feature = "time")]
2087 #[test]
2088 fn decode_time_time_max_value() {
2089 let micros: i64 = 86_400_000_000 - 1; let data = micros.to_be_bytes();
2091 let t = decode_time_time(&data).unwrap();
2092 assert_eq!(t.hour(), 23);
2093 assert_eq!(t.minute(), 59);
2094 assert_eq!(t.second(), 59);
2095 assert_eq!(t.microsecond(), 999999);
2096 }
2097
2098 #[cfg(feature = "time")]
2100 #[test]
2101 fn decode_time_time_negative_micros_error() {
2102 let data = (-1i64).to_be_bytes();
2103 let result = decode_time_time(&data);
2104 assert!(result.is_err(), "negative microseconds should error");
2105 }
2106
2107 #[cfg(feature = "time")]
2109 #[test]
2110 fn decode_time_time_overflow_error() {
2111 let data = 86_400_000_000i64.to_be_bytes();
2112 let result = decode_time_time(&data);
2113 assert!(result.is_err(), ">= 24h microseconds should error");
2114 }
2115
2116 #[cfg(feature = "time")]
2118 #[test]
2119 fn decode_timestamptz_time_pg_epoch() {
2120 let data = 0i64.to_be_bytes();
2121 let dt = decode_timestamptz_time(&data).unwrap();
2122 assert_eq!(dt.year(), 2000);
2124 assert_eq!(dt.month(), time::Month::January);
2125 assert_eq!(dt.day(), 1);
2126 assert_eq!(dt.hour(), 0);
2127 assert_eq!(dt.minute(), 0);
2128 assert_eq!(dt.second(), 0);
2129 }
2130
2131 #[cfg(feature = "decimal")]
2133 #[test]
2134 fn decode_numeric_decimal_zero() {
2135 let mut data = Vec::new();
2137 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();
2142 assert!(dec.is_zero());
2143 }
2144
2145 #[cfg(feature = "decimal")]
2147 #[test]
2148 fn decode_numeric_decimal_negative() {
2149 let mut data = Vec::new();
2151 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();
2157 assert_eq!(dec, rust_decimal::Decimal::new(-42, 0));
2158 }
2159
2160 #[cfg(feature = "decimal")]
2162 #[test]
2163 fn decode_numeric_decimal_pure_fractional() {
2164 let mut data = Vec::new();
2169 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();
2175 let dec_normalized = dec.normalize();
2177 assert_eq!(dec_normalized.to_string(), "0.001");
2178 }
2179
2180 #[cfg(feature = "decimal")]
2185 fn decimal_encode_roundtrip(s: &str) {
2186 use rust_decimal::Decimal;
2187 use std::str::FromStr;
2188 let original = Decimal::from_str(s).unwrap();
2189 let mut buf = Vec::new();
2190 original.encode_binary(&mut buf);
2191 let decoded = decode_numeric_decimal(&buf).unwrap();
2192 assert_eq!(
2193 decoded.normalize().to_string(),
2194 original.normalize().to_string(),
2195 "round-trip failed for {s}: encoded {} bytes",
2196 buf.len()
2197 );
2198 }
2199
2200 #[cfg(feature = "decimal")]
2201 #[test]
2202 fn decimal_roundtrip_zero() {
2203 decimal_encode_roundtrip("0");
2204 }
2205
2206 #[cfg(feature = "decimal")]
2207 #[test]
2208 fn decimal_roundtrip_one() {
2209 decimal_encode_roundtrip("1");
2210 }
2211
2212 #[cfg(feature = "decimal")]
2213 #[test]
2214 fn decimal_roundtrip_negative() {
2215 decimal_encode_roundtrip("-42.5");
2216 }
2217
2218 #[cfg(feature = "decimal")]
2219 #[test]
2220 fn decimal_roundtrip_large_integer() {
2221 decimal_encode_roundtrip("123456789");
2222 }
2223
2224 #[cfg(feature = "decimal")]
2225 #[test]
2226 fn decimal_roundtrip_pure_fractional_0001() {
2227 decimal_encode_roundtrip("0.001");
2228 }
2229
2230 #[cfg(feature = "decimal")]
2231 #[test]
2232 fn decimal_roundtrip_pure_fractional_00001() {
2233 decimal_encode_roundtrip("0.0001");
2234 }
2235
2236 #[cfg(feature = "decimal")]
2237 #[test]
2238 fn decimal_roundtrip_pure_fractional_000001() {
2239 decimal_encode_roundtrip("0.00001");
2240 }
2241
2242 #[cfg(feature = "decimal")]
2243 #[test]
2244 fn decimal_roundtrip_mixed() {
2245 decimal_encode_roundtrip("12345.6789");
2246 }
2247
2248 #[cfg(feature = "decimal")]
2249 #[test]
2250 fn decimal_roundtrip_trailing_zeros() {
2251 decimal_encode_roundtrip("100.00");
2252 }
2253
2254 #[cfg(feature = "decimal")]
2255 #[test]
2256 fn decimal_roundtrip_small_negative_fraction() {
2257 decimal_encode_roundtrip("-0.007");
2258 }
2259
2260 #[cfg(feature = "decimal")]
2261 #[test]
2262 fn decimal_roundtrip_high_scale() {
2263 decimal_encode_roundtrip("0.0000000000000000000000000001");
2265 }
2266
2267 #[cfg(feature = "decimal")]
2268 #[test]
2269 fn decimal_roundtrip_large_with_fraction() {
2270 decimal_encode_roundtrip("999999999999999999.999999999999");
2271 }
2272
2273 #[test]
2275 fn decode_array_empty() {
2276 let mut data = Vec::new();
2278 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();
2282 assert!(elems.is_empty());
2283 }
2284
2285 #[test]
2287 fn decode_array_multidim_error() {
2288 let mut data = Vec::new();
2289 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());
2294 data.extend_from_slice(&0i32.to_be_bytes());
2295 data.extend_from_slice(&0i32.to_be_bytes());
2296 data.extend_from_slice(&0i32.to_be_bytes());
2297 let result = decode_array_i32(&data);
2298 assert!(result.is_err(), "multi-dimensional should error");
2299 }
2300
2301 #[test]
2303 fn decode_array_truncated_error() {
2304 let mut data = Vec::new();
2306 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);
2313 assert!(result.is_err(), "truncated array should error");
2314 }
2315
2316 #[test]
2318 fn option_some_i32_produces_data() {
2319 let val: Option<i32> = Some(42);
2320 assert!(!val.is_null());
2321 let mut buf = Vec::new();
2322 val.encode_binary(&mut buf);
2323 assert_eq!(decode_i32(&buf).unwrap(), 42);
2324 }
2325
2326 #[test]
2328 fn option_none_i32_is_null() {
2329 let val: Option<i32> = None;
2330 assert!(val.is_null());
2331 let mut buf = Vec::new();
2332 val.encode_binary(&mut buf);
2333 assert!(buf.is_empty());
2334 }
2335
2336 #[test]
2338 fn empty_string_encode_decode() {
2339 let mut buf = Vec::new();
2340 "".encode_binary(&mut buf);
2341 assert!(buf.is_empty());
2342 assert_eq!(decode_str(&buf).unwrap(), "");
2343
2344 buf.clear();
2345 String::new().encode_binary(&mut buf);
2346 assert!(buf.is_empty());
2347 assert_eq!(decode_str(&buf).unwrap(), "");
2348 }
2349
2350 #[test]
2352 fn empty_bytes_encode_decode() {
2353 let mut buf = Vec::new();
2354 let empty: &[u8] = &[];
2355 empty.encode_binary(&mut buf);
2356 assert!(buf.is_empty());
2357 assert_eq!(decode_bytes(&buf).len(), 0);
2358
2359 buf.clear();
2360 Vec::<u8>::new().encode_binary(&mut buf);
2361 assert!(buf.is_empty());
2362 }
2363
2364 #[test]
2366 fn large_string_encode_decode() {
2367 let big = "x".repeat(1_000_000);
2368 let mut buf = Vec::new();
2369 big.as_str().encode_binary(&mut buf);
2370 assert_eq!(buf.len(), 1_000_000);
2371 assert_eq!(decode_str(&buf).unwrap(), big);
2372 }
2373
2374 #[test]
2376 fn uuid_nil() {
2377 let nil = [0u8; 16];
2378 let decoded = decode_uuid(&nil).unwrap();
2379 assert_eq!(decoded, [0u8; 16]);
2380 }
2381
2382 #[test]
2384 fn uuid_max() {
2385 let max = [0xFF; 16];
2386 let decoded = decode_uuid(&max).unwrap();
2387 assert_eq!(decoded, [0xFF; 16]);
2388 }
2389
2390 #[cfg(feature = "uuid")]
2392 #[test]
2393 fn uuid_type_nil_and_max() {
2394 let nil = [0u8; 16];
2395 let uuid = decode_uuid_type(&nil).unwrap();
2396 assert_eq!(uuid, uuid::Uuid::nil());
2397
2398 let max = [0xFF; 16];
2399 let uuid = decode_uuid_type(&max).unwrap();
2400 assert_eq!(uuid, uuid::Uuid::max());
2401 }
2402
2403 #[test]
2407 fn encode_array_bool_empty() {
2408 let arr: &[bool] = &[];
2409 let mut buf = Vec::new();
2410 arr.encode_binary(&mut buf);
2411 let decoded = decode_array_bool(&buf).unwrap();
2412 assert!(decoded.is_empty());
2413 }
2414
2415 #[test]
2416 fn encode_array_bool_single() {
2417 let arr: &[bool] = &[true];
2418 let mut buf = Vec::new();
2419 arr.encode_binary(&mut buf);
2420 let decoded = decode_array_bool(&buf).unwrap();
2421 assert_eq!(decoded, vec![true]);
2422 }
2423
2424 #[test]
2425 fn encode_array_bool_multi() {
2426 let arr: &[bool] = &[true, false, true, false];
2427 let mut buf = Vec::new();
2428 arr.encode_binary(&mut buf);
2429 let decoded = decode_array_bool(&buf).unwrap();
2430 assert_eq!(decoded, vec![true, false, true, false]);
2431 }
2432
2433 #[test]
2434 fn encode_array_bool_vec_delegate() {
2435 let v = vec![false, true];
2436 let mut buf = Vec::new();
2437 v.encode_binary(&mut buf);
2438 let decoded = decode_array_bool(&buf).unwrap();
2439 assert_eq!(decoded, vec![false, true]);
2440 assert_eq!(v.type_oid(), 1000);
2441 }
2442
2443 #[test]
2445 fn encode_array_i16_empty() {
2446 let arr: &[i16] = &[];
2447 let mut buf = Vec::new();
2448 arr.encode_binary(&mut buf);
2449 let decoded = decode_array_i16(&buf).unwrap();
2450 assert!(decoded.is_empty());
2451 }
2452
2453 #[test]
2454 fn encode_array_i16_single() {
2455 let arr: &[i16] = &[42];
2456 let mut buf = Vec::new();
2457 arr.encode_binary(&mut buf);
2458 let decoded = decode_array_i16(&buf).unwrap();
2459 assert_eq!(decoded, vec![42i16]);
2460 }
2461
2462 #[test]
2463 fn encode_array_i16_multi_boundary() {
2464 let arr: &[i16] = &[i16::MIN, -1, 0, 1, i16::MAX];
2465 let mut buf = Vec::new();
2466 arr.encode_binary(&mut buf);
2467 let decoded = decode_array_i16(&buf).unwrap();
2468 assert_eq!(decoded, vec![i16::MIN, -1, 0, 1, i16::MAX]);
2469 }
2470
2471 #[test]
2472 fn encode_array_i16_vec_delegate() {
2473 let v = vec![100i16, 200];
2474 let mut buf = Vec::new();
2475 v.encode_binary(&mut buf);
2476 let decoded = decode_array_i16(&buf).unwrap();
2477 assert_eq!(decoded, vec![100i16, 200]);
2478 assert_eq!(v.type_oid(), 1005);
2479 }
2480
2481 #[test]
2483 fn encode_array_i32_empty() {
2484 let arr: &[i32] = &[];
2485 let mut buf = Vec::new();
2486 arr.encode_binary(&mut buf);
2487 let decoded = decode_array_i32(&buf).unwrap();
2488 assert!(decoded.is_empty());
2489 }
2490
2491 #[test]
2492 fn encode_array_i32_single() {
2493 let arr: &[i32] = &[42];
2494 let mut buf = Vec::new();
2495 arr.encode_binary(&mut buf);
2496 let decoded = decode_array_i32(&buf).unwrap();
2497 assert_eq!(decoded, vec![42]);
2498 }
2499
2500 #[test]
2501 fn encode_array_i32_multi_boundary() {
2502 let arr: &[i32] = &[i32::MIN, -1, 0, 1, i32::MAX];
2503 let mut buf = Vec::new();
2504 arr.encode_binary(&mut buf);
2505 let decoded = decode_array_i32(&buf).unwrap();
2506 assert_eq!(decoded, vec![i32::MIN, -1, 0, 1, i32::MAX]);
2507 }
2508
2509 #[test]
2510 fn encode_array_i32_vec_delegate() {
2511 let v = vec![10, 20, 30];
2512 let mut buf = Vec::new();
2513 v.encode_binary(&mut buf);
2514 let decoded = decode_array_i32(&buf).unwrap();
2515 assert_eq!(decoded, vec![10, 20, 30]);
2516 assert_eq!(v.type_oid(), 1007);
2517 }
2518
2519 #[test]
2521 fn encode_array_i64_empty() {
2522 let arr: &[i64] = &[];
2523 let mut buf = Vec::new();
2524 arr.encode_binary(&mut buf);
2525 let decoded = decode_array_i64(&buf).unwrap();
2526 assert!(decoded.is_empty());
2527 }
2528
2529 #[test]
2530 fn encode_array_i64_single() {
2531 let arr: &[i64] = &[9999999999i64];
2532 let mut buf = Vec::new();
2533 arr.encode_binary(&mut buf);
2534 let decoded = decode_array_i64(&buf).unwrap();
2535 assert_eq!(decoded, vec![9999999999i64]);
2536 }
2537
2538 #[test]
2539 fn encode_array_i64_multi_boundary() {
2540 let arr: &[i64] = &[i64::MIN, -1, 0, 1, i64::MAX];
2541 let mut buf = Vec::new();
2542 arr.encode_binary(&mut buf);
2543 let decoded = decode_array_i64(&buf).unwrap();
2544 assert_eq!(decoded, vec![i64::MIN, -1, 0, 1, i64::MAX]);
2545 }
2546
2547 #[test]
2548 fn encode_array_i64_vec_delegate() {
2549 let v = vec![1i64, 2, 3];
2550 let mut buf = Vec::new();
2551 v.encode_binary(&mut buf);
2552 let decoded = decode_array_i64(&buf).unwrap();
2553 assert_eq!(decoded, vec![1i64, 2, 3]);
2554 assert_eq!(v.type_oid(), 1016);
2555 }
2556
2557 #[test]
2559 fn encode_array_f32_empty() {
2560 let arr: &[f32] = &[];
2561 let mut buf = Vec::new();
2562 arr.encode_binary(&mut buf);
2563 let decoded = decode_array_f32(&buf).unwrap();
2564 assert!(decoded.is_empty());
2565 }
2566
2567 #[test]
2568 fn encode_array_f32_single() {
2569 let arr: &[f32] = &[3.14];
2570 let mut buf = Vec::new();
2571 arr.encode_binary(&mut buf);
2572 let decoded = decode_array_f32(&buf).unwrap();
2573 assert!((decoded[0] - 3.14).abs() < f32::EPSILON);
2574 }
2575
2576 #[test]
2577 fn encode_array_f32_multi_boundary() {
2578 let arr: &[f32] = &[
2579 f32::MIN,
2580 -0.0,
2581 0.0,
2582 f32::MAX,
2583 f32::INFINITY,
2584 f32::NEG_INFINITY,
2585 ];
2586 let mut buf = Vec::new();
2587 arr.encode_binary(&mut buf);
2588 let decoded = decode_array_f32(&buf).unwrap();
2589 assert_eq!(decoded[0], f32::MIN);
2590 assert_eq!(decoded[1].to_bits(), (-0.0f32).to_bits());
2591 assert_eq!(decoded[2].to_bits(), 0.0f32.to_bits());
2592 assert_eq!(decoded[3], f32::MAX);
2593 assert_eq!(decoded[4], f32::INFINITY);
2594 assert_eq!(decoded[5], f32::NEG_INFINITY);
2595 }
2596
2597 #[test]
2598 fn encode_array_f32_vec_delegate() {
2599 let v = vec![1.0f32, 2.0];
2600 let mut buf = Vec::new();
2601 v.encode_binary(&mut buf);
2602 let decoded = decode_array_f32(&buf).unwrap();
2603 assert_eq!(decoded, vec![1.0f32, 2.0]);
2604 assert_eq!(v.type_oid(), 1021);
2605 }
2606
2607 #[test]
2609 fn encode_array_f64_empty() {
2610 let arr: &[f64] = &[];
2611 let mut buf = Vec::new();
2612 arr.encode_binary(&mut buf);
2613 let decoded = decode_array_f64(&buf).unwrap();
2614 assert!(decoded.is_empty());
2615 }
2616
2617 #[test]
2618 fn encode_array_f64_single() {
2619 let arr: &[f64] = &[std::f64::consts::PI];
2620 let mut buf = Vec::new();
2621 arr.encode_binary(&mut buf);
2622 let decoded = decode_array_f64(&buf).unwrap();
2623 assert!((decoded[0] - std::f64::consts::PI).abs() < f64::EPSILON);
2624 }
2625
2626 #[test]
2627 fn encode_array_f64_multi_boundary() {
2628 let arr: &[f64] = &[
2629 f64::MIN,
2630 -0.0,
2631 0.0,
2632 f64::MAX,
2633 f64::INFINITY,
2634 f64::NEG_INFINITY,
2635 ];
2636 let mut buf = Vec::new();
2637 arr.encode_binary(&mut buf);
2638 let decoded = decode_array_f64(&buf).unwrap();
2639 assert_eq!(decoded[0], f64::MIN);
2640 assert_eq!(decoded[1].to_bits(), (-0.0f64).to_bits());
2641 assert_eq!(decoded[2].to_bits(), 0.0f64.to_bits());
2642 assert_eq!(decoded[3], f64::MAX);
2643 assert_eq!(decoded[4], f64::INFINITY);
2644 assert_eq!(decoded[5], f64::NEG_INFINITY);
2645 }
2646
2647 #[test]
2648 fn encode_array_f64_vec_delegate() {
2649 let v = vec![1.0f64, 2.0];
2650 let mut buf = Vec::new();
2651 v.encode_binary(&mut buf);
2652 let decoded = decode_array_f64(&buf).unwrap();
2653 assert_eq!(decoded, vec![1.0f64, 2.0]);
2654 assert_eq!(v.type_oid(), 1022);
2655 }
2656
2657 #[test]
2659 fn encode_array_str_empty() {
2660 let arr: &[&str] = &[];
2661 let mut buf = Vec::new();
2662 arr.encode_binary(&mut buf);
2663 let decoded = decode_array_str(&buf).unwrap();
2664 assert!(decoded.is_empty());
2665 }
2666
2667 #[test]
2668 fn encode_array_str_single() {
2669 let arr: &[&str] = &["hello"];
2670 let mut buf = Vec::new();
2671 arr.encode_binary(&mut buf);
2672 let decoded = decode_array_str(&buf).unwrap();
2673 assert_eq!(decoded, vec!["hello".to_string()]);
2674 }
2675
2676 #[test]
2677 fn encode_array_str_multi() {
2678 let arr: &[&str] = &["hello", "", "world"];
2679 let mut buf = Vec::new();
2680 arr.encode_binary(&mut buf);
2681 let decoded = decode_array_str(&buf).unwrap();
2682 assert_eq!(
2683 decoded,
2684 vec!["hello".to_string(), "".to_string(), "world".to_string()]
2685 );
2686 }
2687
2688 #[test]
2689 fn encode_array_str_boundary_unicode() {
2690 let arr: &[&str] = &["\u{1F600}", "\u{00E9}"];
2691 let mut buf = Vec::new();
2692 arr.encode_binary(&mut buf);
2693 let decoded = decode_array_str(&buf).unwrap();
2694 assert_eq!(
2695 decoded,
2696 vec!["\u{1F600}".to_string(), "\u{00E9}".to_string()]
2697 );
2698 }
2699
2700 #[test]
2701 fn encode_array_vec_string() {
2702 let v = vec!["foo".to_string(), "bar".to_string()];
2703 let mut buf = Vec::new();
2704 v.encode_binary(&mut buf);
2705 let decoded = decode_array_str(&buf).unwrap();
2706 assert_eq!(decoded, vec!["foo".to_string(), "bar".to_string()]);
2707 assert_eq!(v.type_oid(), 1009);
2708 }
2709
2710 #[test]
2711 fn encode_array_slice_string() {
2712 let v = vec!["foo".to_string(), "bar".to_string()];
2713 let slice: &[String] = &v;
2714 let mut buf = Vec::new();
2715 slice.encode_binary(&mut buf);
2716 let decoded = decode_array_str(&buf).unwrap();
2717 assert_eq!(decoded, vec!["foo".to_string(), "bar".to_string()]);
2718 assert_eq!(slice.type_oid(), 1009);
2719 }
2720
2721 #[test]
2722 fn encode_array_slice_string_empty() {
2723 let v: Vec<String> = vec![];
2724 let slice: &[String] = &v;
2725 let mut buf = Vec::new();
2726 slice.encode_binary(&mut buf);
2727 let decoded = decode_array_str(&buf).unwrap();
2728 assert!(decoded.is_empty());
2729 }
2730
2731 #[test]
2732 fn encode_array_ref_slice_string() {
2733 let v = ["alpha".to_string(), "beta".to_string()];
2734 let r: &&[String] = &&v[..];
2735 let mut buf = Vec::new();
2736 r.encode_binary(&mut buf);
2737 let decoded = decode_array_str(&buf).unwrap();
2738 assert_eq!(decoded, vec!["alpha".to_string(), "beta".to_string()]);
2739 assert_eq!(r.type_oid(), 1009);
2740 }
2741
2742 #[test]
2743 fn encode_array_vec_string_empty() {
2744 let v: Vec<String> = vec![];
2745 let mut buf = Vec::new();
2746 v.encode_binary(&mut buf);
2747 let decoded = decode_array_str(&buf).unwrap();
2748 assert!(decoded.is_empty());
2749 }
2750
2751 #[test]
2753 fn encode_array_bytea_empty() {
2754 let arr: &[&[u8]] = &[];
2755 let mut buf = Vec::new();
2756 arr.encode_binary(&mut buf);
2757 let decoded = decode_array_bytea(&buf).unwrap();
2758 assert!(decoded.is_empty());
2759 }
2760
2761 #[test]
2762 fn encode_array_bytea_single() {
2763 let data: &[u8] = &[0xDE, 0xAD];
2764 let arr: &[&[u8]] = &[data];
2765 let mut buf = Vec::new();
2766 arr.encode_binary(&mut buf);
2767 let decoded = decode_array_bytea(&buf).unwrap();
2768 assert_eq!(decoded, vec![vec![0xDE, 0xAD]]);
2769 }
2770
2771 #[test]
2772 fn encode_array_bytea_multi() {
2773 let a: &[u8] = &[1, 2, 3];
2774 let b: &[u8] = &[];
2775 let c: &[u8] = &[0xFF];
2776 let arr: &[&[u8]] = &[a, b, c];
2777 let mut buf = Vec::new();
2778 arr.encode_binary(&mut buf);
2779 let decoded = decode_array_bytea(&buf).unwrap();
2780 assert_eq!(decoded, vec![vec![1, 2, 3], vec![], vec![0xFF]]);
2781 }
2782
2783 #[test]
2784 fn encode_array_vec_vec_u8() {
2785 let v = vec![vec![10u8, 20], vec![30]];
2786 let mut buf = Vec::new();
2787 v.encode_binary(&mut buf);
2788 let decoded = decode_array_bytea(&buf).unwrap();
2789 assert_eq!(decoded, vec![vec![10u8, 20], vec![30]]);
2790 assert_eq!(v.type_oid(), 1001);
2791 }
2792
2793 #[test]
2794 fn encode_array_vec_vec_u8_empty() {
2795 let v: Vec<Vec<u8>> = vec![];
2796 let mut buf = Vec::new();
2797 v.encode_binary(&mut buf);
2798 let decoded = decode_array_bytea(&buf).unwrap();
2799 assert!(decoded.is_empty());
2800 }
2801
2802 #[test]
2804 fn array_type_oids_correct() {
2805 let b: &[bool] = &[];
2806 assert_eq!(b.type_oid(), 1000);
2807 let i2: &[i16] = &[];
2808 assert_eq!(i2.type_oid(), 1005);
2809 let i4: &[i32] = &[];
2810 assert_eq!(i4.type_oid(), 1007);
2811 let i8: &[i64] = &[];
2812 assert_eq!(i8.type_oid(), 1016);
2813 let f4: &[f32] = &[];
2814 assert_eq!(f4.type_oid(), 1021);
2815 let f8: &[f64] = &[];
2816 assert_eq!(f8.type_oid(), 1022);
2817 let t: &[&str] = &[];
2818 assert_eq!(t.type_oid(), 1009);
2819 let by: &[&[u8]] = &[];
2820 assert_eq!(by.type_oid(), 1001);
2821
2822 assert_eq!(Vec::<bool>::new().type_oid(), 1000);
2823 assert_eq!(Vec::<i16>::new().type_oid(), 1005);
2824 assert_eq!(Vec::<i32>::new().type_oid(), 1007);
2825 assert_eq!(Vec::<i64>::new().type_oid(), 1016);
2826 assert_eq!(Vec::<f32>::new().type_oid(), 1021);
2827 assert_eq!(Vec::<f64>::new().type_oid(), 1022);
2828 assert_eq!(Vec::<String>::new().type_oid(), 1009);
2829 assert_eq!(Vec::<Vec<u8>>::new().type_oid(), 1001);
2830 }
2831
2832 #[test]
2834 fn encode_array_empty_ndim_zero() {
2835 let arr: &[i32] = &[];
2836 let mut buf = Vec::new();
2837 arr.encode_binary(&mut buf);
2838 assert_eq!(buf.len(), 12);
2840 let ndim = i32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]);
2841 assert_eq!(ndim, 0, "empty array must have ndim=0");
2842 let elem_oid = i32::from_be_bytes([buf[8], buf[9], buf[10], buf[11]]);
2843 assert_eq!(
2844 elem_oid, 23,
2845 "element OID must be preserved for empty arrays"
2846 );
2847 }
2848
2849 #[test]
2852 fn encode_at_bool() {
2853 let mut dst = [0u8; 1];
2854 assert!(true.encode_at(&mut dst));
2855 assert_eq!(dst[0], 1);
2856 assert!(false.encode_at(&mut dst));
2857 assert_eq!(dst[0], 0);
2858 assert!(!true.encode_at(&mut [0u8; 2]));
2860 }
2861
2862 #[test]
2863 fn encode_at_i16() {
2864 let mut dst = [0u8; 2];
2865 assert!(0x1234i16.encode_at(&mut dst));
2866 assert_eq!(dst, [0x12, 0x34]);
2867 assert!(!42i16.encode_at(&mut [0u8; 4]));
2868 }
2869
2870 #[test]
2871 fn encode_at_i32() {
2872 let mut dst = [0u8; 4];
2873 assert!(42i32.encode_at(&mut dst));
2874 assert_eq!(dst, [0, 0, 0, 42]);
2875 assert!(!42i32.encode_at(&mut [0u8; 8]));
2876 }
2877
2878 #[test]
2879 fn encode_at_i64() {
2880 let mut dst = [0u8; 8];
2881 assert!(1234567890123i64.encode_at(&mut dst));
2882 assert_eq!(dst, 1234567890123i64.to_be_bytes());
2883 assert!(!42i64.encode_at(&mut [0u8; 4]));
2884 }
2885
2886 #[test]
2887 fn encode_at_f32() {
2888 let mut dst = [0u8; 4];
2889 assert!(3.14f32.encode_at(&mut dst));
2890 assert_eq!(dst, 3.14f32.to_be_bytes());
2891 assert!(!3.14f32.encode_at(&mut [0u8; 8]));
2892 }
2893
2894 #[test]
2895 fn encode_at_f64() {
2896 let mut dst = [0u8; 8];
2897 assert!(3.14f64.encode_at(&mut dst));
2898 assert_eq!(dst, 3.14f64.to_be_bytes());
2899 assert!(!3.14f64.encode_at(&mut [0u8; 4]));
2900 }
2901
2902 #[test]
2903 fn encode_at_u32() {
2904 let mut dst = [0u8; 4];
2905 assert!(42u32.encode_at(&mut dst));
2906 assert_eq!(dst, 42u32.to_be_bytes());
2907 }
2908
2909 #[test]
2910 fn encode_at_str_default_fallback() {
2911 let s: &str = "hello";
2913 let mut dst = [0u8; 5];
2914 assert!(s.encode_at(&mut dst));
2915 assert_eq!(&dst, b"hello");
2916 assert!(!s.encode_at(&mut [0u8; 3]));
2918 }
2919
2920 #[test]
2921 fn encode_at_matches_encode_binary() {
2922 fn check<T: Encode>(val: T, expected_len: usize) {
2925 let mut buf = Vec::new();
2926 val.encode_binary(&mut buf);
2927 assert_eq!(buf.len(), expected_len);
2928 let mut dst = vec![0u8; expected_len];
2929 assert!(val.encode_at(&mut dst));
2930 assert_eq!(
2931 buf, dst,
2932 "encode_at must produce same bytes as encode_binary"
2933 );
2934 }
2935 check(true, 1);
2936 check(false, 1);
2937 check(42i16, 2);
2938 check(i16::MAX, 2);
2939 check(42i32, 4);
2940 check(i32::MIN, 4);
2941 check(42i64, 8);
2942 check(3.14f32, 4);
2943 check(3.14f64, 8);
2944 check(42u32, 4);
2945 }
2946
2947 #[test]
2950 fn str_10kb_roundtrip() {
2951 let big = "A".repeat(10 * 1024);
2952 let mut buf = Vec::new();
2953 big.as_str().encode_binary(&mut buf);
2954 assert_eq!(buf.len(), 10 * 1024);
2955 assert_eq!(decode_str(&buf).unwrap(), big);
2956 }
2957
2958 #[test]
2961 fn empty_vec_u8_encode_roundtrip() {
2962 let mut buf = Vec::new();
2963 Vec::<u8>::new().encode_binary(&mut buf);
2964 assert!(buf.is_empty(), "empty Vec<u8> should produce no bytes");
2965 assert_eq!(decode_bytes(&buf).len(), 0);
2966 }
2967
2968 #[test]
2971 fn f32_min_max_roundtrip() {
2972 let mut buf = Vec::new();
2973 f32::MIN.encode_binary(&mut buf);
2974 assert_eq!(decode_f32(&buf).unwrap(), f32::MIN);
2975
2976 buf.clear();
2977 f32::MAX.encode_binary(&mut buf);
2978 assert_eq!(decode_f32(&buf).unwrap(), f32::MAX);
2979 }
2980
2981 #[test]
2984 fn f64_min_max_roundtrip() {
2985 let mut buf = Vec::new();
2986 f64::MIN.encode_binary(&mut buf);
2987 assert_eq!(decode_f64(&buf).unwrap(), f64::MIN);
2988
2989 buf.clear();
2990 f64::MAX.encode_binary(&mut buf);
2991 assert_eq!(decode_f64(&buf).unwrap(), f64::MAX);
2992 }
2993
2994 #[test]
2997 fn i32_zero_roundtrip() {
2998 let mut buf = Vec::new();
2999 0i32.encode_binary(&mut buf);
3000 assert_eq!(decode_i32(&buf).unwrap(), 0);
3001 }
3002
3003 #[test]
3006 fn i64_zero_roundtrip() {
3007 let mut buf = Vec::new();
3008 0i64.encode_binary(&mut buf);
3009 assert_eq!(decode_i64(&buf).unwrap(), 0);
3010 }
3011
3012 #[test]
3015 fn i16_zero_roundtrip() {
3016 let mut buf = Vec::new();
3017 0i16.encode_binary(&mut buf);
3018 assert_eq!(decode_i16(&buf).unwrap(), 0);
3019 }
3020
3021 #[test]
3024 fn f32_subnormal_roundtrip() {
3025 let mut buf = Vec::new();
3026 f32::MIN_POSITIVE.encode_binary(&mut buf);
3027 assert_eq!(decode_f32(&buf).unwrap(), f32::MIN_POSITIVE);
3028 }
3029
3030 #[test]
3033 fn f64_subnormal_roundtrip() {
3034 let mut buf = Vec::new();
3035 f64::MIN_POSITIVE.encode_binary(&mut buf);
3036 assert_eq!(decode_f64(&buf).unwrap(), f64::MIN_POSITIVE);
3037 }
3038
3039 #[test]
3042 fn f32_nan_bit_preservation() {
3043 let mut buf = Vec::new();
3044 f32::NAN.encode_binary(&mut buf);
3045 let decoded = decode_f32(&buf).unwrap();
3046 assert!(decoded.is_nan());
3047 assert_eq!(decoded.to_bits(), f32::NAN.to_bits());
3049 }
3050
3051 #[test]
3054 fn f64_nan_bit_preservation() {
3055 let mut buf = Vec::new();
3056 f64::NAN.encode_binary(&mut buf);
3057 let decoded = decode_f64(&buf).unwrap();
3058 assert!(decoded.is_nan());
3059 assert_eq!(decoded.to_bits(), f64::NAN.to_bits());
3060 }
3061
3062 #[test]
3065 fn option_bool_some_roundtrip() {
3066 let val: Option<bool> = Some(true);
3067 assert!(!val.is_null());
3068 assert_eq!(val.type_oid(), 16);
3069 let mut buf = Vec::new();
3070 val.encode_binary(&mut buf);
3071 assert!(decode_bool(&buf).unwrap());
3072 }
3073
3074 #[test]
3075 fn option_bool_none_is_null() {
3076 let val: Option<bool> = None;
3077 assert!(val.is_null());
3078 assert_eq!(val.type_oid(), 0);
3079 let mut buf = Vec::new();
3080 val.encode_binary(&mut buf);
3081 assert!(buf.is_empty());
3082 }
3083
3084 #[test]
3085 fn option_i16_some_roundtrip() {
3086 let val: Option<i16> = Some(i16::MIN);
3087 assert!(!val.is_null());
3088 assert_eq!(val.type_oid(), 21);
3089 let mut buf = Vec::new();
3090 val.encode_binary(&mut buf);
3091 assert_eq!(decode_i16(&buf).unwrap(), i16::MIN);
3092 }
3093
3094 #[test]
3095 fn option_i16_none_is_null() {
3096 let val: Option<i16> = None;
3097 assert!(val.is_null());
3098 let mut buf = Vec::new();
3099 val.encode_binary(&mut buf);
3100 assert!(buf.is_empty());
3101 }
3102
3103 #[test]
3104 fn option_i64_some_roundtrip() {
3105 let val: Option<i64> = Some(i64::MAX);
3106 assert!(!val.is_null());
3107 assert_eq!(val.type_oid(), 20);
3108 let mut buf = Vec::new();
3109 val.encode_binary(&mut buf);
3110 assert_eq!(decode_i64(&buf).unwrap(), i64::MAX);
3111 }
3112
3113 #[test]
3114 fn option_i64_none_is_null() {
3115 let val: Option<i64> = None;
3116 assert!(val.is_null());
3117 let mut buf = Vec::new();
3118 val.encode_binary(&mut buf);
3119 assert!(buf.is_empty());
3120 }
3121
3122 #[test]
3123 fn option_f32_some_roundtrip() {
3124 let val: Option<f32> = Some(f32::INFINITY);
3125 assert!(!val.is_null());
3126 assert_eq!(val.type_oid(), 700);
3127 let mut buf = Vec::new();
3128 val.encode_binary(&mut buf);
3129 assert_eq!(decode_f32(&buf).unwrap(), f32::INFINITY);
3130 }
3131
3132 #[test]
3133 fn option_f32_none_is_null() {
3134 let val: Option<f32> = None;
3135 assert!(val.is_null());
3136 let mut buf = Vec::new();
3137 val.encode_binary(&mut buf);
3138 assert!(buf.is_empty());
3139 }
3140
3141 #[test]
3142 fn option_f64_some_nan_roundtrip() {
3143 let val: Option<f64> = Some(f64::NAN);
3144 assert!(!val.is_null());
3145 assert_eq!(val.type_oid(), 701);
3146 let mut buf = Vec::new();
3147 val.encode_binary(&mut buf);
3148 assert!(decode_f64(&buf).unwrap().is_nan());
3149 }
3150
3151 #[test]
3152 fn option_f64_none_is_null() {
3153 let val: Option<f64> = None;
3154 assert!(val.is_null());
3155 let mut buf = Vec::new();
3156 val.encode_binary(&mut buf);
3157 assert!(buf.is_empty());
3158 }
3159
3160 #[test]
3161 fn option_string_some_roundtrip() {
3162 let val: Option<String> = Some("hello".to_owned());
3163 assert!(!val.is_null());
3164 assert_eq!(val.type_oid(), 25);
3165 let mut buf = Vec::new();
3166 val.encode_binary(&mut buf);
3167 assert_eq!(decode_str(&buf).unwrap(), "hello");
3168 }
3169
3170 #[test]
3171 fn option_string_none_is_null() {
3172 let val: Option<String> = None;
3173 assert!(val.is_null());
3174 let mut buf = Vec::new();
3175 val.encode_binary(&mut buf);
3176 assert!(buf.is_empty());
3177 }
3178
3179 #[test]
3180 fn option_vec_u8_some_roundtrip() {
3181 let val: Option<Vec<u8>> = Some(vec![0xDE, 0xAD]);
3182 assert!(!val.is_null());
3183 assert_eq!(val.type_oid(), 17);
3184 let mut buf = Vec::new();
3185 val.encode_binary(&mut buf);
3186 assert_eq!(decode_bytes(&buf), &[0xDE, 0xAD]);
3187 }
3188
3189 #[test]
3190 fn option_vec_u8_none_is_null() {
3191 let val: Option<Vec<u8>> = None;
3192 assert!(val.is_null());
3193 let mut buf = Vec::new();
3194 val.encode_binary(&mut buf);
3195 assert!(buf.is_empty());
3196 }
3197
3198 #[test]
3201 fn encode_at_vec_u8_same_size() {
3202 let v = vec![1u8, 2, 3];
3203 let mut dst = [0u8; 3];
3204 assert!(v.encode_at(&mut dst));
3205 assert_eq!(dst, [1, 2, 3]);
3206 }
3207
3208 #[test]
3209 fn encode_at_vec_u8_wrong_size() {
3210 let v = vec![1u8, 2, 3];
3211 let mut dst = [0u8; 5];
3212 assert!(!v.encode_at(&mut dst));
3213 }
3214
3215 #[test]
3216 fn encode_at_byte_slice_same_size() {
3217 let data: &[u8] = &[0xAA, 0xBB];
3218 let mut dst = [0u8; 2];
3219 assert!(data.encode_at(&mut dst));
3220 assert_eq!(dst, [0xAA, 0xBB]);
3221 }
3222
3223 #[test]
3224 fn encode_at_byte_slice_wrong_size() {
3225 let data: &[u8] = &[0xAA, 0xBB];
3226 let mut dst = [0u8; 4];
3227 assert!(!data.encode_at(&mut dst));
3228 }
3229
3230 #[test]
3231 fn encode_at_string_same_size() {
3232 let s = String::from("hi");
3233 let mut dst = [0u8; 2];
3234 assert!(s.encode_at(&mut dst));
3235 assert_eq!(&dst, b"hi");
3236 }
3237
3238 #[test]
3239 fn encode_at_string_wrong_size() {
3240 let s = String::from("hi");
3241 let mut dst = [0u8; 5];
3242 assert!(!s.encode_at(&mut dst));
3243 }
3244
3245 #[test]
3248 fn encode_param_null_option() {
3249 let val: Option<i32> = None;
3253 let mut buf = Vec::new();
3254 encode_param(&mut buf, &val);
3255 assert_eq!(buf.len(), 4);
3258 let len = i32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]);
3259 assert_eq!(len, 0);
3260 }
3261
3262 #[test]
3265 fn decode_array_negative_element_count() {
3266 let mut data = Vec::new();
3267 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);
3273 assert!(result.is_err(), "negative element count should error");
3274 assert!(result.unwrap_err().to_string().contains("negative"));
3275 }
3276
3277 #[test]
3280 fn decode_array_excessive_element_count() {
3281 let mut data = Vec::new();
3282 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(&20_000_000i32.to_be_bytes()); data.extend_from_slice(&1i32.to_be_bytes()); let result = decode_array_i32(&data);
3288 assert!(result.is_err(), "excessive element count should error");
3289 assert!(result.unwrap_err().to_string().contains("exceeds limit"));
3290 }
3291
3292 #[test]
3295 fn decode_array_header_too_short() {
3296 let data = [0u8; 8]; let result = decode_array_i32(&data);
3298 assert!(result.is_err(), "header too short should error");
3299 }
3300
3301 #[test]
3304 fn decode_array_truncated_dimension_header() {
3305 let mut data = Vec::new();
3306 data.extend_from_slice(&1i32.to_be_bytes()); data.extend_from_slice(&0i32.to_be_bytes()); data.extend_from_slice(&23i32.to_be_bytes()); let result = decode_array_i32(&data);
3311 assert!(result.is_err(), "truncated dimension header should error");
3312 }
3313
3314 mod proptest_fuzz {
3315 use super::*;
3316 use proptest::prelude::*;
3317
3318 proptest! {
3319 #[test]
3320 fn i32_roundtrip(val: i32) {
3321 let mut buf = Vec::new();
3322 val.encode_binary(&mut buf);
3323 let decoded = decode_i32(&buf).unwrap();
3324 prop_assert_eq!(decoded, val);
3325 }
3326
3327 #[test]
3328 fn i64_roundtrip(val: i64) {
3329 let mut buf = Vec::new();
3330 val.encode_binary(&mut buf);
3331 let decoded = decode_i64(&buf).unwrap();
3332 prop_assert_eq!(decoded, val);
3333 }
3334
3335 #[test]
3336 fn i16_roundtrip(val: i16) {
3337 let mut buf = Vec::new();
3338 val.encode_binary(&mut buf);
3339 let decoded = decode_i16(&buf).unwrap();
3340 prop_assert_eq!(decoded, val);
3341 }
3342
3343 #[test]
3344 fn f32_roundtrip(val: f32) {
3345 let mut buf = Vec::new();
3346 val.encode_binary(&mut buf);
3347 let decoded = decode_f32(&buf).unwrap();
3348 if val.is_nan() {
3349 prop_assert!(decoded.is_nan());
3350 } else {
3351 prop_assert_eq!(decoded, val);
3352 }
3353 }
3354
3355 #[test]
3356 fn f64_roundtrip(val: f64) {
3357 let mut buf = Vec::new();
3358 val.encode_binary(&mut buf);
3359 let decoded = decode_f64(&buf).unwrap();
3360 if val.is_nan() {
3361 prop_assert!(decoded.is_nan());
3362 } else {
3363 prop_assert_eq!(decoded, val);
3364 }
3365 }
3366
3367 #[test]
3368 fn bool_roundtrip(val: bool) {
3369 let mut buf = Vec::new();
3370 val.encode_binary(&mut buf);
3371 let decoded = decode_bool(&buf).unwrap();
3372 prop_assert_eq!(decoded, val);
3373 }
3374
3375 #[test]
3376 fn str_roundtrip(val in "\\PC*") {
3377 let mut buf = Vec::new();
3378 val.as_str().encode_binary(&mut buf);
3379 let decoded = decode_str(&buf).unwrap();
3380 prop_assert_eq!(decoded, val.as_str());
3381 }
3382
3383 #[test]
3384 fn decode_i32_arbitrary_never_panics(data in proptest::collection::vec(any::<u8>(), 0..16)) {
3385 let _ = decode_i32(&data);
3386 }
3387
3388 #[test]
3389 fn decode_str_arbitrary_never_panics(data in proptest::collection::vec(any::<u8>(), 0..1024)) {
3390 let _ = decode_str(&data);
3391 }
3392 }
3393 }
3394}