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 [&[u8]] {
1256 fn encode_binary(&self, buf: &mut Vec<u8>) {
1257 encode_array_header(buf, self.len(), 17);
1258 for val in self {
1259 buf.extend_from_slice(&(val.len() as i32).to_be_bytes());
1260 buf.extend_from_slice(val);
1261 }
1262 }
1263
1264 #[inline]
1265 fn type_oid(&self) -> u32 {
1266 1001 }
1268}
1269
1270impl Encode for &[&[u8]] {
1271 #[inline]
1272 fn encode_binary(&self, buf: &mut Vec<u8>) {
1273 (**self).encode_binary(buf);
1274 }
1275
1276 #[inline]
1277 fn type_oid(&self) -> u32 {
1278 1001
1279 }
1280}
1281
1282impl Encode for [Vec<u8>] {
1283 fn encode_binary(&self, buf: &mut Vec<u8>) {
1284 encode_array_header(buf, self.len(), 17);
1285 for val in self {
1286 buf.extend_from_slice(&(val.len() as i32).to_be_bytes());
1287 buf.extend_from_slice(val);
1288 }
1289 }
1290
1291 #[inline]
1292 fn type_oid(&self) -> u32 {
1293 1001 }
1295}
1296
1297impl Encode for &[Vec<u8>] {
1298 #[inline]
1299 fn encode_binary(&self, buf: &mut Vec<u8>) {
1300 (**self).encode_binary(buf);
1301 }
1302
1303 #[inline]
1304 fn type_oid(&self) -> u32 {
1305 1001
1306 }
1307}
1308
1309impl Encode for Vec<Vec<u8>> {
1310 #[inline]
1311 fn encode_binary(&self, buf: &mut Vec<u8>) {
1312 self.as_slice().encode_binary(buf);
1313 }
1314
1315 #[inline]
1316 fn type_oid(&self) -> u32 {
1317 1001 }
1319}
1320
1321fn decode_array_elements(data: &[u8]) -> Result<Vec<&[u8]>, DriverError> {
1332 if data.len() < 12 {
1333 return Err(DriverError::Protocol(format!(
1334 "array: expected >= 12 bytes header, got {}",
1335 data.len()
1336 )));
1337 }
1338 let ndim = i32::from_be_bytes([data[0], data[1], data[2], data[3]]);
1339 if ndim == 0 {
1340 return Ok(Vec::new());
1341 }
1342 if ndim != 1 {
1343 return Err(DriverError::Protocol(format!(
1344 "array: only 1-dimensional arrays supported, got {ndim}"
1345 )));
1346 }
1347 if data.len() < 20 {
1349 return Err(DriverError::Protocol(
1350 "array: truncated dimension header".into(),
1351 ));
1352 }
1353 let n_elements_raw = i32::from_be_bytes([data[12], data[13], data[14], data[15]]);
1354 if n_elements_raw < 0 {
1355 return Err(DriverError::Protocol(
1356 "array: negative element count".into(),
1357 ));
1358 }
1359 let n_elements = n_elements_raw as usize;
1360 const MAX_ARRAY_ELEMENTS: usize = 10_000_000;
1364 if n_elements > MAX_ARRAY_ELEMENTS {
1365 return Err(DriverError::Protocol(format!(
1366 "array element count {n_elements} exceeds limit of {MAX_ARRAY_ELEMENTS}"
1367 )));
1368 }
1369 let mut pos = 20;
1371 let mut elements = Vec::with_capacity(n_elements);
1372 for _ in 0..n_elements {
1373 if pos + 4 > data.len() {
1374 return Err(DriverError::Protocol("array: truncated element".into()));
1375 }
1376 let elem_len = i32::from_be_bytes([data[pos], data[pos + 1], data[pos + 2], data[pos + 3]]);
1377 pos += 4;
1378 if elem_len < 0 {
1379 continue;
1381 }
1382 let elem_len = elem_len as usize;
1383 if pos + elem_len > data.len() {
1384 return Err(DriverError::Protocol(
1385 "array: truncated element data".into(),
1386 ));
1387 }
1388 elements.push(&data[pos..pos + elem_len]);
1389 pos += elem_len;
1390 }
1391 Ok(elements)
1392}
1393
1394pub fn decode_array_i32(data: &[u8]) -> Result<Vec<i32>, DriverError> {
1396 decode_array_elements(data)?
1397 .into_iter()
1398 .map(decode_i32)
1399 .collect()
1400}
1401
1402pub fn decode_array_i16(data: &[u8]) -> Result<Vec<i16>, DriverError> {
1404 decode_array_elements(data)?
1405 .into_iter()
1406 .map(decode_i16)
1407 .collect()
1408}
1409
1410pub fn decode_array_i64(data: &[u8]) -> Result<Vec<i64>, DriverError> {
1412 decode_array_elements(data)?
1413 .into_iter()
1414 .map(decode_i64)
1415 .collect()
1416}
1417
1418pub fn decode_array_f32(data: &[u8]) -> Result<Vec<f32>, DriverError> {
1420 decode_array_elements(data)?
1421 .into_iter()
1422 .map(decode_f32)
1423 .collect()
1424}
1425
1426pub fn decode_array_f64(data: &[u8]) -> Result<Vec<f64>, DriverError> {
1428 decode_array_elements(data)?
1429 .into_iter()
1430 .map(decode_f64)
1431 .collect()
1432}
1433
1434pub fn decode_array_bool(data: &[u8]) -> Result<Vec<bool>, DriverError> {
1436 decode_array_elements(data)?
1437 .into_iter()
1438 .map(decode_bool)
1439 .collect()
1440}
1441
1442pub fn decode_array_str(data: &[u8]) -> Result<Vec<String>, DriverError> {
1444 decode_array_elements(data)?
1445 .into_iter()
1446 .map(|d| decode_str(d).map(|s| s.to_owned()))
1447 .collect()
1448}
1449
1450pub fn decode_array_bytea(data: &[u8]) -> Result<Vec<Vec<u8>>, DriverError> {
1452 Ok(decode_array_elements(data)?
1453 .into_iter()
1454 .map(|d| d.to_vec())
1455 .collect())
1456}
1457
1458#[cfg(feature = "uuid")]
1462#[inline]
1463pub fn decode_uuid_type(data: &[u8]) -> Result<uuid::Uuid, DriverError> {
1464 let bytes = decode_uuid(data)?;
1465 Ok(uuid::Uuid::from_bytes(bytes))
1466}
1467
1468#[cfg(feature = "time")]
1470#[inline]
1471pub fn decode_timestamptz_time(data: &[u8]) -> Result<time::OffsetDateTime, DriverError> {
1472 let micros = decode_i64(data)?;
1473 let unix_micros = micros + 946_684_800i64 * 1_000_000;
1475 let secs = unix_micros.div_euclid(1_000_000);
1476 let nanos = (unix_micros.rem_euclid(1_000_000) * 1000) as i128;
1477 time::OffsetDateTime::from_unix_timestamp_nanos(secs as i128 * 1_000_000_000 + nanos)
1478 .map_err(|e| DriverError::Protocol(format!("timestamptz decode: {e}")))
1479}
1480
1481#[cfg(feature = "time")]
1483#[inline]
1484pub fn decode_date_time(data: &[u8]) -> Result<time::Date, DriverError> {
1485 let days = decode_i32(data)?;
1486 let julian_day = PG_EPOCH_JULIAN_DAY as i64 + days as i64;
1488 if julian_day < i32::MIN as i64 || julian_day > i32::MAX as i64 {
1489 return Err(DriverError::Protocol(format!(
1490 "date out of range: {days} days"
1491 )));
1492 }
1493 time::Date::from_julian_day(julian_day as i32)
1494 .map_err(|_| DriverError::Protocol(format!("date out of range: {days} days")))
1495}
1496
1497#[cfg(feature = "time")]
1499#[inline]
1500pub fn decode_time_time(data: &[u8]) -> Result<time::Time, DriverError> {
1501 let micros = decode_i64(data)?;
1502
1503 if !(0..86_400_000_000).contains(µs) {
1505 return Err(DriverError::Protocol(format!(
1506 "time out of range: {micros}us (must be 0..86_400_000_000)"
1507 )));
1508 }
1509 let total_secs = micros / 1_000_000;
1510 let h = (total_secs / 3600) as u8;
1511 let m = ((total_secs % 3600) / 60) as u8;
1512 let s = (total_secs % 60) as u8;
1513 let micro = (micros % 1_000_000) as u32;
1514 time::Time::from_hms_micro(h, m, s, micro)
1515 .map_err(|e| DriverError::Protocol(format!("time decode: {e}")))
1516}
1517
1518#[cfg(feature = "chrono")]
1520#[inline]
1521pub fn decode_timestamptz_chrono(
1522 data: &[u8],
1523) -> Result<chrono::DateTime<chrono::Utc>, DriverError> {
1524 let micros = decode_i64(data)?;
1525 let pg_epoch_unix_micros: i64 = 946_684_800 * 1_000_000;
1526 let unix_micros = micros + pg_epoch_unix_micros;
1527 let secs = unix_micros.div_euclid(1_000_000);
1528 let nsecs = (unix_micros.rem_euclid(1_000_000) * 1000) as u32;
1529 chrono::DateTime::from_timestamp(secs, nsecs)
1530 .ok_or_else(|| DriverError::Protocol(format!("timestamptz out of range: {micros}us")))
1531}
1532
1533#[cfg(feature = "chrono")]
1535#[inline]
1536pub fn decode_date_chrono(data: &[u8]) -> Result<chrono::NaiveDate, DriverError> {
1537 let days = decode_i32(data)?;
1538 const PG_EPOCH_CE_DAYS: i32 = 730_120;
1540 let ce_days = PG_EPOCH_CE_DAYS as i64 + days as i64;
1541 if ce_days < i32::MIN as i64 || ce_days > i32::MAX as i64 {
1542 return Err(DriverError::Protocol(format!(
1543 "date out of range: {days} days"
1544 )));
1545 }
1546 chrono::NaiveDate::from_num_days_from_ce_opt(ce_days as i32)
1547 .ok_or_else(|| DriverError::Protocol(format!("date out of range: {days} days")))
1548}
1549
1550#[cfg(feature = "chrono")]
1552#[inline]
1553pub fn decode_time_chrono(data: &[u8]) -> Result<chrono::NaiveTime, DriverError> {
1554 let micros = decode_i64(data)?;
1555
1556 if !(0..86_400_000_000).contains(µs) {
1558 return Err(DriverError::Protocol(format!(
1559 "time out of range: {micros}us (must be 0..86_400_000_000)"
1560 )));
1561 }
1562 let total_secs = (micros / 1_000_000) as u32;
1563 let micro = (micros % 1_000_000) as u32;
1564 chrono::NaiveTime::from_num_seconds_from_midnight_opt(total_secs, micro * 1000)
1565 .ok_or_else(|| DriverError::Protocol(format!("time out of range: {micros}us")))
1566}
1567
1568#[cfg(feature = "decimal")]
1575pub fn decode_numeric_decimal(data: &[u8]) -> Result<rust_decimal::Decimal, DriverError> {
1576 if data.len() < 8 {
1577 return Err(DriverError::Protocol(format!(
1578 "numeric: expected >= 8 bytes header, got {}",
1579 data.len()
1580 )));
1581 }
1582 let ndigits = i16::from_be_bytes([data[0], data[1]]) as usize;
1583 let weight = i16::from_be_bytes([data[2], data[3]]) as i32;
1584 let sign = i16::from_be_bytes([data[4], data[5]]);
1585 let _dscale = i16::from_be_bytes([data[6], data[7]]) as u32;
1586
1587 if data.len() != 8 + ndigits * 2 {
1588 return Err(DriverError::Protocol(format!(
1589 "numeric: expected {} bytes, got {}",
1590 8 + ndigits * 2,
1591 data.len()
1592 )));
1593 }
1594
1595 if ndigits == 0 {
1596 return Ok(rust_decimal::Decimal::ZERO);
1597 }
1598
1599 let mut digits: smallvec::SmallVec<[i64; 16]> = smallvec::SmallVec::with_capacity(ndigits);
1601 for i in 0..ndigits {
1602 let off = 8 + i * 2;
1603 digits.push(i16::from_be_bytes([data[off], data[off + 1]]) as i64);
1604 }
1605
1606 let mut mantissa: u128 = 0;
1609 for &d in &digits {
1610 mantissa = mantissa
1611 .checked_mul(10_000)
1612 .and_then(|m| m.checked_add(d as u128))
1613 .ok_or_else(|| DriverError::Protocol("numeric value too large for Decimal".into()))?;
1614 }
1615
1616 let exponent = 4 * (weight - ndigits as i32 + 1);
1620 let result = if exponent >= 0 {
1621 let factor = 10u128
1623 .checked_pow(exponent as u32)
1624 .ok_or_else(|| DriverError::Protocol("numeric exponent too large".into()))?;
1625 let m = mantissa
1626 .checked_mul(factor)
1627 .ok_or_else(|| DriverError::Protocol("numeric value too large for Decimal".into()))?;
1628 if m > u128::from(u64::MAX) {
1629 let s = m.to_string();
1631 s.parse::<rust_decimal::Decimal>()
1632 .map_err(|e| DriverError::Protocol(format!("numeric parse error: {e}")))?
1633 } else {
1634 rust_decimal::Decimal::from_i128_with_scale(m as i128, 0)
1635 }
1636 } else {
1637 let scale = (-exponent) as u32;
1639 if mantissa <= u128::from(u64::MAX) {
1641 rust_decimal::Decimal::from_i128_with_scale(mantissa as i128, scale)
1642 } else {
1643 let mut s = mantissa.to_string();
1645 if scale as usize >= s.len() {
1646 let zeros = scale as usize - s.len() + 1;
1647 s = format!("0.{}{s}", "0".repeat(zeros));
1648 } else {
1649 let dot_pos = s.len() - scale as usize;
1650 s.insert(dot_pos, '.');
1651 }
1652 s.parse::<rust_decimal::Decimal>()
1653 .map_err(|e| DriverError::Protocol(format!("numeric parse error: {e}")))?
1654 }
1655 };
1656
1657 if sign == 0x4000 {
1658 Ok(-result)
1659 } else {
1660 Ok(result)
1661 }
1662}
1663
1664#[cfg(test)]
1665#[allow(clippy::approx_constant)]
1666mod tests {
1667 use super::*;
1668
1669 #[test]
1672 fn bool_roundtrip() {
1673 let mut buf = Vec::new();
1674 true.encode_binary(&mut buf);
1675 assert!(decode_bool(&buf).unwrap());
1676
1677 buf.clear();
1678 false.encode_binary(&mut buf);
1679 assert!(!decode_bool(&buf).unwrap());
1680 }
1681
1682 #[test]
1683 fn i16_roundtrip() {
1684 let mut buf = Vec::new();
1685 12345i16.encode_binary(&mut buf);
1686 assert_eq!(decode_i16(&buf).unwrap(), 12345);
1687
1688 buf.clear();
1689 (-1i16).encode_binary(&mut buf);
1690 assert_eq!(decode_i16(&buf).unwrap(), -1);
1691
1692 buf.clear();
1693 i16::MIN.encode_binary(&mut buf);
1694 assert_eq!(decode_i16(&buf).unwrap(), i16::MIN);
1695
1696 buf.clear();
1697 i16::MAX.encode_binary(&mut buf);
1698 assert_eq!(decode_i16(&buf).unwrap(), i16::MAX);
1699 }
1700
1701 #[test]
1702 fn i32_roundtrip() {
1703 let mut buf = Vec::new();
1704 42i32.encode_binary(&mut buf);
1705 assert_eq!(buf, &[0, 0, 0, 42]);
1706 assert_eq!(decode_i32(&buf).unwrap(), 42);
1707
1708 buf.clear();
1709 i32::MAX.encode_binary(&mut buf);
1710 assert_eq!(decode_i32(&buf).unwrap(), i32::MAX);
1711
1712 buf.clear();
1713 i32::MIN.encode_binary(&mut buf);
1714 assert_eq!(decode_i32(&buf).unwrap(), i32::MIN);
1715 }
1716
1717 #[test]
1718 fn i64_roundtrip() {
1719 let mut buf = Vec::new();
1720 1234567890123i64.encode_binary(&mut buf);
1721 assert_eq!(decode_i64(&buf).unwrap(), 1234567890123);
1722 }
1723
1724 #[test]
1725 fn f32_roundtrip() {
1726 let mut buf = Vec::new();
1727 3.14f32.encode_binary(&mut buf);
1728 let decoded = decode_f32(&buf).unwrap();
1729 assert!((decoded - 3.14).abs() < f32::EPSILON);
1730 }
1731
1732 #[test]
1733 fn f64_roundtrip() {
1734 let mut buf = Vec::new();
1735 std::f64::consts::PI.encode_binary(&mut buf);
1736 let decoded = decode_f64(&buf).unwrap();
1737 assert!((decoded - std::f64::consts::PI).abs() < f64::EPSILON);
1738 }
1739
1740 #[test]
1741 fn str_roundtrip() {
1742 let mut buf = Vec::new();
1743 "hello world".encode_binary(&mut buf);
1744 assert_eq!(decode_str(&buf).unwrap(), "hello world");
1745 }
1746
1747 #[test]
1748 fn string_roundtrip() {
1749 let mut buf = Vec::new();
1750 let s = String::from("test string");
1751 s.encode_binary(&mut buf);
1752 assert_eq!(decode_str(&buf).unwrap(), "test string");
1753 }
1754
1755 #[test]
1756 fn bytes_roundtrip() {
1757 let mut buf = Vec::new();
1758 let data: &[u8] = &[0xDE, 0xAD, 0xBE, 0xEF];
1759 data.encode_binary(&mut buf);
1760 assert_eq!(decode_bytes(&buf), data);
1761 }
1762
1763 #[test]
1764 fn vec_u8_roundtrip() {
1765 let mut buf = Vec::new();
1766 let data = vec![1u8, 2, 3, 4, 5];
1767 data.encode_binary(&mut buf);
1768 assert_eq!(decode_bytes(&buf), &[1, 2, 3, 4, 5]);
1769 }
1770
1771 #[test]
1772 fn u32_encode() {
1773 let mut buf = Vec::new();
1774 42u32.encode_binary(&mut buf);
1775 assert_eq!(buf, &[0, 0, 0, 42]);
1776 }
1777
1778 #[test]
1779 fn uuid_roundtrip() {
1780 let uuid_bytes: [u8; 16] = [
1781 0x55, 0x0e, 0x84, 0x00, 0xe2, 0x9b, 0x41, 0xd4, 0xa7, 0x16, 0x44, 0x66, 0x55, 0x44,
1782 0x00, 0x00,
1783 ];
1784 let decoded = decode_uuid(&uuid_bytes).unwrap();
1785 assert_eq!(decoded, uuid_bytes);
1786 }
1787
1788 #[test]
1791 fn decode_bool_wrong_length() {
1792 assert!(decode_bool(&[]).is_err());
1793 assert!(decode_bool(&[0, 0]).is_err());
1794 }
1795
1796 #[test]
1797 fn decode_i32_wrong_length() {
1798 assert!(decode_i32(&[0, 0, 0]).is_err());
1799 assert!(decode_i32(&[0, 0, 0, 0, 0]).is_err());
1800 }
1801
1802 #[test]
1803 fn decode_i64_wrong_length() {
1804 assert!(decode_i64(&[0; 7]).is_err());
1805 assert!(decode_i64(&[0; 9]).is_err());
1806 }
1807
1808 #[test]
1809 fn decode_f32_wrong_length() {
1810 assert!(decode_f32(&[0; 3]).is_err());
1811 }
1812
1813 #[test]
1814 fn decode_f64_wrong_length() {
1815 assert!(decode_f64(&[0; 7]).is_err());
1816 }
1817
1818 #[test]
1819 fn decode_str_invalid_utf8() {
1820 assert!(decode_str(&[0xFF, 0xFE]).is_err());
1821 }
1822
1823 #[test]
1824 fn decode_uuid_wrong_length() {
1825 assert!(decode_uuid(&[0; 15]).is_err());
1826 assert!(decode_uuid(&[0; 17]).is_err());
1827 }
1828
1829 #[test]
1830 fn empty_str_decode() {
1831 assert_eq!(decode_str(&[]).unwrap(), "");
1832 }
1833
1834 #[test]
1835 fn empty_bytes_decode() {
1836 assert_eq!(decode_bytes(&[]).len(), 0);
1837 }
1838
1839 #[test]
1842 fn type_oids_correct() {
1843 assert_eq!(true.type_oid(), 16);
1844 assert_eq!(0i16.type_oid(), 21);
1845 assert_eq!(0i32.type_oid(), 23);
1846 assert_eq!(0i64.type_oid(), 20);
1847 assert_eq!(0f32.type_oid(), 700);
1848 assert_eq!(0f64.type_oid(), 701);
1849 assert_eq!("".type_oid(), 25);
1850 assert_eq!(String::new().type_oid(), 25);
1851 let b: &[u8] = &[];
1852 assert_eq!(b.type_oid(), 17);
1853 assert_eq!(Vec::<u8>::new().type_oid(), 17);
1854 assert_eq!(0u32.type_oid(), 26);
1855 }
1856
1857 #[test]
1860 fn encode_param_i32() {
1861 let mut buf = Vec::new();
1862 encode_param(&mut buf, &42i32);
1863 assert_eq!(buf.len(), 8);
1865 let len = i32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]);
1866 assert_eq!(len, 4);
1867 let val = i32::from_be_bytes([buf[4], buf[5], buf[6], buf[7]]);
1868 assert_eq!(val, 42);
1869 }
1870
1871 #[test]
1872 fn encode_param_str() {
1873 let mut buf = Vec::new();
1874 encode_param(&mut buf, &"hello");
1875 assert_eq!(buf.len(), 9);
1877 let len = i32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]);
1878 assert_eq!(len, 5);
1879 assert_eq!(&buf[4..], b"hello");
1880 }
1881
1882 #[test]
1883 fn option_none_is_null() {
1884 let val: Option<i32> = None;
1885 assert!(val.is_null());
1886 assert_eq!(val.type_oid(), 0);
1887 }
1888
1889 #[test]
1890 fn option_some_encodes() {
1891 let val: Option<i32> = Some(42);
1892 assert!(!val.is_null());
1893 assert_eq!(val.type_oid(), 23);
1894 let mut buf = Vec::new();
1895 val.encode_binary(&mut buf);
1896 assert_eq!(buf, &[0, 0, 0, 42]);
1897 }
1898
1899 #[test]
1900 fn option_none_encode_is_noop() {
1901 let val: Option<i32> = None;
1902 let mut buf = Vec::new();
1903 val.encode_binary(&mut buf);
1904 assert!(buf.is_empty(), "None encode should produce no bytes");
1905 }
1906
1907 #[test]
1911 fn decode_i16_wrong_length() {
1912 assert!(decode_i16(&[]).is_err());
1913 assert!(decode_i16(&[0]).is_err());
1914 assert!(decode_i16(&[0, 0, 0]).is_err());
1915 }
1916
1917 #[test]
1919 fn f32_nan_roundtrip() {
1920 let mut buf = Vec::new();
1921 f32::NAN.encode_binary(&mut buf);
1922 let decoded = decode_f32(&buf).unwrap();
1923 assert!(decoded.is_nan(), "NaN should survive roundtrip");
1924 }
1925
1926 #[test]
1928 fn f64_nan_roundtrip() {
1929 let mut buf = Vec::new();
1930 f64::NAN.encode_binary(&mut buf);
1931 let decoded = decode_f64(&buf).unwrap();
1932 assert!(decoded.is_nan(), "NaN should survive roundtrip");
1933 }
1934
1935 #[test]
1937 fn f32_infinity_roundtrip() {
1938 let mut buf = Vec::new();
1939 f32::INFINITY.encode_binary(&mut buf);
1940 assert_eq!(decode_f32(&buf).unwrap(), f32::INFINITY);
1941
1942 buf.clear();
1943 f32::NEG_INFINITY.encode_binary(&mut buf);
1944 assert_eq!(decode_f32(&buf).unwrap(), f32::NEG_INFINITY);
1945 }
1946
1947 #[test]
1949 fn f64_infinity_roundtrip() {
1950 let mut buf = Vec::new();
1951 f64::INFINITY.encode_binary(&mut buf);
1952 assert_eq!(decode_f64(&buf).unwrap(), f64::INFINITY);
1953
1954 buf.clear();
1955 f64::NEG_INFINITY.encode_binary(&mut buf);
1956 assert_eq!(decode_f64(&buf).unwrap(), f64::NEG_INFINITY);
1957 }
1958
1959 #[test]
1961 fn f32_signed_zero_roundtrip() {
1962 let mut buf = Vec::new();
1963 0.0f32.encode_binary(&mut buf);
1964 let decoded = decode_f32(&buf).unwrap();
1965 assert_eq!(decoded.to_bits(), 0.0f32.to_bits(), "+0.0 bits must match");
1966
1967 buf.clear();
1968 (-0.0f32).encode_binary(&mut buf);
1969 let decoded = decode_f32(&buf).unwrap();
1970 assert_eq!(
1971 decoded.to_bits(),
1972 (-0.0f32).to_bits(),
1973 "-0.0 bits must match"
1974 );
1975 }
1976
1977 #[test]
1979 fn f64_signed_zero_roundtrip() {
1980 let mut buf = Vec::new();
1981 0.0f64.encode_binary(&mut buf);
1982 let decoded = decode_f64(&buf).unwrap();
1983 assert_eq!(decoded.to_bits(), 0.0f64.to_bits(), "+0.0 bits must match");
1984
1985 buf.clear();
1986 (-0.0f64).encode_binary(&mut buf);
1987 let decoded = decode_f64(&buf).unwrap();
1988 assert_eq!(
1989 decoded.to_bits(),
1990 (-0.0f64).to_bits(),
1991 "-0.0 bits must match"
1992 );
1993 }
1994
1995 #[test]
1997 fn i64_boundary_roundtrip() {
1998 let mut buf = Vec::new();
1999 i64::MIN.encode_binary(&mut buf);
2000 assert_eq!(decode_i64(&buf).unwrap(), i64::MIN);
2001
2002 buf.clear();
2003 i64::MAX.encode_binary(&mut buf);
2004 assert_eq!(decode_i64(&buf).unwrap(), i64::MAX);
2005 }
2006
2007 #[test]
2009 fn i16_boundary_standalone() {
2010 let mut buf = Vec::new();
2011 i16::MIN.encode_binary(&mut buf);
2012 assert_eq!(decode_i16(&buf).unwrap(), i16::MIN);
2013
2014 buf.clear();
2015 i16::MAX.encode_binary(&mut buf);
2016 assert_eq!(decode_i16(&buf).unwrap(), i16::MAX);
2017 }
2018
2019 #[cfg(feature = "chrono")]
2021 #[test]
2022 fn decode_date_chrono_negative_days() {
2023 let data = (-365i32).to_be_bytes();
2025 let date = decode_date_chrono(&data).unwrap();
2026 assert_eq!(date, chrono::NaiveDate::from_ymd_opt(1999, 1, 1).unwrap());
2027 }
2028
2029 #[cfg(feature = "chrono")]
2031 #[test]
2032 fn decode_date_chrono_day_zero() {
2033 let data = 0i32.to_be_bytes();
2034 let date = decode_date_chrono(&data).unwrap();
2035 assert_eq!(date, chrono::NaiveDate::from_ymd_opt(2000, 1, 1).unwrap());
2036 }
2037
2038 #[cfg(feature = "time")]
2040 #[test]
2041 fn decode_date_time_negative_days() {
2042 let data = (-1i32).to_be_bytes();
2043 let date = decode_date_time(&data).unwrap();
2044 let expected = time::Date::from_calendar_date(1999, time::Month::December, 31).unwrap();
2045 assert_eq!(date, expected);
2046 }
2047
2048 #[cfg(feature = "time")]
2050 #[test]
2051 fn decode_time_time_midnight() {
2052 let data = 0i64.to_be_bytes();
2053 let t = decode_time_time(&data).unwrap();
2054 assert_eq!(t, time::Time::MIDNIGHT);
2055 }
2056
2057 #[cfg(feature = "time")]
2059 #[test]
2060 fn decode_time_time_max_value() {
2061 let micros: i64 = 86_400_000_000 - 1; let data = micros.to_be_bytes();
2063 let t = decode_time_time(&data).unwrap();
2064 assert_eq!(t.hour(), 23);
2065 assert_eq!(t.minute(), 59);
2066 assert_eq!(t.second(), 59);
2067 assert_eq!(t.microsecond(), 999999);
2068 }
2069
2070 #[cfg(feature = "time")]
2072 #[test]
2073 fn decode_time_time_negative_micros_error() {
2074 let data = (-1i64).to_be_bytes();
2075 let result = decode_time_time(&data);
2076 assert!(result.is_err(), "negative microseconds should error");
2077 }
2078
2079 #[cfg(feature = "time")]
2081 #[test]
2082 fn decode_time_time_overflow_error() {
2083 let data = 86_400_000_000i64.to_be_bytes();
2084 let result = decode_time_time(&data);
2085 assert!(result.is_err(), ">= 24h microseconds should error");
2086 }
2087
2088 #[cfg(feature = "time")]
2090 #[test]
2091 fn decode_timestamptz_time_pg_epoch() {
2092 let data = 0i64.to_be_bytes();
2093 let dt = decode_timestamptz_time(&data).unwrap();
2094 assert_eq!(dt.year(), 2000);
2096 assert_eq!(dt.month(), time::Month::January);
2097 assert_eq!(dt.day(), 1);
2098 assert_eq!(dt.hour(), 0);
2099 assert_eq!(dt.minute(), 0);
2100 assert_eq!(dt.second(), 0);
2101 }
2102
2103 #[cfg(feature = "decimal")]
2105 #[test]
2106 fn decode_numeric_decimal_zero() {
2107 let mut data = Vec::new();
2109 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();
2114 assert!(dec.is_zero());
2115 }
2116
2117 #[cfg(feature = "decimal")]
2119 #[test]
2120 fn decode_numeric_decimal_negative() {
2121 let mut data = Vec::new();
2123 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();
2129 assert_eq!(dec, rust_decimal::Decimal::new(-42, 0));
2130 }
2131
2132 #[cfg(feature = "decimal")]
2134 #[test]
2135 fn decode_numeric_decimal_pure_fractional() {
2136 let mut data = Vec::new();
2141 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();
2147 let dec_normalized = dec.normalize();
2149 assert_eq!(dec_normalized.to_string(), "0.001");
2150 }
2151
2152 #[cfg(feature = "decimal")]
2157 fn decimal_encode_roundtrip(s: &str) {
2158 use rust_decimal::Decimal;
2159 use std::str::FromStr;
2160 let original = Decimal::from_str(s).unwrap();
2161 let mut buf = Vec::new();
2162 original.encode_binary(&mut buf);
2163 let decoded = decode_numeric_decimal(&buf).unwrap();
2164 assert_eq!(
2165 decoded.normalize().to_string(),
2166 original.normalize().to_string(),
2167 "round-trip failed for {s}: encoded {} bytes",
2168 buf.len()
2169 );
2170 }
2171
2172 #[cfg(feature = "decimal")]
2173 #[test]
2174 fn decimal_roundtrip_zero() {
2175 decimal_encode_roundtrip("0");
2176 }
2177
2178 #[cfg(feature = "decimal")]
2179 #[test]
2180 fn decimal_roundtrip_one() {
2181 decimal_encode_roundtrip("1");
2182 }
2183
2184 #[cfg(feature = "decimal")]
2185 #[test]
2186 fn decimal_roundtrip_negative() {
2187 decimal_encode_roundtrip("-42.5");
2188 }
2189
2190 #[cfg(feature = "decimal")]
2191 #[test]
2192 fn decimal_roundtrip_large_integer() {
2193 decimal_encode_roundtrip("123456789");
2194 }
2195
2196 #[cfg(feature = "decimal")]
2197 #[test]
2198 fn decimal_roundtrip_pure_fractional_0001() {
2199 decimal_encode_roundtrip("0.001");
2200 }
2201
2202 #[cfg(feature = "decimal")]
2203 #[test]
2204 fn decimal_roundtrip_pure_fractional_00001() {
2205 decimal_encode_roundtrip("0.0001");
2206 }
2207
2208 #[cfg(feature = "decimal")]
2209 #[test]
2210 fn decimal_roundtrip_pure_fractional_000001() {
2211 decimal_encode_roundtrip("0.00001");
2212 }
2213
2214 #[cfg(feature = "decimal")]
2215 #[test]
2216 fn decimal_roundtrip_mixed() {
2217 decimal_encode_roundtrip("12345.6789");
2218 }
2219
2220 #[cfg(feature = "decimal")]
2221 #[test]
2222 fn decimal_roundtrip_trailing_zeros() {
2223 decimal_encode_roundtrip("100.00");
2224 }
2225
2226 #[cfg(feature = "decimal")]
2227 #[test]
2228 fn decimal_roundtrip_small_negative_fraction() {
2229 decimal_encode_roundtrip("-0.007");
2230 }
2231
2232 #[cfg(feature = "decimal")]
2233 #[test]
2234 fn decimal_roundtrip_high_scale() {
2235 decimal_encode_roundtrip("0.0000000000000000000000000001");
2237 }
2238
2239 #[cfg(feature = "decimal")]
2240 #[test]
2241 fn decimal_roundtrip_large_with_fraction() {
2242 decimal_encode_roundtrip("999999999999999999.999999999999");
2243 }
2244
2245 #[test]
2247 fn decode_array_empty() {
2248 let mut data = Vec::new();
2250 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();
2254 assert!(elems.is_empty());
2255 }
2256
2257 #[test]
2259 fn decode_array_multidim_error() {
2260 let mut data = Vec::new();
2261 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());
2266 data.extend_from_slice(&0i32.to_be_bytes());
2267 data.extend_from_slice(&0i32.to_be_bytes());
2268 data.extend_from_slice(&0i32.to_be_bytes());
2269 let result = decode_array_i32(&data);
2270 assert!(result.is_err(), "multi-dimensional should error");
2271 }
2272
2273 #[test]
2275 fn decode_array_truncated_error() {
2276 let mut data = Vec::new();
2278 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);
2285 assert!(result.is_err(), "truncated array should error");
2286 }
2287
2288 #[test]
2290 fn option_some_i32_produces_data() {
2291 let val: Option<i32> = Some(42);
2292 assert!(!val.is_null());
2293 let mut buf = Vec::new();
2294 val.encode_binary(&mut buf);
2295 assert_eq!(decode_i32(&buf).unwrap(), 42);
2296 }
2297
2298 #[test]
2300 fn option_none_i32_is_null() {
2301 let val: Option<i32> = None;
2302 assert!(val.is_null());
2303 let mut buf = Vec::new();
2304 val.encode_binary(&mut buf);
2305 assert!(buf.is_empty());
2306 }
2307
2308 #[test]
2310 fn empty_string_encode_decode() {
2311 let mut buf = Vec::new();
2312 "".encode_binary(&mut buf);
2313 assert!(buf.is_empty());
2314 assert_eq!(decode_str(&buf).unwrap(), "");
2315
2316 buf.clear();
2317 String::new().encode_binary(&mut buf);
2318 assert!(buf.is_empty());
2319 assert_eq!(decode_str(&buf).unwrap(), "");
2320 }
2321
2322 #[test]
2324 fn empty_bytes_encode_decode() {
2325 let mut buf = Vec::new();
2326 let empty: &[u8] = &[];
2327 empty.encode_binary(&mut buf);
2328 assert!(buf.is_empty());
2329 assert_eq!(decode_bytes(&buf).len(), 0);
2330
2331 buf.clear();
2332 Vec::<u8>::new().encode_binary(&mut buf);
2333 assert!(buf.is_empty());
2334 }
2335
2336 #[test]
2338 fn large_string_encode_decode() {
2339 let big = "x".repeat(1_000_000);
2340 let mut buf = Vec::new();
2341 big.as_str().encode_binary(&mut buf);
2342 assert_eq!(buf.len(), 1_000_000);
2343 assert_eq!(decode_str(&buf).unwrap(), big);
2344 }
2345
2346 #[test]
2348 fn uuid_nil() {
2349 let nil = [0u8; 16];
2350 let decoded = decode_uuid(&nil).unwrap();
2351 assert_eq!(decoded, [0u8; 16]);
2352 }
2353
2354 #[test]
2356 fn uuid_max() {
2357 let max = [0xFF; 16];
2358 let decoded = decode_uuid(&max).unwrap();
2359 assert_eq!(decoded, [0xFF; 16]);
2360 }
2361
2362 #[cfg(feature = "uuid")]
2364 #[test]
2365 fn uuid_type_nil_and_max() {
2366 let nil = [0u8; 16];
2367 let uuid = decode_uuid_type(&nil).unwrap();
2368 assert_eq!(uuid, uuid::Uuid::nil());
2369
2370 let max = [0xFF; 16];
2371 let uuid = decode_uuid_type(&max).unwrap();
2372 assert_eq!(uuid, uuid::Uuid::max());
2373 }
2374
2375 #[test]
2379 fn encode_array_bool_empty() {
2380 let arr: &[bool] = &[];
2381 let mut buf = Vec::new();
2382 arr.encode_binary(&mut buf);
2383 let decoded = decode_array_bool(&buf).unwrap();
2384 assert!(decoded.is_empty());
2385 }
2386
2387 #[test]
2388 fn encode_array_bool_single() {
2389 let arr: &[bool] = &[true];
2390 let mut buf = Vec::new();
2391 arr.encode_binary(&mut buf);
2392 let decoded = decode_array_bool(&buf).unwrap();
2393 assert_eq!(decoded, vec![true]);
2394 }
2395
2396 #[test]
2397 fn encode_array_bool_multi() {
2398 let arr: &[bool] = &[true, false, true, false];
2399 let mut buf = Vec::new();
2400 arr.encode_binary(&mut buf);
2401 let decoded = decode_array_bool(&buf).unwrap();
2402 assert_eq!(decoded, vec![true, false, true, false]);
2403 }
2404
2405 #[test]
2406 fn encode_array_bool_vec_delegate() {
2407 let v = vec![false, true];
2408 let mut buf = Vec::new();
2409 v.encode_binary(&mut buf);
2410 let decoded = decode_array_bool(&buf).unwrap();
2411 assert_eq!(decoded, vec![false, true]);
2412 assert_eq!(v.type_oid(), 1000);
2413 }
2414
2415 #[test]
2417 fn encode_array_i16_empty() {
2418 let arr: &[i16] = &[];
2419 let mut buf = Vec::new();
2420 arr.encode_binary(&mut buf);
2421 let decoded = decode_array_i16(&buf).unwrap();
2422 assert!(decoded.is_empty());
2423 }
2424
2425 #[test]
2426 fn encode_array_i16_single() {
2427 let arr: &[i16] = &[42];
2428 let mut buf = Vec::new();
2429 arr.encode_binary(&mut buf);
2430 let decoded = decode_array_i16(&buf).unwrap();
2431 assert_eq!(decoded, vec![42i16]);
2432 }
2433
2434 #[test]
2435 fn encode_array_i16_multi_boundary() {
2436 let arr: &[i16] = &[i16::MIN, -1, 0, 1, i16::MAX];
2437 let mut buf = Vec::new();
2438 arr.encode_binary(&mut buf);
2439 let decoded = decode_array_i16(&buf).unwrap();
2440 assert_eq!(decoded, vec![i16::MIN, -1, 0, 1, i16::MAX]);
2441 }
2442
2443 #[test]
2444 fn encode_array_i16_vec_delegate() {
2445 let v = vec![100i16, 200];
2446 let mut buf = Vec::new();
2447 v.encode_binary(&mut buf);
2448 let decoded = decode_array_i16(&buf).unwrap();
2449 assert_eq!(decoded, vec![100i16, 200]);
2450 assert_eq!(v.type_oid(), 1005);
2451 }
2452
2453 #[test]
2455 fn encode_array_i32_empty() {
2456 let arr: &[i32] = &[];
2457 let mut buf = Vec::new();
2458 arr.encode_binary(&mut buf);
2459 let decoded = decode_array_i32(&buf).unwrap();
2460 assert!(decoded.is_empty());
2461 }
2462
2463 #[test]
2464 fn encode_array_i32_single() {
2465 let arr: &[i32] = &[42];
2466 let mut buf = Vec::new();
2467 arr.encode_binary(&mut buf);
2468 let decoded = decode_array_i32(&buf).unwrap();
2469 assert_eq!(decoded, vec![42]);
2470 }
2471
2472 #[test]
2473 fn encode_array_i32_multi_boundary() {
2474 let arr: &[i32] = &[i32::MIN, -1, 0, 1, i32::MAX];
2475 let mut buf = Vec::new();
2476 arr.encode_binary(&mut buf);
2477 let decoded = decode_array_i32(&buf).unwrap();
2478 assert_eq!(decoded, vec![i32::MIN, -1, 0, 1, i32::MAX]);
2479 }
2480
2481 #[test]
2482 fn encode_array_i32_vec_delegate() {
2483 let v = vec![10, 20, 30];
2484 let mut buf = Vec::new();
2485 v.encode_binary(&mut buf);
2486 let decoded = decode_array_i32(&buf).unwrap();
2487 assert_eq!(decoded, vec![10, 20, 30]);
2488 assert_eq!(v.type_oid(), 1007);
2489 }
2490
2491 #[test]
2493 fn encode_array_i64_empty() {
2494 let arr: &[i64] = &[];
2495 let mut buf = Vec::new();
2496 arr.encode_binary(&mut buf);
2497 let decoded = decode_array_i64(&buf).unwrap();
2498 assert!(decoded.is_empty());
2499 }
2500
2501 #[test]
2502 fn encode_array_i64_single() {
2503 let arr: &[i64] = &[9999999999i64];
2504 let mut buf = Vec::new();
2505 arr.encode_binary(&mut buf);
2506 let decoded = decode_array_i64(&buf).unwrap();
2507 assert_eq!(decoded, vec![9999999999i64]);
2508 }
2509
2510 #[test]
2511 fn encode_array_i64_multi_boundary() {
2512 let arr: &[i64] = &[i64::MIN, -1, 0, 1, i64::MAX];
2513 let mut buf = Vec::new();
2514 arr.encode_binary(&mut buf);
2515 let decoded = decode_array_i64(&buf).unwrap();
2516 assert_eq!(decoded, vec![i64::MIN, -1, 0, 1, i64::MAX]);
2517 }
2518
2519 #[test]
2520 fn encode_array_i64_vec_delegate() {
2521 let v = vec![1i64, 2, 3];
2522 let mut buf = Vec::new();
2523 v.encode_binary(&mut buf);
2524 let decoded = decode_array_i64(&buf).unwrap();
2525 assert_eq!(decoded, vec![1i64, 2, 3]);
2526 assert_eq!(v.type_oid(), 1016);
2527 }
2528
2529 #[test]
2531 fn encode_array_f32_empty() {
2532 let arr: &[f32] = &[];
2533 let mut buf = Vec::new();
2534 arr.encode_binary(&mut buf);
2535 let decoded = decode_array_f32(&buf).unwrap();
2536 assert!(decoded.is_empty());
2537 }
2538
2539 #[test]
2540 fn encode_array_f32_single() {
2541 let arr: &[f32] = &[3.14];
2542 let mut buf = Vec::new();
2543 arr.encode_binary(&mut buf);
2544 let decoded = decode_array_f32(&buf).unwrap();
2545 assert!((decoded[0] - 3.14).abs() < f32::EPSILON);
2546 }
2547
2548 #[test]
2549 fn encode_array_f32_multi_boundary() {
2550 let arr: &[f32] = &[
2551 f32::MIN,
2552 -0.0,
2553 0.0,
2554 f32::MAX,
2555 f32::INFINITY,
2556 f32::NEG_INFINITY,
2557 ];
2558 let mut buf = Vec::new();
2559 arr.encode_binary(&mut buf);
2560 let decoded = decode_array_f32(&buf).unwrap();
2561 assert_eq!(decoded[0], f32::MIN);
2562 assert_eq!(decoded[1].to_bits(), (-0.0f32).to_bits());
2563 assert_eq!(decoded[2].to_bits(), 0.0f32.to_bits());
2564 assert_eq!(decoded[3], f32::MAX);
2565 assert_eq!(decoded[4], f32::INFINITY);
2566 assert_eq!(decoded[5], f32::NEG_INFINITY);
2567 }
2568
2569 #[test]
2570 fn encode_array_f32_vec_delegate() {
2571 let v = vec![1.0f32, 2.0];
2572 let mut buf = Vec::new();
2573 v.encode_binary(&mut buf);
2574 let decoded = decode_array_f32(&buf).unwrap();
2575 assert_eq!(decoded, vec![1.0f32, 2.0]);
2576 assert_eq!(v.type_oid(), 1021);
2577 }
2578
2579 #[test]
2581 fn encode_array_f64_empty() {
2582 let arr: &[f64] = &[];
2583 let mut buf = Vec::new();
2584 arr.encode_binary(&mut buf);
2585 let decoded = decode_array_f64(&buf).unwrap();
2586 assert!(decoded.is_empty());
2587 }
2588
2589 #[test]
2590 fn encode_array_f64_single() {
2591 let arr: &[f64] = &[std::f64::consts::PI];
2592 let mut buf = Vec::new();
2593 arr.encode_binary(&mut buf);
2594 let decoded = decode_array_f64(&buf).unwrap();
2595 assert!((decoded[0] - std::f64::consts::PI).abs() < f64::EPSILON);
2596 }
2597
2598 #[test]
2599 fn encode_array_f64_multi_boundary() {
2600 let arr: &[f64] = &[
2601 f64::MIN,
2602 -0.0,
2603 0.0,
2604 f64::MAX,
2605 f64::INFINITY,
2606 f64::NEG_INFINITY,
2607 ];
2608 let mut buf = Vec::new();
2609 arr.encode_binary(&mut buf);
2610 let decoded = decode_array_f64(&buf).unwrap();
2611 assert_eq!(decoded[0], f64::MIN);
2612 assert_eq!(decoded[1].to_bits(), (-0.0f64).to_bits());
2613 assert_eq!(decoded[2].to_bits(), 0.0f64.to_bits());
2614 assert_eq!(decoded[3], f64::MAX);
2615 assert_eq!(decoded[4], f64::INFINITY);
2616 assert_eq!(decoded[5], f64::NEG_INFINITY);
2617 }
2618
2619 #[test]
2620 fn encode_array_f64_vec_delegate() {
2621 let v = vec![1.0f64, 2.0];
2622 let mut buf = Vec::new();
2623 v.encode_binary(&mut buf);
2624 let decoded = decode_array_f64(&buf).unwrap();
2625 assert_eq!(decoded, vec![1.0f64, 2.0]);
2626 assert_eq!(v.type_oid(), 1022);
2627 }
2628
2629 #[test]
2631 fn encode_array_str_empty() {
2632 let arr: &[&str] = &[];
2633 let mut buf = Vec::new();
2634 arr.encode_binary(&mut buf);
2635 let decoded = decode_array_str(&buf).unwrap();
2636 assert!(decoded.is_empty());
2637 }
2638
2639 #[test]
2640 fn encode_array_str_single() {
2641 let arr: &[&str] = &["hello"];
2642 let mut buf = Vec::new();
2643 arr.encode_binary(&mut buf);
2644 let decoded = decode_array_str(&buf).unwrap();
2645 assert_eq!(decoded, vec!["hello".to_string()]);
2646 }
2647
2648 #[test]
2649 fn encode_array_str_multi() {
2650 let arr: &[&str] = &["hello", "", "world"];
2651 let mut buf = Vec::new();
2652 arr.encode_binary(&mut buf);
2653 let decoded = decode_array_str(&buf).unwrap();
2654 assert_eq!(
2655 decoded,
2656 vec!["hello".to_string(), "".to_string(), "world".to_string()]
2657 );
2658 }
2659
2660 #[test]
2661 fn encode_array_str_boundary_unicode() {
2662 let arr: &[&str] = &["\u{1F600}", "\u{00E9}"];
2663 let mut buf = Vec::new();
2664 arr.encode_binary(&mut buf);
2665 let decoded = decode_array_str(&buf).unwrap();
2666 assert_eq!(
2667 decoded,
2668 vec!["\u{1F600}".to_string(), "\u{00E9}".to_string()]
2669 );
2670 }
2671
2672 #[test]
2673 fn encode_array_vec_string() {
2674 let v = vec!["foo".to_string(), "bar".to_string()];
2675 let mut buf = Vec::new();
2676 v.encode_binary(&mut buf);
2677 let decoded = decode_array_str(&buf).unwrap();
2678 assert_eq!(decoded, vec!["foo".to_string(), "bar".to_string()]);
2679 assert_eq!(v.type_oid(), 1009);
2680 }
2681
2682 #[test]
2683 fn encode_array_vec_string_empty() {
2684 let v: Vec<String> = vec![];
2685 let mut buf = Vec::new();
2686 v.encode_binary(&mut buf);
2687 let decoded = decode_array_str(&buf).unwrap();
2688 assert!(decoded.is_empty());
2689 }
2690
2691 #[test]
2693 fn encode_array_bytea_empty() {
2694 let arr: &[&[u8]] = &[];
2695 let mut buf = Vec::new();
2696 arr.encode_binary(&mut buf);
2697 let decoded = decode_array_bytea(&buf).unwrap();
2698 assert!(decoded.is_empty());
2699 }
2700
2701 #[test]
2702 fn encode_array_bytea_single() {
2703 let data: &[u8] = &[0xDE, 0xAD];
2704 let arr: &[&[u8]] = &[data];
2705 let mut buf = Vec::new();
2706 arr.encode_binary(&mut buf);
2707 let decoded = decode_array_bytea(&buf).unwrap();
2708 assert_eq!(decoded, vec![vec![0xDE, 0xAD]]);
2709 }
2710
2711 #[test]
2712 fn encode_array_bytea_multi() {
2713 let a: &[u8] = &[1, 2, 3];
2714 let b: &[u8] = &[];
2715 let c: &[u8] = &[0xFF];
2716 let arr: &[&[u8]] = &[a, b, c];
2717 let mut buf = Vec::new();
2718 arr.encode_binary(&mut buf);
2719 let decoded = decode_array_bytea(&buf).unwrap();
2720 assert_eq!(decoded, vec![vec![1, 2, 3], vec![], vec![0xFF]]);
2721 }
2722
2723 #[test]
2724 fn encode_array_vec_vec_u8() {
2725 let v = vec![vec![10u8, 20], vec![30]];
2726 let mut buf = Vec::new();
2727 v.encode_binary(&mut buf);
2728 let decoded = decode_array_bytea(&buf).unwrap();
2729 assert_eq!(decoded, vec![vec![10u8, 20], vec![30]]);
2730 assert_eq!(v.type_oid(), 1001);
2731 }
2732
2733 #[test]
2734 fn encode_array_vec_vec_u8_empty() {
2735 let v: Vec<Vec<u8>> = vec![];
2736 let mut buf = Vec::new();
2737 v.encode_binary(&mut buf);
2738 let decoded = decode_array_bytea(&buf).unwrap();
2739 assert!(decoded.is_empty());
2740 }
2741
2742 #[test]
2744 fn array_type_oids_correct() {
2745 let b: &[bool] = &[];
2746 assert_eq!(b.type_oid(), 1000);
2747 let i2: &[i16] = &[];
2748 assert_eq!(i2.type_oid(), 1005);
2749 let i4: &[i32] = &[];
2750 assert_eq!(i4.type_oid(), 1007);
2751 let i8: &[i64] = &[];
2752 assert_eq!(i8.type_oid(), 1016);
2753 let f4: &[f32] = &[];
2754 assert_eq!(f4.type_oid(), 1021);
2755 let f8: &[f64] = &[];
2756 assert_eq!(f8.type_oid(), 1022);
2757 let t: &[&str] = &[];
2758 assert_eq!(t.type_oid(), 1009);
2759 let by: &[&[u8]] = &[];
2760 assert_eq!(by.type_oid(), 1001);
2761
2762 assert_eq!(Vec::<bool>::new().type_oid(), 1000);
2763 assert_eq!(Vec::<i16>::new().type_oid(), 1005);
2764 assert_eq!(Vec::<i32>::new().type_oid(), 1007);
2765 assert_eq!(Vec::<i64>::new().type_oid(), 1016);
2766 assert_eq!(Vec::<f32>::new().type_oid(), 1021);
2767 assert_eq!(Vec::<f64>::new().type_oid(), 1022);
2768 assert_eq!(Vec::<String>::new().type_oid(), 1009);
2769 assert_eq!(Vec::<Vec<u8>>::new().type_oid(), 1001);
2770 }
2771
2772 #[test]
2774 fn encode_array_empty_ndim_zero() {
2775 let arr: &[i32] = &[];
2776 let mut buf = Vec::new();
2777 arr.encode_binary(&mut buf);
2778 assert_eq!(buf.len(), 12);
2780 let ndim = i32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]);
2781 assert_eq!(ndim, 0, "empty array must have ndim=0");
2782 let elem_oid = i32::from_be_bytes([buf[8], buf[9], buf[10], buf[11]]);
2783 assert_eq!(
2784 elem_oid, 23,
2785 "element OID must be preserved for empty arrays"
2786 );
2787 }
2788
2789 #[test]
2792 fn encode_at_bool() {
2793 let mut dst = [0u8; 1];
2794 assert!(true.encode_at(&mut dst));
2795 assert_eq!(dst[0], 1);
2796 assert!(false.encode_at(&mut dst));
2797 assert_eq!(dst[0], 0);
2798 assert!(!true.encode_at(&mut [0u8; 2]));
2800 }
2801
2802 #[test]
2803 fn encode_at_i16() {
2804 let mut dst = [0u8; 2];
2805 assert!(0x1234i16.encode_at(&mut dst));
2806 assert_eq!(dst, [0x12, 0x34]);
2807 assert!(!42i16.encode_at(&mut [0u8; 4]));
2808 }
2809
2810 #[test]
2811 fn encode_at_i32() {
2812 let mut dst = [0u8; 4];
2813 assert!(42i32.encode_at(&mut dst));
2814 assert_eq!(dst, [0, 0, 0, 42]);
2815 assert!(!42i32.encode_at(&mut [0u8; 8]));
2816 }
2817
2818 #[test]
2819 fn encode_at_i64() {
2820 let mut dst = [0u8; 8];
2821 assert!(1234567890123i64.encode_at(&mut dst));
2822 assert_eq!(dst, 1234567890123i64.to_be_bytes());
2823 assert!(!42i64.encode_at(&mut [0u8; 4]));
2824 }
2825
2826 #[test]
2827 fn encode_at_f32() {
2828 let mut dst = [0u8; 4];
2829 assert!(3.14f32.encode_at(&mut dst));
2830 assert_eq!(dst, 3.14f32.to_be_bytes());
2831 assert!(!3.14f32.encode_at(&mut [0u8; 8]));
2832 }
2833
2834 #[test]
2835 fn encode_at_f64() {
2836 let mut dst = [0u8; 8];
2837 assert!(3.14f64.encode_at(&mut dst));
2838 assert_eq!(dst, 3.14f64.to_be_bytes());
2839 assert!(!3.14f64.encode_at(&mut [0u8; 4]));
2840 }
2841
2842 #[test]
2843 fn encode_at_u32() {
2844 let mut dst = [0u8; 4];
2845 assert!(42u32.encode_at(&mut dst));
2846 assert_eq!(dst, 42u32.to_be_bytes());
2847 }
2848
2849 #[test]
2850 fn encode_at_str_default_fallback() {
2851 let s: &str = "hello";
2853 let mut dst = [0u8; 5];
2854 assert!(s.encode_at(&mut dst));
2855 assert_eq!(&dst, b"hello");
2856 assert!(!s.encode_at(&mut [0u8; 3]));
2858 }
2859
2860 #[test]
2861 fn encode_at_matches_encode_binary() {
2862 fn check<T: Encode>(val: T, expected_len: usize) {
2865 let mut buf = Vec::new();
2866 val.encode_binary(&mut buf);
2867 assert_eq!(buf.len(), expected_len);
2868 let mut dst = vec![0u8; expected_len];
2869 assert!(val.encode_at(&mut dst));
2870 assert_eq!(
2871 buf, dst,
2872 "encode_at must produce same bytes as encode_binary"
2873 );
2874 }
2875 check(true, 1);
2876 check(false, 1);
2877 check(42i16, 2);
2878 check(i16::MAX, 2);
2879 check(42i32, 4);
2880 check(i32::MIN, 4);
2881 check(42i64, 8);
2882 check(3.14f32, 4);
2883 check(3.14f64, 8);
2884 check(42u32, 4);
2885 }
2886
2887 #[test]
2890 fn str_10kb_roundtrip() {
2891 let big = "A".repeat(10 * 1024);
2892 let mut buf = Vec::new();
2893 big.as_str().encode_binary(&mut buf);
2894 assert_eq!(buf.len(), 10 * 1024);
2895 assert_eq!(decode_str(&buf).unwrap(), big);
2896 }
2897
2898 #[test]
2901 fn empty_vec_u8_encode_roundtrip() {
2902 let mut buf = Vec::new();
2903 Vec::<u8>::new().encode_binary(&mut buf);
2904 assert!(buf.is_empty(), "empty Vec<u8> should produce no bytes");
2905 assert_eq!(decode_bytes(&buf).len(), 0);
2906 }
2907
2908 #[test]
2911 fn f32_min_max_roundtrip() {
2912 let mut buf = Vec::new();
2913 f32::MIN.encode_binary(&mut buf);
2914 assert_eq!(decode_f32(&buf).unwrap(), f32::MIN);
2915
2916 buf.clear();
2917 f32::MAX.encode_binary(&mut buf);
2918 assert_eq!(decode_f32(&buf).unwrap(), f32::MAX);
2919 }
2920
2921 #[test]
2924 fn f64_min_max_roundtrip() {
2925 let mut buf = Vec::new();
2926 f64::MIN.encode_binary(&mut buf);
2927 assert_eq!(decode_f64(&buf).unwrap(), f64::MIN);
2928
2929 buf.clear();
2930 f64::MAX.encode_binary(&mut buf);
2931 assert_eq!(decode_f64(&buf).unwrap(), f64::MAX);
2932 }
2933
2934 #[test]
2937 fn i32_zero_roundtrip() {
2938 let mut buf = Vec::new();
2939 0i32.encode_binary(&mut buf);
2940 assert_eq!(decode_i32(&buf).unwrap(), 0);
2941 }
2942
2943 #[test]
2946 fn i64_zero_roundtrip() {
2947 let mut buf = Vec::new();
2948 0i64.encode_binary(&mut buf);
2949 assert_eq!(decode_i64(&buf).unwrap(), 0);
2950 }
2951
2952 #[test]
2955 fn i16_zero_roundtrip() {
2956 let mut buf = Vec::new();
2957 0i16.encode_binary(&mut buf);
2958 assert_eq!(decode_i16(&buf).unwrap(), 0);
2959 }
2960
2961 #[test]
2964 fn f32_subnormal_roundtrip() {
2965 let mut buf = Vec::new();
2966 f32::MIN_POSITIVE.encode_binary(&mut buf);
2967 assert_eq!(decode_f32(&buf).unwrap(), f32::MIN_POSITIVE);
2968 }
2969
2970 #[test]
2973 fn f64_subnormal_roundtrip() {
2974 let mut buf = Vec::new();
2975 f64::MIN_POSITIVE.encode_binary(&mut buf);
2976 assert_eq!(decode_f64(&buf).unwrap(), f64::MIN_POSITIVE);
2977 }
2978
2979 #[test]
2982 fn f32_nan_bit_preservation() {
2983 let mut buf = Vec::new();
2984 f32::NAN.encode_binary(&mut buf);
2985 let decoded = decode_f32(&buf).unwrap();
2986 assert!(decoded.is_nan());
2987 assert_eq!(decoded.to_bits(), f32::NAN.to_bits());
2989 }
2990
2991 #[test]
2994 fn f64_nan_bit_preservation() {
2995 let mut buf = Vec::new();
2996 f64::NAN.encode_binary(&mut buf);
2997 let decoded = decode_f64(&buf).unwrap();
2998 assert!(decoded.is_nan());
2999 assert_eq!(decoded.to_bits(), f64::NAN.to_bits());
3000 }
3001
3002 #[test]
3005 fn option_bool_some_roundtrip() {
3006 let val: Option<bool> = Some(true);
3007 assert!(!val.is_null());
3008 assert_eq!(val.type_oid(), 16);
3009 let mut buf = Vec::new();
3010 val.encode_binary(&mut buf);
3011 assert!(decode_bool(&buf).unwrap());
3012 }
3013
3014 #[test]
3015 fn option_bool_none_is_null() {
3016 let val: Option<bool> = None;
3017 assert!(val.is_null());
3018 assert_eq!(val.type_oid(), 0);
3019 let mut buf = Vec::new();
3020 val.encode_binary(&mut buf);
3021 assert!(buf.is_empty());
3022 }
3023
3024 #[test]
3025 fn option_i16_some_roundtrip() {
3026 let val: Option<i16> = Some(i16::MIN);
3027 assert!(!val.is_null());
3028 assert_eq!(val.type_oid(), 21);
3029 let mut buf = Vec::new();
3030 val.encode_binary(&mut buf);
3031 assert_eq!(decode_i16(&buf).unwrap(), i16::MIN);
3032 }
3033
3034 #[test]
3035 fn option_i16_none_is_null() {
3036 let val: Option<i16> = None;
3037 assert!(val.is_null());
3038 let mut buf = Vec::new();
3039 val.encode_binary(&mut buf);
3040 assert!(buf.is_empty());
3041 }
3042
3043 #[test]
3044 fn option_i64_some_roundtrip() {
3045 let val: Option<i64> = Some(i64::MAX);
3046 assert!(!val.is_null());
3047 assert_eq!(val.type_oid(), 20);
3048 let mut buf = Vec::new();
3049 val.encode_binary(&mut buf);
3050 assert_eq!(decode_i64(&buf).unwrap(), i64::MAX);
3051 }
3052
3053 #[test]
3054 fn option_i64_none_is_null() {
3055 let val: Option<i64> = None;
3056 assert!(val.is_null());
3057 let mut buf = Vec::new();
3058 val.encode_binary(&mut buf);
3059 assert!(buf.is_empty());
3060 }
3061
3062 #[test]
3063 fn option_f32_some_roundtrip() {
3064 let val: Option<f32> = Some(f32::INFINITY);
3065 assert!(!val.is_null());
3066 assert_eq!(val.type_oid(), 700);
3067 let mut buf = Vec::new();
3068 val.encode_binary(&mut buf);
3069 assert_eq!(decode_f32(&buf).unwrap(), f32::INFINITY);
3070 }
3071
3072 #[test]
3073 fn option_f32_none_is_null() {
3074 let val: Option<f32> = None;
3075 assert!(val.is_null());
3076 let mut buf = Vec::new();
3077 val.encode_binary(&mut buf);
3078 assert!(buf.is_empty());
3079 }
3080
3081 #[test]
3082 fn option_f64_some_nan_roundtrip() {
3083 let val: Option<f64> = Some(f64::NAN);
3084 assert!(!val.is_null());
3085 assert_eq!(val.type_oid(), 701);
3086 let mut buf = Vec::new();
3087 val.encode_binary(&mut buf);
3088 assert!(decode_f64(&buf).unwrap().is_nan());
3089 }
3090
3091 #[test]
3092 fn option_f64_none_is_null() {
3093 let val: Option<f64> = None;
3094 assert!(val.is_null());
3095 let mut buf = Vec::new();
3096 val.encode_binary(&mut buf);
3097 assert!(buf.is_empty());
3098 }
3099
3100 #[test]
3101 fn option_string_some_roundtrip() {
3102 let val: Option<String> = Some("hello".to_owned());
3103 assert!(!val.is_null());
3104 assert_eq!(val.type_oid(), 25);
3105 let mut buf = Vec::new();
3106 val.encode_binary(&mut buf);
3107 assert_eq!(decode_str(&buf).unwrap(), "hello");
3108 }
3109
3110 #[test]
3111 fn option_string_none_is_null() {
3112 let val: Option<String> = None;
3113 assert!(val.is_null());
3114 let mut buf = Vec::new();
3115 val.encode_binary(&mut buf);
3116 assert!(buf.is_empty());
3117 }
3118
3119 #[test]
3120 fn option_vec_u8_some_roundtrip() {
3121 let val: Option<Vec<u8>> = Some(vec![0xDE, 0xAD]);
3122 assert!(!val.is_null());
3123 assert_eq!(val.type_oid(), 17);
3124 let mut buf = Vec::new();
3125 val.encode_binary(&mut buf);
3126 assert_eq!(decode_bytes(&buf), &[0xDE, 0xAD]);
3127 }
3128
3129 #[test]
3130 fn option_vec_u8_none_is_null() {
3131 let val: Option<Vec<u8>> = None;
3132 assert!(val.is_null());
3133 let mut buf = Vec::new();
3134 val.encode_binary(&mut buf);
3135 assert!(buf.is_empty());
3136 }
3137
3138 #[test]
3141 fn encode_at_vec_u8_same_size() {
3142 let v = vec![1u8, 2, 3];
3143 let mut dst = [0u8; 3];
3144 assert!(v.encode_at(&mut dst));
3145 assert_eq!(dst, [1, 2, 3]);
3146 }
3147
3148 #[test]
3149 fn encode_at_vec_u8_wrong_size() {
3150 let v = vec![1u8, 2, 3];
3151 let mut dst = [0u8; 5];
3152 assert!(!v.encode_at(&mut dst));
3153 }
3154
3155 #[test]
3156 fn encode_at_byte_slice_same_size() {
3157 let data: &[u8] = &[0xAA, 0xBB];
3158 let mut dst = [0u8; 2];
3159 assert!(data.encode_at(&mut dst));
3160 assert_eq!(dst, [0xAA, 0xBB]);
3161 }
3162
3163 #[test]
3164 fn encode_at_byte_slice_wrong_size() {
3165 let data: &[u8] = &[0xAA, 0xBB];
3166 let mut dst = [0u8; 4];
3167 assert!(!data.encode_at(&mut dst));
3168 }
3169
3170 #[test]
3171 fn encode_at_string_same_size() {
3172 let s = String::from("hi");
3173 let mut dst = [0u8; 2];
3174 assert!(s.encode_at(&mut dst));
3175 assert_eq!(&dst, b"hi");
3176 }
3177
3178 #[test]
3179 fn encode_at_string_wrong_size() {
3180 let s = String::from("hi");
3181 let mut dst = [0u8; 5];
3182 assert!(!s.encode_at(&mut dst));
3183 }
3184
3185 #[test]
3188 fn encode_param_null_option() {
3189 let val: Option<i32> = None;
3193 let mut buf = Vec::new();
3194 encode_param(&mut buf, &val);
3195 assert_eq!(buf.len(), 4);
3198 let len = i32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]);
3199 assert_eq!(len, 0);
3200 }
3201
3202 #[test]
3205 fn decode_array_negative_element_count() {
3206 let mut data = Vec::new();
3207 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);
3213 assert!(result.is_err(), "negative element count should error");
3214 assert!(result.unwrap_err().to_string().contains("negative"));
3215 }
3216
3217 #[test]
3220 fn decode_array_excessive_element_count() {
3221 let mut data = Vec::new();
3222 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);
3228 assert!(result.is_err(), "excessive element count should error");
3229 assert!(result.unwrap_err().to_string().contains("exceeds limit"));
3230 }
3231
3232 #[test]
3235 fn decode_array_header_too_short() {
3236 let data = [0u8; 8]; let result = decode_array_i32(&data);
3238 assert!(result.is_err(), "header too short should error");
3239 }
3240
3241 #[test]
3244 fn decode_array_truncated_dimension_header() {
3245 let mut data = Vec::new();
3246 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);
3251 assert!(result.is_err(), "truncated dimension header should error");
3252 }
3253
3254 mod proptest_fuzz {
3255 use super::*;
3256 use proptest::prelude::*;
3257
3258 proptest! {
3259 #[test]
3260 fn i32_roundtrip(val: i32) {
3261 let mut buf = Vec::new();
3262 val.encode_binary(&mut buf);
3263 let decoded = decode_i32(&buf).unwrap();
3264 prop_assert_eq!(decoded, val);
3265 }
3266
3267 #[test]
3268 fn i64_roundtrip(val: i64) {
3269 let mut buf = Vec::new();
3270 val.encode_binary(&mut buf);
3271 let decoded = decode_i64(&buf).unwrap();
3272 prop_assert_eq!(decoded, val);
3273 }
3274
3275 #[test]
3276 fn i16_roundtrip(val: i16) {
3277 let mut buf = Vec::new();
3278 val.encode_binary(&mut buf);
3279 let decoded = decode_i16(&buf).unwrap();
3280 prop_assert_eq!(decoded, val);
3281 }
3282
3283 #[test]
3284 fn f32_roundtrip(val: f32) {
3285 let mut buf = Vec::new();
3286 val.encode_binary(&mut buf);
3287 let decoded = decode_f32(&buf).unwrap();
3288 if val.is_nan() {
3289 prop_assert!(decoded.is_nan());
3290 } else {
3291 prop_assert_eq!(decoded, val);
3292 }
3293 }
3294
3295 #[test]
3296 fn f64_roundtrip(val: f64) {
3297 let mut buf = Vec::new();
3298 val.encode_binary(&mut buf);
3299 let decoded = decode_f64(&buf).unwrap();
3300 if val.is_nan() {
3301 prop_assert!(decoded.is_nan());
3302 } else {
3303 prop_assert_eq!(decoded, val);
3304 }
3305 }
3306
3307 #[test]
3308 fn bool_roundtrip(val: bool) {
3309 let mut buf = Vec::new();
3310 val.encode_binary(&mut buf);
3311 let decoded = decode_bool(&buf).unwrap();
3312 prop_assert_eq!(decoded, val);
3313 }
3314
3315 #[test]
3316 fn str_roundtrip(val in "\\PC*") {
3317 let mut buf = Vec::new();
3318 val.as_str().encode_binary(&mut buf);
3319 let decoded = decode_str(&buf).unwrap();
3320 prop_assert_eq!(decoded, val.as_str());
3321 }
3322
3323 #[test]
3324 fn decode_i32_arbitrary_never_panics(data in proptest::collection::vec(any::<u8>(), 0..16)) {
3325 let _ = decode_i32(&data);
3326 }
3327
3328 #[test]
3329 fn decode_str_arbitrary_never_panics(data in proptest::collection::vec(any::<u8>(), 0..1024)) {
3330 let _ = decode_str(&data);
3331 }
3332 }
3333 }
3334}