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 pg_type_oid() -> u32
57 where
58 Self: Sized,
59 {
60 0
61 }
62
63 fn is_null(&self) -> bool {
68 false
69 }
70
71 fn encode_at(&self, dst: &mut [u8]) -> bool {
81 let mut tmp = Vec::with_capacity(dst.len());
83 self.encode_binary(&mut tmp);
84 if tmp.len() == dst.len() {
85 dst.copy_from_slice(&tmp);
86 true
87 } else {
88 false
89 }
90 }
91}
92
93impl Encode for bool {
96 fn pg_type_oid() -> u32 {
97 16
98 }
99
100 #[inline]
101 fn encode_binary(&self, buf: &mut Vec<u8>) {
102 buf.push(if *self { 1 } else { 0 });
103 }
104
105 #[inline]
106 fn type_oid(&self) -> u32 {
107 16 }
109
110 #[inline]
111 fn encode_at(&self, dst: &mut [u8]) -> bool {
112 if dst.len() != 1 {
113 return false;
114 }
115 dst[0] = if *self { 1 } else { 0 };
116 true
117 }
118}
119
120impl Encode for i16 {
121 fn pg_type_oid() -> u32 {
122 21
123 }
124
125 #[inline]
126 fn encode_binary(&self, buf: &mut Vec<u8>) {
127 buf.extend_from_slice(&self.to_be_bytes());
128 }
129
130 #[inline]
131 fn type_oid(&self) -> u32 {
132 21 }
134
135 #[inline]
136 fn encode_at(&self, dst: &mut [u8]) -> bool {
137 if dst.len() != 2 {
138 return false;
139 }
140 dst.copy_from_slice(&self.to_be_bytes());
141 true
142 }
143}
144
145impl Encode for i32 {
146 fn pg_type_oid() -> u32 {
147 23
148 }
149
150 #[inline]
151 fn encode_binary(&self, buf: &mut Vec<u8>) {
152 buf.extend_from_slice(&self.to_be_bytes());
153 }
154
155 #[inline]
156 fn type_oid(&self) -> u32 {
157 23 }
159
160 #[inline]
161 fn encode_at(&self, dst: &mut [u8]) -> bool {
162 if dst.len() != 4 {
163 return false;
164 }
165 dst.copy_from_slice(&self.to_be_bytes());
166 true
167 }
168}
169
170impl Encode for i64 {
171 fn pg_type_oid() -> u32 {
172 20
173 }
174
175 #[inline]
176 fn encode_binary(&self, buf: &mut Vec<u8>) {
177 buf.extend_from_slice(&self.to_be_bytes());
178 }
179
180 #[inline]
181 fn type_oid(&self) -> u32 {
182 20 }
184
185 #[inline]
186 fn encode_at(&self, dst: &mut [u8]) -> bool {
187 if dst.len() != 8 {
188 return false;
189 }
190 dst.copy_from_slice(&self.to_be_bytes());
191 true
192 }
193}
194
195impl Encode for f32 {
196 fn pg_type_oid() -> u32 {
197 700
198 }
199
200 #[inline]
201 fn encode_binary(&self, buf: &mut Vec<u8>) {
202 buf.extend_from_slice(&self.to_be_bytes());
203 }
204
205 #[inline]
206 fn type_oid(&self) -> u32 {
207 700 }
209
210 #[inline]
211 fn encode_at(&self, dst: &mut [u8]) -> bool {
212 if dst.len() != 4 {
213 return false;
214 }
215 dst.copy_from_slice(&self.to_be_bytes());
216 true
217 }
218}
219
220impl Encode for f64 {
221 fn pg_type_oid() -> u32 {
222 701
223 }
224
225 #[inline]
226 fn encode_binary(&self, buf: &mut Vec<u8>) {
227 buf.extend_from_slice(&self.to_be_bytes());
228 }
229
230 #[inline]
231 fn type_oid(&self) -> u32 {
232 701 }
234
235 #[inline]
236 fn encode_at(&self, dst: &mut [u8]) -> bool {
237 if dst.len() != 8 {
238 return false;
239 }
240 dst.copy_from_slice(&self.to_be_bytes());
241 true
242 }
243}
244
245impl Encode for &str {
246 fn pg_type_oid() -> u32 {
247 25
248 }
249
250 #[inline]
251 fn encode_binary(&self, buf: &mut Vec<u8>) {
252 buf.extend_from_slice(self.as_bytes());
253 }
254
255 #[inline]
256 fn type_oid(&self) -> u32 {
257 25 }
259
260 #[inline]
261 fn encode_at(&self, dst: &mut [u8]) -> bool {
262 let bytes = self.as_bytes();
263 if bytes.len() != dst.len() {
264 return false;
265 }
266 dst.copy_from_slice(bytes);
267 true
268 }
269}
270
271impl Encode for String {
272 fn pg_type_oid() -> u32 {
273 25
274 }
275
276 #[inline]
277 fn encode_binary(&self, buf: &mut Vec<u8>) {
278 buf.extend_from_slice(self.as_bytes());
279 }
280
281 #[inline]
282 fn type_oid(&self) -> u32 {
283 25 }
285
286 #[inline]
287 fn encode_at(&self, dst: &mut [u8]) -> bool {
288 self.as_str().encode_at(dst)
289 }
290}
291
292impl Encode for &[u8] {
293 fn pg_type_oid() -> u32 {
294 17
295 }
296
297 #[inline]
298 fn encode_binary(&self, buf: &mut Vec<u8>) {
299 buf.extend_from_slice(self);
300 }
301
302 #[inline]
303 fn type_oid(&self) -> u32 {
304 17 }
306
307 #[inline]
308 fn encode_at(&self, dst: &mut [u8]) -> bool {
309 if self.len() != dst.len() {
310 return false;
311 }
312 dst.copy_from_slice(self);
313 true
314 }
315}
316
317impl Encode for Vec<u8> {
318 fn pg_type_oid() -> u32 {
319 17
320 }
321
322 #[inline]
323 fn encode_binary(&self, buf: &mut Vec<u8>) {
324 buf.extend_from_slice(self);
325 }
326
327 #[inline]
328 fn type_oid(&self) -> u32 {
329 17 }
331
332 #[inline]
333 fn encode_at(&self, dst: &mut [u8]) -> bool {
334 if self.len() != dst.len() {
335 return false;
336 }
337 dst.copy_from_slice(self);
338 true
339 }
340}
341
342impl Encode for u32 {
343 fn pg_type_oid() -> u32 {
344 26
345 }
346
347 #[inline]
348 fn encode_binary(&self, buf: &mut Vec<u8>) {
349 buf.extend_from_slice(&self.to_be_bytes());
350 }
351
352 #[inline]
353 fn type_oid(&self) -> u32 {
354 26 }
356
357 #[inline]
358 fn encode_at(&self, dst: &mut [u8]) -> bool {
359 if dst.len() != 4 {
360 return false;
361 }
362 dst.copy_from_slice(&self.to_be_bytes());
363 true
364 }
365}
366
367impl<T: Encode> Encode for Option<T> {
370 fn pg_type_oid() -> u32 {
371 T::pg_type_oid()
372 }
373
374 #[inline]
375 fn encode_binary(&self, buf: &mut Vec<u8>) {
376 if let Some(val) = self {
377 val.encode_binary(buf);
378 }
379 }
382
383 #[inline]
384 fn type_oid(&self) -> u32 {
385 match self {
386 Some(val) => val.type_oid(),
387 None => T::pg_type_oid(),
388 }
389 }
390
391 #[inline]
392 fn is_null(&self) -> bool {
393 self.is_none()
394 }
395}
396
397#[cfg(feature = "uuid")]
400impl Encode for uuid::Uuid {
401 fn pg_type_oid() -> u32 {
402 2950
403 }
404
405 #[inline]
406 fn encode_binary(&self, buf: &mut Vec<u8>) {
407 buf.extend_from_slice(self.as_bytes());
408 }
409
410 #[inline]
411 fn type_oid(&self) -> u32 {
412 2950 }
414
415 #[inline]
416 fn encode_at(&self, dst: &mut [u8]) -> bool {
417 if dst.len() != 16 {
418 return false;
419 }
420 dst.copy_from_slice(self.as_bytes());
421 true
422 }
423}
424
425#[cfg(feature = "time")]
426impl Encode for time::OffsetDateTime {
427 fn pg_type_oid() -> u32 {
428 1184
429 }
430
431 #[inline]
432 fn encode_binary(&self, buf: &mut Vec<u8>) {
433 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
434 }
435
436 #[inline]
437 fn type_oid(&self) -> u32 {
438 1184 }
440
441 #[inline]
442 fn encode_at(&self, dst: &mut [u8]) -> bool {
443 if dst.len() != 8 {
444 return false;
445 }
446 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
447 true
448 }
449}
450
451#[cfg(feature = "time")]
452trait OffsetDateTimeExt {
453 fn encode_pg_micros(&self) -> i64;
454}
455
456#[cfg(feature = "time")]
457impl OffsetDateTimeExt for time::OffsetDateTime {
458 #[inline]
459 fn encode_pg_micros(&self) -> i64 {
460 let unix_nanos = self.unix_timestamp_nanos();
463 let unix_micros = (unix_nanos / 1000) as i64;
464 unix_micros.saturating_sub(PG_EPOCH_UNIX_MICROS)
465 }
466}
467
468#[cfg(feature = "time")]
469impl Encode for time::Date {
470 fn pg_type_oid() -> u32 {
471 1082
472 }
473
474 #[inline]
475 fn encode_binary(&self, buf: &mut Vec<u8>) {
476 buf.extend_from_slice(&self.encode_pg_days().to_be_bytes());
477 }
478
479 #[inline]
480 fn type_oid(&self) -> u32 {
481 1082 }
483
484 #[inline]
485 fn encode_at(&self, dst: &mut [u8]) -> bool {
486 if dst.len() != 4 {
487 return false;
488 }
489 dst.copy_from_slice(&self.encode_pg_days().to_be_bytes());
490 true
491 }
492}
493
494#[cfg(feature = "time")]
495trait DateExt {
496 fn encode_pg_days(&self) -> i32;
497}
498
499#[cfg(feature = "time")]
500impl DateExt for time::Date {
501 #[inline]
502 fn encode_pg_days(&self) -> i32 {
503 self.to_julian_day() - PG_EPOCH_JULIAN_DAY
506 }
507}
508
509#[cfg(feature = "time")]
510impl Encode for time::Time {
511 fn pg_type_oid() -> u32 {
512 1083
513 }
514
515 #[inline]
516 fn encode_binary(&self, buf: &mut Vec<u8>) {
517 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
518 }
519
520 #[inline]
521 fn type_oid(&self) -> u32 {
522 1083 }
524
525 #[inline]
526 fn encode_at(&self, dst: &mut [u8]) -> bool {
527 if dst.len() != 8 {
528 return false;
529 }
530 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
531 true
532 }
533}
534
535#[cfg(feature = "time")]
536trait TimeExt {
537 fn encode_pg_micros(&self) -> i64;
538}
539
540#[cfg(feature = "time")]
541impl TimeExt for time::Time {
542 #[inline]
543 fn encode_pg_micros(&self) -> i64 {
544 let midnight = time::Time::MIDNIGHT;
546 let diff = *self - midnight;
547 diff.whole_microseconds() as i64
548 }
549}
550
551#[cfg(feature = "time")]
552impl Encode for time::PrimitiveDateTime {
553 fn pg_type_oid() -> u32 {
554 1114
555 }
556
557 #[inline]
558 fn encode_binary(&self, buf: &mut Vec<u8>) {
559 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
560 }
561
562 #[inline]
563 fn type_oid(&self) -> u32 {
564 1114 }
566
567 #[inline]
568 fn encode_at(&self, dst: &mut [u8]) -> bool {
569 if dst.len() != 8 {
570 return false;
571 }
572 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
573 true
574 }
575}
576
577#[cfg(feature = "time")]
578trait PrimitiveDateTimeExt {
579 fn encode_pg_micros(&self) -> i64;
580}
581
582#[cfg(feature = "time")]
583impl PrimitiveDateTimeExt for time::PrimitiveDateTime {
584 #[inline]
585 fn encode_pg_micros(&self) -> i64 {
586 let unix_nanos = self.assume_utc().unix_timestamp_nanos();
590 let unix_micros = (unix_nanos / 1000) as i64;
591 unix_micros.saturating_sub(PG_EPOCH_UNIX_MICROS)
592 }
593}
594
595#[cfg(feature = "chrono")]
596impl Encode for chrono::NaiveDateTime {
597 fn pg_type_oid() -> u32 {
598 1114
599 }
600
601 #[inline]
602 fn encode_binary(&self, buf: &mut Vec<u8>) {
603 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
604 }
605
606 #[inline]
607 fn type_oid(&self) -> u32 {
608 1114 }
610
611 #[inline]
612 fn encode_at(&self, dst: &mut [u8]) -> bool {
613 if dst.len() != 8 {
614 return false;
615 }
616 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
617 true
618 }
619}
620
621#[cfg(feature = "chrono")]
622trait NaiveDateTimeExt {
623 fn encode_pg_micros(&self) -> i64;
624}
625
626#[cfg(feature = "chrono")]
627impl NaiveDateTimeExt for chrono::NaiveDateTime {
628 #[inline]
629 fn encode_pg_micros(&self) -> i64 {
630 let unix_micros = self.and_utc().timestamp_micros();
632 unix_micros.saturating_sub(PG_EPOCH_UNIX_MICROS)
633 }
634}
635
636#[cfg(feature = "chrono")]
637impl Encode for chrono::DateTime<chrono::Utc> {
638 fn pg_type_oid() -> u32 {
639 1184
640 }
641
642 #[inline]
643 fn encode_binary(&self, buf: &mut Vec<u8>) {
644 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
645 }
646
647 #[inline]
648 fn type_oid(&self) -> u32 {
649 1184 }
651
652 #[inline]
653 fn encode_at(&self, dst: &mut [u8]) -> bool {
654 if dst.len() != 8 {
655 return false;
656 }
657 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
658 true
659 }
660}
661
662#[cfg(feature = "chrono")]
663trait ChronoDateTimeUtcExt {
664 fn encode_pg_micros(&self) -> i64;
665}
666
667#[cfg(feature = "chrono")]
668impl ChronoDateTimeUtcExt for chrono::DateTime<chrono::Utc> {
669 #[inline]
670 fn encode_pg_micros(&self) -> i64 {
671 let unix_micros = self.timestamp_micros();
673 unix_micros.saturating_sub(PG_EPOCH_UNIX_MICROS)
674 }
675}
676
677#[cfg(feature = "chrono")]
678impl Encode for chrono::NaiveDate {
679 fn pg_type_oid() -> u32 {
680 1082
681 }
682
683 #[inline]
684 fn encode_binary(&self, buf: &mut Vec<u8>) {
685 buf.extend_from_slice(&self.encode_pg_days().to_be_bytes());
686 }
687
688 #[inline]
689 fn type_oid(&self) -> u32 {
690 1082 }
692
693 #[inline]
694 fn encode_at(&self, dst: &mut [u8]) -> bool {
695 if dst.len() != 4 {
696 return false;
697 }
698 dst.copy_from_slice(&self.encode_pg_days().to_be_bytes());
699 true
700 }
701}
702
703#[cfg(feature = "chrono")]
704trait ChronoNaiveDateExt {
705 fn encode_pg_days(&self) -> i32;
706}
707
708#[cfg(feature = "chrono")]
709impl ChronoNaiveDateExt for chrono::NaiveDate {
710 #[inline]
711 fn encode_pg_days(&self) -> i32 {
712 const PG_EPOCH_CE_DAYS: i32 = 730_120;
716 let days_i64 = (self.num_days_from_ce() - PG_EPOCH_CE_DAYS) as i64;
717 i32::try_from(days_i64).unwrap_or(if days_i64 < 0 { i32::MIN } else { i32::MAX })
718 }
719}
720
721#[cfg(feature = "chrono")]
722impl Encode for chrono::NaiveTime {
723 fn pg_type_oid() -> u32 {
724 1083
725 }
726
727 #[inline]
728 fn encode_binary(&self, buf: &mut Vec<u8>) {
729 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
730 }
731
732 #[inline]
733 fn type_oid(&self) -> u32 {
734 1083 }
736
737 #[inline]
738 fn encode_at(&self, dst: &mut [u8]) -> bool {
739 if dst.len() != 8 {
740 return false;
741 }
742 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
743 true
744 }
745}
746
747#[cfg(feature = "chrono")]
748trait ChronoNaiveTimeExt {
749 fn encode_pg_micros(&self) -> i64;
750}
751
752#[cfg(feature = "chrono")]
753impl ChronoNaiveTimeExt for chrono::NaiveTime {
754 #[inline]
755 fn encode_pg_micros(&self) -> i64 {
756 let secs = self.num_seconds_from_midnight() as i64;
758 let nanos = self.nanosecond() % 1_000_000_000; let micros_in_sec = (nanos / 1000) as i64;
760 secs * 1_000_000 + micros_in_sec
761 }
762}
763
764#[cfg(feature = "decimal")]
765impl Encode for rust_decimal::Decimal {
766 fn pg_type_oid() -> u32 {
767 1700
768 }
769
770 fn encode_binary(&self, buf: &mut Vec<u8>) {
771 if self.is_zero() {
781 let dscale = i16::try_from(self.scale()).unwrap_or(i16::MAX);
783 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;
788 }
789
790 let sign: i16 = if self.is_sign_negative() {
791 0x4000
792 } else {
793 0x0000
794 };
795 let scale = self.scale();
796
797 let abs = self.abs();
799 let mut mantissa = abs.mantissa().unsigned_abs();
800
801 let mut decimal_digits: smallvec::SmallVec<[i16; 32]> = smallvec::SmallVec::new();
803 while mantissa > 0 {
804 decimal_digits.push((mantissa % 10) as i16);
805 mantissa /= 10;
806 }
807 decimal_digits.reverse();
808
809 let total_digits = decimal_digits.len();
813 let scale_usize = scale as usize;
814 let int_len = total_digits.saturating_sub(scale_usize);
815 let sig_frac_len = total_digits - int_len; let mut padded: smallvec::SmallVec<[i16; 32]> = smallvec::SmallVec::new();
820
821 let int_pad = if int_len > 0 {
823 (4 - (int_len % 4)) % 4
824 } else {
825 0
826 };
827 padded.extend(std::iter::repeat(0i16).take(int_pad));
828 padded.extend_from_slice(&decimal_digits[..int_len]);
829
830 let implicit_zeros = scale_usize.saturating_sub(sig_frac_len);
834 padded.extend(std::iter::repeat(0i16).take(implicit_zeros));
835 padded.extend_from_slice(&decimal_digits[int_len..]);
836 let frac_total = implicit_zeros + sig_frac_len; let frac_pad = (4 - (frac_total % 4)) % 4;
838 padded.extend(std::iter::repeat(0i16).take(frac_pad));
839
840 let mut pg_digits: smallvec::SmallVec<[i16; 12]> = smallvec::SmallVec::new();
842 for chunk in padded.chunks(4) {
843 let d = chunk[0] * 1000 + chunk[1] * 100 + chunk[2] * 10 + chunk[3];
844 pg_digits.push(d);
845 }
846
847 let int_groups = if int_len > 0 {
849 (int_len + int_pad) / 4
850 } else {
851 0
852 };
853
854 let mut leading_frac_zeros = 0usize;
856 for i in int_groups..pg_digits.len() {
857 if pg_digits[i] == 0 {
858 leading_frac_zeros += 1;
859 } else {
860 break;
861 }
862 }
863
864 while pg_digits.len() > int_groups + leading_frac_zeros
866 && pg_digits.last().copied() == Some(0)
867 {
868 pg_digits.pop();
869 }
870
871 if leading_frac_zeros > 0 {
873 pg_digits.drain(int_groups..int_groups + leading_frac_zeros);
874 }
875
876 let ndigits = pg_digits.len() as i16;
877
878 let weight: i16 = if int_groups > 0 {
880 let w = (int_groups - 1) as i32;
881 w.clamp(i16::MIN as i32, i16::MAX as i32) as i16
882 } else {
883 let w = -(leading_frac_zeros as i32 + 1);
885 w.clamp(i16::MIN as i32, i16::MAX as i32) as i16
886 };
887
888 let dscale = i16::try_from(scale).unwrap_or(i16::MAX);
889 buf.extend_from_slice(&ndigits.to_be_bytes());
890 buf.extend_from_slice(&weight.to_be_bytes());
891 buf.extend_from_slice(&sign.to_be_bytes());
892 buf.extend_from_slice(&dscale.to_be_bytes());
893 for d in &pg_digits {
894 buf.extend_from_slice(&d.to_be_bytes());
895 }
896 }
897
898 #[inline]
899 fn type_oid(&self) -> u32 {
900 1700 }
902}
903
904#[inline]
912pub fn decode_bool(data: &[u8]) -> Result<bool, DriverError> {
913 if data.len() != 1 {
914 return Err(DriverError::Protocol(format!(
915 "bool: expected 1 byte, got {}",
916 data.len()
917 )));
918 }
919 Ok(data[0] != 0)
920}
921
922#[inline]
924pub fn decode_i16(data: &[u8]) -> Result<i16, DriverError> {
925 if data.len() != 2 {
926 return Err(DriverError::Protocol(format!(
927 "i16: expected 2 bytes, got {}",
928 data.len()
929 )));
930 }
931 Ok(i16::from_be_bytes([data[0], data[1]]))
932}
933
934#[inline]
936pub fn decode_i32(data: &[u8]) -> Result<i32, DriverError> {
937 if data.len() != 4 {
938 return Err(DriverError::Protocol(format!(
939 "i32: expected 4 bytes, got {}",
940 data.len()
941 )));
942 }
943 Ok(i32::from_be_bytes([data[0], data[1], data[2], data[3]]))
944}
945
946#[inline]
948pub fn decode_i64(data: &[u8]) -> Result<i64, DriverError> {
949 if data.len() != 8 {
950 return Err(DriverError::Protocol(format!(
951 "i64: expected 8 bytes, got {}",
952 data.len()
953 )));
954 }
955 Ok(i64::from_be_bytes([
956 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
957 ]))
958}
959
960#[inline]
962pub fn decode_f32(data: &[u8]) -> Result<f32, DriverError> {
963 if data.len() != 4 {
964 return Err(DriverError::Protocol(format!(
965 "f32: expected 4 bytes, got {}",
966 data.len()
967 )));
968 }
969 Ok(f32::from_be_bytes([data[0], data[1], data[2], data[3]]))
970}
971
972#[inline]
974pub fn decode_f64(data: &[u8]) -> Result<f64, DriverError> {
975 if data.len() != 8 {
976 return Err(DriverError::Protocol(format!(
977 "f64: expected 8 bytes, got {}",
978 data.len()
979 )));
980 }
981 Ok(f64::from_be_bytes([
982 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
983 ]))
984}
985
986#[inline]
992pub fn decode_str(data: &[u8]) -> Result<&str, DriverError> {
993 simdutf8::basic::from_utf8(data)
994 .map_err(|e| DriverError::Protocol(format!("invalid UTF-8 in text column: {e}")))
995}
996
997#[inline]
999pub fn decode_bytes(data: &[u8]) -> &[u8] {
1000 data
1001}
1002
1003#[inline]
1005pub fn decode_uuid(data: &[u8]) -> Result<[u8; 16], DriverError> {
1006 if data.len() != 16 {
1007 return Err(DriverError::Protocol(format!(
1008 "uuid: expected 16 bytes, got {}",
1009 data.len()
1010 )));
1011 }
1012 let mut uuid = [0u8; 16];
1013 uuid.copy_from_slice(data);
1014 Ok(uuid)
1015}
1016
1017pub fn encode_param(buf: &mut Vec<u8>, param: &dyn Encode) {
1021 let start = buf.len();
1022 buf.extend_from_slice(&[0u8; 4]); param.encode_binary(buf);
1024 let data_len = (buf.len() - start - 4) as i32;
1025 buf[start..start + 4].copy_from_slice(&data_len.to_be_bytes());
1026}
1027
1028fn encode_array_header(buf: &mut Vec<u8>, n_elements: usize, elem_oid: u32) {
1035 if n_elements == 0 {
1036 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;
1040 }
1041 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()); }
1047
1048impl Encode for [bool] {
1051 fn encode_binary(&self, buf: &mut Vec<u8>) {
1052 encode_array_header(buf, self.len(), 16);
1053 buf.reserve(self.len() * 5);
1055 for val in self {
1056 let tmp = [0u8, 0, 0, 1, if *val { 1 } else { 0 }];
1057 buf.extend_from_slice(&tmp);
1058 }
1059 }
1060
1061 #[inline]
1062 fn type_oid(&self) -> u32 {
1063 1000 }
1065}
1066
1067impl Encode for &[bool] {
1068 fn pg_type_oid() -> u32 {
1069 1000
1070 }
1071
1072 #[inline]
1073 fn encode_binary(&self, buf: &mut Vec<u8>) {
1074 (**self).encode_binary(buf);
1075 }
1076
1077 #[inline]
1078 fn type_oid(&self) -> u32 {
1079 1000
1080 }
1081}
1082
1083impl Encode for Vec<bool> {
1084 fn pg_type_oid() -> u32 {
1085 1000
1086 }
1087 #[inline]
1088 fn encode_binary(&self, buf: &mut Vec<u8>) {
1089 self.as_slice().encode_binary(buf);
1090 }
1091
1092 #[inline]
1093 fn type_oid(&self) -> u32 {
1094 1000
1095 }
1096}
1097
1098impl Encode for [i16] {
1099 fn encode_binary(&self, buf: &mut Vec<u8>) {
1100 encode_array_header(buf, self.len(), 21);
1101 buf.reserve(self.len() * 6);
1103 for val in self {
1104 let mut tmp = [0u8; 6];
1105 tmp[0..4].copy_from_slice(&2i32.to_be_bytes());
1106 tmp[4..6].copy_from_slice(&val.to_be_bytes());
1107 buf.extend_from_slice(&tmp);
1108 }
1109 }
1110
1111 #[inline]
1112 fn type_oid(&self) -> u32 {
1113 1005 }
1115}
1116
1117impl Encode for &[i16] {
1118 fn pg_type_oid() -> u32 {
1119 1005
1120 }
1121
1122 #[inline]
1123 fn encode_binary(&self, buf: &mut Vec<u8>) {
1124 (**self).encode_binary(buf);
1125 }
1126
1127 #[inline]
1128 fn type_oid(&self) -> u32 {
1129 1005
1130 }
1131}
1132
1133impl Encode for Vec<i16> {
1134 fn pg_type_oid() -> u32 {
1135 1005
1136 }
1137 #[inline]
1138 fn encode_binary(&self, buf: &mut Vec<u8>) {
1139 self.as_slice().encode_binary(buf);
1140 }
1141
1142 #[inline]
1143 fn type_oid(&self) -> u32 {
1144 1005
1145 }
1146}
1147
1148impl Encode for [i32] {
1149 fn encode_binary(&self, buf: &mut Vec<u8>) {
1150 encode_array_header(buf, self.len(), 23);
1151 buf.reserve(self.len() * 8);
1153 for val in self {
1154 let mut tmp = [0u8; 8];
1155 tmp[0..4].copy_from_slice(&4i32.to_be_bytes());
1156 tmp[4..8].copy_from_slice(&val.to_be_bytes());
1157 buf.extend_from_slice(&tmp);
1158 }
1159 }
1160
1161 #[inline]
1162 fn type_oid(&self) -> u32 {
1163 1007 }
1165}
1166
1167impl Encode for &[i32] {
1168 fn pg_type_oid() -> u32 {
1169 1007
1170 }
1171
1172 #[inline]
1173 fn encode_binary(&self, buf: &mut Vec<u8>) {
1174 (**self).encode_binary(buf);
1175 }
1176
1177 #[inline]
1178 fn type_oid(&self) -> u32 {
1179 1007
1180 }
1181}
1182
1183impl Encode for Vec<i32> {
1184 fn pg_type_oid() -> u32 {
1185 1007
1186 }
1187 #[inline]
1188 fn encode_binary(&self, buf: &mut Vec<u8>) {
1189 self.as_slice().encode_binary(buf);
1190 }
1191
1192 #[inline]
1193 fn type_oid(&self) -> u32 {
1194 1007
1195 }
1196}
1197
1198impl Encode for [i64] {
1199 fn encode_binary(&self, buf: &mut Vec<u8>) {
1200 encode_array_header(buf, self.len(), 20);
1201 buf.reserve(self.len() * 12);
1203 for val in self {
1204 let mut tmp = [0u8; 12];
1205 tmp[0..4].copy_from_slice(&8i32.to_be_bytes());
1206 tmp[4..12].copy_from_slice(&val.to_be_bytes());
1207 buf.extend_from_slice(&tmp);
1208 }
1209 }
1210
1211 #[inline]
1212 fn type_oid(&self) -> u32 {
1213 1016 }
1215}
1216
1217impl Encode for &[i64] {
1218 fn pg_type_oid() -> u32 {
1219 1016
1220 }
1221
1222 #[inline]
1223 fn encode_binary(&self, buf: &mut Vec<u8>) {
1224 (**self).encode_binary(buf);
1225 }
1226
1227 #[inline]
1228 fn type_oid(&self) -> u32 {
1229 1016
1230 }
1231}
1232
1233impl Encode for Vec<i64> {
1234 fn pg_type_oid() -> u32 {
1235 1016
1236 }
1237 #[inline]
1238 fn encode_binary(&self, buf: &mut Vec<u8>) {
1239 self.as_slice().encode_binary(buf);
1240 }
1241
1242 #[inline]
1243 fn type_oid(&self) -> u32 {
1244 1016
1245 }
1246}
1247
1248impl Encode for [f32] {
1249 fn encode_binary(&self, buf: &mut Vec<u8>) {
1250 encode_array_header(buf, self.len(), 700);
1251 buf.reserve(self.len() * 8);
1253 for val in self {
1254 let mut tmp = [0u8; 8];
1255 tmp[0..4].copy_from_slice(&4i32.to_be_bytes());
1256 tmp[4..8].copy_from_slice(&val.to_be_bytes());
1257 buf.extend_from_slice(&tmp);
1258 }
1259 }
1260
1261 #[inline]
1262 fn type_oid(&self) -> u32 {
1263 1021 }
1265}
1266
1267impl Encode for &[f32] {
1268 fn pg_type_oid() -> u32 {
1269 1021
1270 }
1271
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 1021
1280 }
1281}
1282
1283impl Encode for Vec<f32> {
1284 fn pg_type_oid() -> u32 {
1285 1021
1286 }
1287 #[inline]
1288 fn encode_binary(&self, buf: &mut Vec<u8>) {
1289 self.as_slice().encode_binary(buf);
1290 }
1291
1292 #[inline]
1293 fn type_oid(&self) -> u32 {
1294 1021
1295 }
1296}
1297
1298impl Encode for [f64] {
1299 fn encode_binary(&self, buf: &mut Vec<u8>) {
1300 encode_array_header(buf, self.len(), 701);
1301 buf.reserve(self.len() * 12);
1303 for val in self {
1304 let mut tmp = [0u8; 12];
1305 tmp[0..4].copy_from_slice(&8i32.to_be_bytes());
1306 tmp[4..12].copy_from_slice(&val.to_be_bytes());
1307 buf.extend_from_slice(&tmp);
1308 }
1309 }
1310
1311 #[inline]
1312 fn type_oid(&self) -> u32 {
1313 1022 }
1315}
1316
1317impl Encode for &[f64] {
1318 fn pg_type_oid() -> u32 {
1319 1022
1320 }
1321
1322 #[inline]
1323 fn encode_binary(&self, buf: &mut Vec<u8>) {
1324 (**self).encode_binary(buf);
1325 }
1326
1327 #[inline]
1328 fn type_oid(&self) -> u32 {
1329 1022
1330 }
1331}
1332
1333impl Encode for Vec<f64> {
1334 fn pg_type_oid() -> u32 {
1335 1022
1336 }
1337 #[inline]
1338 fn encode_binary(&self, buf: &mut Vec<u8>) {
1339 self.as_slice().encode_binary(buf);
1340 }
1341
1342 #[inline]
1343 fn type_oid(&self) -> u32 {
1344 1022
1345 }
1346}
1347
1348impl Encode for [&str] {
1349 fn encode_binary(&self, buf: &mut Vec<u8>) {
1350 encode_array_header(buf, self.len(), 25);
1351 for val in self {
1352 let bytes = val.as_bytes();
1353 buf.extend_from_slice(&(bytes.len() as i32).to_be_bytes());
1354 buf.extend_from_slice(bytes);
1355 }
1356 }
1357
1358 #[inline]
1359 fn type_oid(&self) -> u32 {
1360 1009 }
1362}
1363
1364impl Encode for &[&str] {
1365 fn pg_type_oid() -> u32 {
1366 1009
1367 }
1368
1369 #[inline]
1370 fn encode_binary(&self, buf: &mut Vec<u8>) {
1371 (**self).encode_binary(buf);
1372 }
1373
1374 #[inline]
1375 fn type_oid(&self) -> u32 {
1376 1009
1377 }
1378}
1379
1380impl Encode for Vec<String> {
1381 fn pg_type_oid() -> u32 {
1382 1009
1383 }
1384 fn encode_binary(&self, buf: &mut Vec<u8>) {
1385 encode_array_header(buf, self.len(), 25);
1386 for val in self {
1387 let bytes = val.as_bytes();
1388 buf.extend_from_slice(&(bytes.len() as i32).to_be_bytes());
1389 buf.extend_from_slice(bytes);
1390 }
1391 }
1392
1393 #[inline]
1394 fn type_oid(&self) -> u32 {
1395 1009 }
1397}
1398
1399impl Encode for [String] {
1400 fn encode_binary(&self, buf: &mut Vec<u8>) {
1401 encode_array_header(buf, self.len(), 25); for val in self {
1403 let bytes = val.as_bytes();
1404 buf.extend_from_slice(&(bytes.len() as i32).to_be_bytes());
1405 buf.extend_from_slice(bytes);
1406 }
1407 }
1408
1409 #[inline]
1410 fn type_oid(&self) -> u32 {
1411 1009
1412 }
1413}
1414
1415impl Encode for &[String] {
1416 fn pg_type_oid() -> u32 {
1417 1009
1418 }
1419
1420 #[inline]
1421 fn encode_binary(&self, buf: &mut Vec<u8>) {
1422 (**self).encode_binary(buf);
1423 }
1424
1425 #[inline]
1426 fn type_oid(&self) -> u32 {
1427 1009
1428 }
1429}
1430
1431impl Encode for [&[u8]] {
1432 fn encode_binary(&self, buf: &mut Vec<u8>) {
1433 encode_array_header(buf, self.len(), 17);
1434 for val in self {
1435 buf.extend_from_slice(&(val.len() as i32).to_be_bytes());
1436 buf.extend_from_slice(val);
1437 }
1438 }
1439
1440 #[inline]
1441 fn type_oid(&self) -> u32 {
1442 1001 }
1444}
1445
1446impl Encode for &[&[u8]] {
1447 fn pg_type_oid() -> u32 {
1448 1001
1449 }
1450
1451 #[inline]
1452 fn encode_binary(&self, buf: &mut Vec<u8>) {
1453 (**self).encode_binary(buf);
1454 }
1455
1456 #[inline]
1457 fn type_oid(&self) -> u32 {
1458 1001
1459 }
1460}
1461
1462impl Encode for [Vec<u8>] {
1463 fn encode_binary(&self, buf: &mut Vec<u8>) {
1464 encode_array_header(buf, self.len(), 17);
1465 for val in self {
1466 buf.extend_from_slice(&(val.len() as i32).to_be_bytes());
1467 buf.extend_from_slice(val);
1468 }
1469 }
1470
1471 #[inline]
1472 fn type_oid(&self) -> u32 {
1473 1001 }
1475}
1476
1477impl Encode for &[Vec<u8>] {
1478 fn pg_type_oid() -> u32 {
1479 1001
1480 }
1481
1482 #[inline]
1483 fn encode_binary(&self, buf: &mut Vec<u8>) {
1484 (**self).encode_binary(buf);
1485 }
1486
1487 #[inline]
1488 fn type_oid(&self) -> u32 {
1489 1001
1490 }
1491}
1492
1493impl Encode for Vec<Vec<u8>> {
1494 fn pg_type_oid() -> u32 {
1495 1001
1496 }
1497 #[inline]
1498 fn encode_binary(&self, buf: &mut Vec<u8>) {
1499 self.as_slice().encode_binary(buf);
1500 }
1501
1502 #[inline]
1503 fn type_oid(&self) -> u32 {
1504 1001 }
1506}
1507
1508fn decode_array_elements(data: &[u8]) -> Result<Vec<&[u8]>, DriverError> {
1519 if data.len() < 12 {
1520 return Err(DriverError::Protocol(format!(
1521 "array: expected >= 12 bytes header, got {}",
1522 data.len()
1523 )));
1524 }
1525 let ndim = i32::from_be_bytes([data[0], data[1], data[2], data[3]]);
1526 if ndim == 0 {
1527 return Ok(Vec::new());
1528 }
1529 if ndim != 1 {
1530 return Err(DriverError::Protocol(format!(
1531 "array: only 1-dimensional arrays supported, got {ndim}"
1532 )));
1533 }
1534 if data.len() < 20 {
1536 return Err(DriverError::Protocol(
1537 "array: truncated dimension header".into(),
1538 ));
1539 }
1540 let n_elements_raw = i32::from_be_bytes([data[12], data[13], data[14], data[15]]);
1541 if n_elements_raw < 0 {
1542 return Err(DriverError::Protocol(
1543 "array: negative element count".into(),
1544 ));
1545 }
1546 let n_elements = n_elements_raw as usize;
1547 const MAX_ARRAY_ELEMENTS: usize = 10_000_000;
1551 if n_elements > MAX_ARRAY_ELEMENTS {
1552 return Err(DriverError::Protocol(format!(
1553 "array element count {n_elements} exceeds limit of {MAX_ARRAY_ELEMENTS}"
1554 )));
1555 }
1556 let mut pos = 20;
1558 let mut elements = Vec::with_capacity(n_elements);
1559 for _ in 0..n_elements {
1560 if pos + 4 > data.len() {
1561 return Err(DriverError::Protocol("array: truncated element".into()));
1562 }
1563 let elem_len = i32::from_be_bytes([data[pos], data[pos + 1], data[pos + 2], data[pos + 3]]);
1564 pos += 4;
1565 if elem_len < 0 {
1566 continue;
1568 }
1569 let elem_len = elem_len as usize;
1570 if pos + elem_len > data.len() {
1571 return Err(DriverError::Protocol(
1572 "array: truncated element data".into(),
1573 ));
1574 }
1575 elements.push(&data[pos..pos + elem_len]);
1576 pos += elem_len;
1577 }
1578 Ok(elements)
1579}
1580
1581pub fn decode_array_i32(data: &[u8]) -> Result<Vec<i32>, DriverError> {
1583 decode_array_elements(data)?
1584 .into_iter()
1585 .map(decode_i32)
1586 .collect()
1587}
1588
1589pub fn decode_array_i16(data: &[u8]) -> Result<Vec<i16>, DriverError> {
1591 decode_array_elements(data)?
1592 .into_iter()
1593 .map(decode_i16)
1594 .collect()
1595}
1596
1597pub fn decode_array_i64(data: &[u8]) -> Result<Vec<i64>, DriverError> {
1599 decode_array_elements(data)?
1600 .into_iter()
1601 .map(decode_i64)
1602 .collect()
1603}
1604
1605pub fn decode_array_f32(data: &[u8]) -> Result<Vec<f32>, DriverError> {
1607 decode_array_elements(data)?
1608 .into_iter()
1609 .map(decode_f32)
1610 .collect()
1611}
1612
1613pub fn decode_array_f64(data: &[u8]) -> Result<Vec<f64>, DriverError> {
1615 decode_array_elements(data)?
1616 .into_iter()
1617 .map(decode_f64)
1618 .collect()
1619}
1620
1621pub fn decode_array_bool(data: &[u8]) -> Result<Vec<bool>, DriverError> {
1623 decode_array_elements(data)?
1624 .into_iter()
1625 .map(decode_bool)
1626 .collect()
1627}
1628
1629pub fn decode_array_str(data: &[u8]) -> Result<Vec<String>, DriverError> {
1631 decode_array_elements(data)?
1632 .into_iter()
1633 .map(|d| decode_str(d).map(|s| s.to_owned()))
1634 .collect()
1635}
1636
1637pub fn decode_array_bytea(data: &[u8]) -> Result<Vec<Vec<u8>>, DriverError> {
1639 Ok(decode_array_elements(data)?
1640 .into_iter()
1641 .map(|d| d.to_vec())
1642 .collect())
1643}
1644
1645#[cfg(feature = "uuid")]
1649#[inline]
1650pub fn decode_uuid_type(data: &[u8]) -> Result<uuid::Uuid, DriverError> {
1651 let bytes = decode_uuid(data)?;
1652 Ok(uuid::Uuid::from_bytes(bytes))
1653}
1654
1655#[cfg(feature = "time")]
1657#[inline]
1658pub fn decode_timestamptz_time(data: &[u8]) -> Result<time::OffsetDateTime, DriverError> {
1659 let micros = decode_i64(data)?;
1660 let unix_micros = micros + 946_684_800i64 * 1_000_000;
1662 let secs = unix_micros.div_euclid(1_000_000);
1663 let nanos = (unix_micros.rem_euclid(1_000_000) * 1000) as i128;
1664 time::OffsetDateTime::from_unix_timestamp_nanos(secs as i128 * 1_000_000_000 + nanos)
1665 .map_err(|e| DriverError::Protocol(format!("timestamptz decode: {e}")))
1666}
1667
1668#[cfg(feature = "time")]
1670#[inline]
1671pub fn decode_date_time(data: &[u8]) -> Result<time::Date, DriverError> {
1672 let days = decode_i32(data)?;
1673 let julian_day = PG_EPOCH_JULIAN_DAY as i64 + days as i64;
1675 if julian_day < i32::MIN as i64 || julian_day > i32::MAX as i64 {
1676 return Err(DriverError::Protocol(format!(
1677 "date out of range: {days} days"
1678 )));
1679 }
1680 time::Date::from_julian_day(julian_day as i32)
1681 .map_err(|_| DriverError::Protocol(format!("date out of range: {days} days")))
1682}
1683
1684#[cfg(feature = "time")]
1686#[inline]
1687pub fn decode_time_time(data: &[u8]) -> Result<time::Time, DriverError> {
1688 let micros = decode_i64(data)?;
1689
1690 if !(0..86_400_000_000).contains(µs) {
1692 return Err(DriverError::Protocol(format!(
1693 "time out of range: {micros}us (must be 0..86_400_000_000)"
1694 )));
1695 }
1696 let total_secs = micros / 1_000_000;
1697 let h = (total_secs / 3600) as u8;
1698 let m = ((total_secs % 3600) / 60) as u8;
1699 let s = (total_secs % 60) as u8;
1700 let micro = (micros % 1_000_000) as u32;
1701 time::Time::from_hms_micro(h, m, s, micro)
1702 .map_err(|e| DriverError::Protocol(format!("time decode: {e}")))
1703}
1704
1705#[cfg(feature = "chrono")]
1707#[inline]
1708pub fn decode_timestamptz_chrono(
1709 data: &[u8],
1710) -> Result<chrono::DateTime<chrono::Utc>, DriverError> {
1711 let micros = decode_i64(data)?;
1712 let pg_epoch_unix_micros: i64 = 946_684_800 * 1_000_000;
1713 let unix_micros = micros + pg_epoch_unix_micros;
1714 let secs = unix_micros.div_euclid(1_000_000);
1715 let nsecs = (unix_micros.rem_euclid(1_000_000) * 1000) as u32;
1716 chrono::DateTime::from_timestamp(secs, nsecs)
1717 .ok_or_else(|| DriverError::Protocol(format!("timestamptz out of range: {micros}us")))
1718}
1719
1720#[cfg(feature = "chrono")]
1722#[inline]
1723pub fn decode_date_chrono(data: &[u8]) -> Result<chrono::NaiveDate, DriverError> {
1724 let days = decode_i32(data)?;
1725 const PG_EPOCH_CE_DAYS: i32 = 730_120;
1727 let ce_days = PG_EPOCH_CE_DAYS as i64 + days as i64;
1728 if ce_days < i32::MIN as i64 || ce_days > i32::MAX as i64 {
1729 return Err(DriverError::Protocol(format!(
1730 "date out of range: {days} days"
1731 )));
1732 }
1733 chrono::NaiveDate::from_num_days_from_ce_opt(ce_days as i32)
1734 .ok_or_else(|| DriverError::Protocol(format!("date out of range: {days} days")))
1735}
1736
1737#[cfg(feature = "chrono")]
1739#[inline]
1740pub fn decode_time_chrono(data: &[u8]) -> Result<chrono::NaiveTime, DriverError> {
1741 let micros = decode_i64(data)?;
1742
1743 if !(0..86_400_000_000).contains(µs) {
1745 return Err(DriverError::Protocol(format!(
1746 "time out of range: {micros}us (must be 0..86_400_000_000)"
1747 )));
1748 }
1749 let total_secs = (micros / 1_000_000) as u32;
1750 let micro = (micros % 1_000_000) as u32;
1751 chrono::NaiveTime::from_num_seconds_from_midnight_opt(total_secs, micro * 1000)
1752 .ok_or_else(|| DriverError::Protocol(format!("time out of range: {micros}us")))
1753}
1754
1755#[cfg(feature = "decimal")]
1762pub fn decode_numeric_decimal(data: &[u8]) -> Result<rust_decimal::Decimal, DriverError> {
1763 if data.len() < 8 {
1764 return Err(DriverError::Protocol(format!(
1765 "numeric: expected >= 8 bytes header, got {}",
1766 data.len()
1767 )));
1768 }
1769 let ndigits = i16::from_be_bytes([data[0], data[1]]) as usize;
1770 let weight = i16::from_be_bytes([data[2], data[3]]) as i32;
1771 let sign = i16::from_be_bytes([data[4], data[5]]);
1772 let _dscale = i16::from_be_bytes([data[6], data[7]]) as u32;
1773
1774 if data.len() != 8 + ndigits * 2 {
1775 return Err(DriverError::Protocol(format!(
1776 "numeric: expected {} bytes, got {}",
1777 8 + ndigits * 2,
1778 data.len()
1779 )));
1780 }
1781
1782 if ndigits == 0 {
1783 return Ok(rust_decimal::Decimal::ZERO);
1784 }
1785
1786 let mut digits: smallvec::SmallVec<[i64; 16]> = smallvec::SmallVec::with_capacity(ndigits);
1788 for i in 0..ndigits {
1789 let off = 8 + i * 2;
1790 digits.push(i16::from_be_bytes([data[off], data[off + 1]]) as i64);
1791 }
1792
1793 let mut mantissa: u128 = 0;
1796 for &d in &digits {
1797 mantissa = mantissa
1798 .checked_mul(10_000)
1799 .and_then(|m| m.checked_add(d as u128))
1800 .ok_or_else(|| DriverError::Protocol("numeric value too large for Decimal".into()))?;
1801 }
1802
1803 let exponent = 4 * (weight - ndigits as i32 + 1);
1807 let result = if exponent >= 0 {
1808 let factor = 10u128
1810 .checked_pow(exponent as u32)
1811 .ok_or_else(|| DriverError::Protocol("numeric exponent too large".into()))?;
1812 let m = mantissa
1813 .checked_mul(factor)
1814 .ok_or_else(|| DriverError::Protocol("numeric value too large for Decimal".into()))?;
1815 if m > u128::from(u64::MAX) {
1816 let s = m.to_string();
1818 s.parse::<rust_decimal::Decimal>()
1819 .map_err(|e| DriverError::Protocol(format!("numeric parse error: {e}")))?
1820 } else {
1821 rust_decimal::Decimal::from_i128_with_scale(m as i128, 0)
1822 }
1823 } else {
1824 let scale = (-exponent) as u32;
1826 if mantissa <= u128::from(u64::MAX) {
1828 rust_decimal::Decimal::from_i128_with_scale(mantissa as i128, scale)
1829 } else {
1830 let mut s = mantissa.to_string();
1832 if scale as usize >= s.len() {
1833 let zeros = scale as usize - s.len() + 1;
1834 s = format!("0.{}{s}", "0".repeat(zeros));
1835 } else {
1836 let dot_pos = s.len() - scale as usize;
1837 s.insert(dot_pos, '.');
1838 }
1839 s.parse::<rust_decimal::Decimal>()
1840 .map_err(|e| DriverError::Protocol(format!("numeric parse error: {e}")))?
1841 }
1842 };
1843
1844 if sign == 0x4000 {
1845 Ok(-result)
1846 } else {
1847 Ok(result)
1848 }
1849}
1850
1851#[cfg(test)]
1852#[allow(clippy::approx_constant)]
1853mod tests {
1854 use super::*;
1855
1856 #[test]
1859 fn bool_roundtrip() {
1860 let mut buf = Vec::new();
1861 true.encode_binary(&mut buf);
1862 assert!(decode_bool(&buf).unwrap());
1863
1864 buf.clear();
1865 false.encode_binary(&mut buf);
1866 assert!(!decode_bool(&buf).unwrap());
1867 }
1868
1869 #[test]
1870 fn i16_roundtrip() {
1871 let mut buf = Vec::new();
1872 12345i16.encode_binary(&mut buf);
1873 assert_eq!(decode_i16(&buf).unwrap(), 12345);
1874
1875 buf.clear();
1876 (-1i16).encode_binary(&mut buf);
1877 assert_eq!(decode_i16(&buf).unwrap(), -1);
1878
1879 buf.clear();
1880 i16::MIN.encode_binary(&mut buf);
1881 assert_eq!(decode_i16(&buf).unwrap(), i16::MIN);
1882
1883 buf.clear();
1884 i16::MAX.encode_binary(&mut buf);
1885 assert_eq!(decode_i16(&buf).unwrap(), i16::MAX);
1886 }
1887
1888 #[test]
1889 fn i32_roundtrip() {
1890 let mut buf = Vec::new();
1891 42i32.encode_binary(&mut buf);
1892 assert_eq!(buf, &[0, 0, 0, 42]);
1893 assert_eq!(decode_i32(&buf).unwrap(), 42);
1894
1895 buf.clear();
1896 i32::MAX.encode_binary(&mut buf);
1897 assert_eq!(decode_i32(&buf).unwrap(), i32::MAX);
1898
1899 buf.clear();
1900 i32::MIN.encode_binary(&mut buf);
1901 assert_eq!(decode_i32(&buf).unwrap(), i32::MIN);
1902 }
1903
1904 #[test]
1905 fn i64_roundtrip() {
1906 let mut buf = Vec::new();
1907 1234567890123i64.encode_binary(&mut buf);
1908 assert_eq!(decode_i64(&buf).unwrap(), 1234567890123);
1909 }
1910
1911 #[test]
1912 fn f32_roundtrip() {
1913 let mut buf = Vec::new();
1914 3.14f32.encode_binary(&mut buf);
1915 let decoded = decode_f32(&buf).unwrap();
1916 assert!((decoded - 3.14).abs() < f32::EPSILON);
1917 }
1918
1919 #[test]
1920 fn f64_roundtrip() {
1921 let mut buf = Vec::new();
1922 std::f64::consts::PI.encode_binary(&mut buf);
1923 let decoded = decode_f64(&buf).unwrap();
1924 assert!((decoded - std::f64::consts::PI).abs() < f64::EPSILON);
1925 }
1926
1927 #[test]
1928 fn str_roundtrip() {
1929 let mut buf = Vec::new();
1930 "hello world".encode_binary(&mut buf);
1931 assert_eq!(decode_str(&buf).unwrap(), "hello world");
1932 }
1933
1934 #[test]
1935 fn string_roundtrip() {
1936 let mut buf = Vec::new();
1937 let s = String::from("test string");
1938 s.encode_binary(&mut buf);
1939 assert_eq!(decode_str(&buf).unwrap(), "test string");
1940 }
1941
1942 #[test]
1943 fn bytes_roundtrip() {
1944 let mut buf = Vec::new();
1945 let data: &[u8] = &[0xDE, 0xAD, 0xBE, 0xEF];
1946 data.encode_binary(&mut buf);
1947 assert_eq!(decode_bytes(&buf), data);
1948 }
1949
1950 #[test]
1951 fn vec_u8_roundtrip() {
1952 let mut buf = Vec::new();
1953 let data = vec![1u8, 2, 3, 4, 5];
1954 data.encode_binary(&mut buf);
1955 assert_eq!(decode_bytes(&buf), &[1, 2, 3, 4, 5]);
1956 }
1957
1958 #[test]
1959 fn u32_encode() {
1960 let mut buf = Vec::new();
1961 42u32.encode_binary(&mut buf);
1962 assert_eq!(buf, &[0, 0, 0, 42]);
1963 }
1964
1965 #[test]
1966 fn uuid_roundtrip() {
1967 let uuid_bytes: [u8; 16] = [
1968 0x55, 0x0e, 0x84, 0x00, 0xe2, 0x9b, 0x41, 0xd4, 0xa7, 0x16, 0x44, 0x66, 0x55, 0x44,
1969 0x00, 0x00,
1970 ];
1971 let decoded = decode_uuid(&uuid_bytes).unwrap();
1972 assert_eq!(decoded, uuid_bytes);
1973 }
1974
1975 #[test]
1978 fn decode_bool_wrong_length() {
1979 assert!(decode_bool(&[]).is_err());
1980 assert!(decode_bool(&[0, 0]).is_err());
1981 }
1982
1983 #[test]
1984 fn decode_i32_wrong_length() {
1985 assert!(decode_i32(&[0, 0, 0]).is_err());
1986 assert!(decode_i32(&[0, 0, 0, 0, 0]).is_err());
1987 }
1988
1989 #[test]
1990 fn decode_i64_wrong_length() {
1991 assert!(decode_i64(&[0; 7]).is_err());
1992 assert!(decode_i64(&[0; 9]).is_err());
1993 }
1994
1995 #[test]
1996 fn decode_f32_wrong_length() {
1997 assert!(decode_f32(&[0; 3]).is_err());
1998 }
1999
2000 #[test]
2001 fn decode_f64_wrong_length() {
2002 assert!(decode_f64(&[0; 7]).is_err());
2003 }
2004
2005 #[test]
2006 fn decode_str_invalid_utf8() {
2007 assert!(decode_str(&[0xFF, 0xFE]).is_err());
2008 }
2009
2010 #[test]
2011 fn decode_uuid_wrong_length() {
2012 assert!(decode_uuid(&[0; 15]).is_err());
2013 assert!(decode_uuid(&[0; 17]).is_err());
2014 }
2015
2016 #[test]
2017 fn empty_str_decode() {
2018 assert_eq!(decode_str(&[]).unwrap(), "");
2019 }
2020
2021 #[test]
2022 fn empty_bytes_decode() {
2023 assert_eq!(decode_bytes(&[]).len(), 0);
2024 }
2025
2026 #[test]
2029 fn type_oids_correct() {
2030 assert_eq!(true.type_oid(), 16);
2031 assert_eq!(0i16.type_oid(), 21);
2032 assert_eq!(0i32.type_oid(), 23);
2033 assert_eq!(0i64.type_oid(), 20);
2034 assert_eq!(0f32.type_oid(), 700);
2035 assert_eq!(0f64.type_oid(), 701);
2036 assert_eq!("".type_oid(), 25);
2037 assert_eq!(String::new().type_oid(), 25);
2038 let b: &[u8] = &[];
2039 assert_eq!(b.type_oid(), 17);
2040 assert_eq!(Vec::<u8>::new().type_oid(), 17);
2041 assert_eq!(0u32.type_oid(), 26);
2042 }
2043
2044 #[test]
2047 fn encode_param_i32() {
2048 let mut buf = Vec::new();
2049 encode_param(&mut buf, &42i32);
2050 assert_eq!(buf.len(), 8);
2052 let len = i32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]);
2053 assert_eq!(len, 4);
2054 let val = i32::from_be_bytes([buf[4], buf[5], buf[6], buf[7]]);
2055 assert_eq!(val, 42);
2056 }
2057
2058 #[test]
2059 fn encode_param_str() {
2060 let mut buf = Vec::new();
2061 encode_param(&mut buf, &"hello");
2062 assert_eq!(buf.len(), 9);
2064 let len = i32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]);
2065 assert_eq!(len, 5);
2066 assert_eq!(&buf[4..], b"hello");
2067 }
2068
2069 #[test]
2070 fn option_none_is_null() {
2071 let val: Option<i32> = None;
2072 assert!(val.is_null());
2073 assert_eq!(val.type_oid(), 23); }
2075
2076 #[test]
2077 fn option_some_encodes() {
2078 let val: Option<i32> = Some(42);
2079 assert!(!val.is_null());
2080 assert_eq!(val.type_oid(), 23);
2081 let mut buf = Vec::new();
2082 val.encode_binary(&mut buf);
2083 assert_eq!(buf, &[0, 0, 0, 42]);
2084 }
2085
2086 #[test]
2087 fn option_none_encode_is_noop() {
2088 let val: Option<i32> = None;
2089 let mut buf = Vec::new();
2090 val.encode_binary(&mut buf);
2091 assert!(buf.is_empty(), "None encode should produce no bytes");
2092 }
2093
2094 #[test]
2098 fn decode_i16_wrong_length() {
2099 assert!(decode_i16(&[]).is_err());
2100 assert!(decode_i16(&[0]).is_err());
2101 assert!(decode_i16(&[0, 0, 0]).is_err());
2102 }
2103
2104 #[test]
2106 fn f32_nan_roundtrip() {
2107 let mut buf = Vec::new();
2108 f32::NAN.encode_binary(&mut buf);
2109 let decoded = decode_f32(&buf).unwrap();
2110 assert!(decoded.is_nan(), "NaN should survive roundtrip");
2111 }
2112
2113 #[test]
2115 fn f64_nan_roundtrip() {
2116 let mut buf = Vec::new();
2117 f64::NAN.encode_binary(&mut buf);
2118 let decoded = decode_f64(&buf).unwrap();
2119 assert!(decoded.is_nan(), "NaN should survive roundtrip");
2120 }
2121
2122 #[test]
2124 fn f32_infinity_roundtrip() {
2125 let mut buf = Vec::new();
2126 f32::INFINITY.encode_binary(&mut buf);
2127 assert_eq!(decode_f32(&buf).unwrap(), f32::INFINITY);
2128
2129 buf.clear();
2130 f32::NEG_INFINITY.encode_binary(&mut buf);
2131 assert_eq!(decode_f32(&buf).unwrap(), f32::NEG_INFINITY);
2132 }
2133
2134 #[test]
2136 fn f64_infinity_roundtrip() {
2137 let mut buf = Vec::new();
2138 f64::INFINITY.encode_binary(&mut buf);
2139 assert_eq!(decode_f64(&buf).unwrap(), f64::INFINITY);
2140
2141 buf.clear();
2142 f64::NEG_INFINITY.encode_binary(&mut buf);
2143 assert_eq!(decode_f64(&buf).unwrap(), f64::NEG_INFINITY);
2144 }
2145
2146 #[test]
2148 fn f32_signed_zero_roundtrip() {
2149 let mut buf = Vec::new();
2150 0.0f32.encode_binary(&mut buf);
2151 let decoded = decode_f32(&buf).unwrap();
2152 assert_eq!(decoded.to_bits(), 0.0f32.to_bits(), "+0.0 bits must match");
2153
2154 buf.clear();
2155 (-0.0f32).encode_binary(&mut buf);
2156 let decoded = decode_f32(&buf).unwrap();
2157 assert_eq!(
2158 decoded.to_bits(),
2159 (-0.0f32).to_bits(),
2160 "-0.0 bits must match"
2161 );
2162 }
2163
2164 #[test]
2166 fn f64_signed_zero_roundtrip() {
2167 let mut buf = Vec::new();
2168 0.0f64.encode_binary(&mut buf);
2169 let decoded = decode_f64(&buf).unwrap();
2170 assert_eq!(decoded.to_bits(), 0.0f64.to_bits(), "+0.0 bits must match");
2171
2172 buf.clear();
2173 (-0.0f64).encode_binary(&mut buf);
2174 let decoded = decode_f64(&buf).unwrap();
2175 assert_eq!(
2176 decoded.to_bits(),
2177 (-0.0f64).to_bits(),
2178 "-0.0 bits must match"
2179 );
2180 }
2181
2182 #[test]
2184 fn i64_boundary_roundtrip() {
2185 let mut buf = Vec::new();
2186 i64::MIN.encode_binary(&mut buf);
2187 assert_eq!(decode_i64(&buf).unwrap(), i64::MIN);
2188
2189 buf.clear();
2190 i64::MAX.encode_binary(&mut buf);
2191 assert_eq!(decode_i64(&buf).unwrap(), i64::MAX);
2192 }
2193
2194 #[test]
2196 fn i16_boundary_standalone() {
2197 let mut buf = Vec::new();
2198 i16::MIN.encode_binary(&mut buf);
2199 assert_eq!(decode_i16(&buf).unwrap(), i16::MIN);
2200
2201 buf.clear();
2202 i16::MAX.encode_binary(&mut buf);
2203 assert_eq!(decode_i16(&buf).unwrap(), i16::MAX);
2204 }
2205
2206 #[cfg(feature = "chrono")]
2208 #[test]
2209 fn decode_date_chrono_negative_days() {
2210 let data = (-365i32).to_be_bytes();
2212 let date = decode_date_chrono(&data).unwrap();
2213 assert_eq!(date, chrono::NaiveDate::from_ymd_opt(1999, 1, 1).unwrap());
2214 }
2215
2216 #[cfg(feature = "chrono")]
2218 #[test]
2219 fn decode_date_chrono_day_zero() {
2220 let data = 0i32.to_be_bytes();
2221 let date = decode_date_chrono(&data).unwrap();
2222 assert_eq!(date, chrono::NaiveDate::from_ymd_opt(2000, 1, 1).unwrap());
2223 }
2224
2225 #[cfg(feature = "time")]
2227 #[test]
2228 fn decode_date_time_negative_days() {
2229 let data = (-1i32).to_be_bytes();
2230 let date = decode_date_time(&data).unwrap();
2231 let expected = time::Date::from_calendar_date(1999, time::Month::December, 31).unwrap();
2232 assert_eq!(date, expected);
2233 }
2234
2235 #[cfg(feature = "time")]
2237 #[test]
2238 fn decode_time_time_midnight() {
2239 let data = 0i64.to_be_bytes();
2240 let t = decode_time_time(&data).unwrap();
2241 assert_eq!(t, time::Time::MIDNIGHT);
2242 }
2243
2244 #[cfg(feature = "time")]
2246 #[test]
2247 fn decode_time_time_max_value() {
2248 let micros: i64 = 86_400_000_000 - 1; let data = micros.to_be_bytes();
2250 let t = decode_time_time(&data).unwrap();
2251 assert_eq!(t.hour(), 23);
2252 assert_eq!(t.minute(), 59);
2253 assert_eq!(t.second(), 59);
2254 assert_eq!(t.microsecond(), 999999);
2255 }
2256
2257 #[cfg(feature = "time")]
2259 #[test]
2260 fn decode_time_time_negative_micros_error() {
2261 let data = (-1i64).to_be_bytes();
2262 let result = decode_time_time(&data);
2263 assert!(result.is_err(), "negative microseconds should error");
2264 }
2265
2266 #[cfg(feature = "time")]
2268 #[test]
2269 fn decode_time_time_overflow_error() {
2270 let data = 86_400_000_000i64.to_be_bytes();
2271 let result = decode_time_time(&data);
2272 assert!(result.is_err(), ">= 24h microseconds should error");
2273 }
2274
2275 #[cfg(feature = "time")]
2277 #[test]
2278 fn decode_timestamptz_time_pg_epoch() {
2279 let data = 0i64.to_be_bytes();
2280 let dt = decode_timestamptz_time(&data).unwrap();
2281 assert_eq!(dt.year(), 2000);
2283 assert_eq!(dt.month(), time::Month::January);
2284 assert_eq!(dt.day(), 1);
2285 assert_eq!(dt.hour(), 0);
2286 assert_eq!(dt.minute(), 0);
2287 assert_eq!(dt.second(), 0);
2288 }
2289
2290 #[cfg(feature = "decimal")]
2292 #[test]
2293 fn decode_numeric_decimal_zero() {
2294 let mut data = Vec::new();
2296 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();
2301 assert!(dec.is_zero());
2302 }
2303
2304 #[cfg(feature = "decimal")]
2306 #[test]
2307 fn decode_numeric_decimal_negative() {
2308 let mut data = Vec::new();
2310 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();
2316 assert_eq!(dec, rust_decimal::Decimal::new(-42, 0));
2317 }
2318
2319 #[cfg(feature = "decimal")]
2321 #[test]
2322 fn decode_numeric_decimal_pure_fractional() {
2323 let mut data = Vec::new();
2328 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();
2334 let dec_normalized = dec.normalize();
2336 assert_eq!(dec_normalized.to_string(), "0.001");
2337 }
2338
2339 #[cfg(feature = "decimal")]
2344 fn decimal_encode_roundtrip(s: &str) {
2345 use rust_decimal::Decimal;
2346 use std::str::FromStr;
2347 let original = Decimal::from_str(s).unwrap();
2348 let mut buf = Vec::new();
2349 original.encode_binary(&mut buf);
2350 let decoded = decode_numeric_decimal(&buf).unwrap();
2351 assert_eq!(
2352 decoded.normalize().to_string(),
2353 original.normalize().to_string(),
2354 "round-trip failed for {s}: encoded {} bytes",
2355 buf.len()
2356 );
2357 }
2358
2359 #[cfg(feature = "decimal")]
2360 #[test]
2361 fn decimal_roundtrip_zero() {
2362 decimal_encode_roundtrip("0");
2363 }
2364
2365 #[cfg(feature = "decimal")]
2366 #[test]
2367 fn decimal_roundtrip_one() {
2368 decimal_encode_roundtrip("1");
2369 }
2370
2371 #[cfg(feature = "decimal")]
2372 #[test]
2373 fn decimal_roundtrip_negative() {
2374 decimal_encode_roundtrip("-42.5");
2375 }
2376
2377 #[cfg(feature = "decimal")]
2378 #[test]
2379 fn decimal_roundtrip_large_integer() {
2380 decimal_encode_roundtrip("123456789");
2381 }
2382
2383 #[cfg(feature = "decimal")]
2384 #[test]
2385 fn decimal_roundtrip_pure_fractional_0001() {
2386 decimal_encode_roundtrip("0.001");
2387 }
2388
2389 #[cfg(feature = "decimal")]
2390 #[test]
2391 fn decimal_roundtrip_pure_fractional_00001() {
2392 decimal_encode_roundtrip("0.0001");
2393 }
2394
2395 #[cfg(feature = "decimal")]
2396 #[test]
2397 fn decimal_roundtrip_pure_fractional_000001() {
2398 decimal_encode_roundtrip("0.00001");
2399 }
2400
2401 #[cfg(feature = "decimal")]
2402 #[test]
2403 fn decimal_roundtrip_mixed() {
2404 decimal_encode_roundtrip("12345.6789");
2405 }
2406
2407 #[cfg(feature = "decimal")]
2408 #[test]
2409 fn decimal_roundtrip_trailing_zeros() {
2410 decimal_encode_roundtrip("100.00");
2411 }
2412
2413 #[cfg(feature = "decimal")]
2414 #[test]
2415 fn decimal_roundtrip_small_negative_fraction() {
2416 decimal_encode_roundtrip("-0.007");
2417 }
2418
2419 #[cfg(feature = "decimal")]
2420 #[test]
2421 fn decimal_roundtrip_high_scale() {
2422 decimal_encode_roundtrip("0.0000000000000000000000000001");
2424 }
2425
2426 #[cfg(feature = "decimal")]
2427 #[test]
2428 fn decimal_roundtrip_large_with_fraction() {
2429 decimal_encode_roundtrip("999999999999999999.999999999999");
2430 }
2431
2432 #[test]
2434 fn decode_array_empty() {
2435 let mut data = Vec::new();
2437 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();
2441 assert!(elems.is_empty());
2442 }
2443
2444 #[test]
2446 fn decode_array_multidim_error() {
2447 let mut data = Vec::new();
2448 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());
2453 data.extend_from_slice(&0i32.to_be_bytes());
2454 data.extend_from_slice(&0i32.to_be_bytes());
2455 data.extend_from_slice(&0i32.to_be_bytes());
2456 let result = decode_array_i32(&data);
2457 assert!(result.is_err(), "multi-dimensional should error");
2458 }
2459
2460 #[test]
2462 fn decode_array_truncated_error() {
2463 let mut data = Vec::new();
2465 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);
2472 assert!(result.is_err(), "truncated array should error");
2473 }
2474
2475 #[test]
2477 fn option_some_i32_produces_data() {
2478 let val: Option<i32> = Some(42);
2479 assert!(!val.is_null());
2480 let mut buf = Vec::new();
2481 val.encode_binary(&mut buf);
2482 assert_eq!(decode_i32(&buf).unwrap(), 42);
2483 }
2484
2485 #[test]
2487 fn option_none_i32_is_null() {
2488 let val: Option<i32> = None;
2489 assert!(val.is_null());
2490 assert_eq!(val.type_oid(), 23);
2491 let mut buf = Vec::new();
2492 val.encode_binary(&mut buf);
2493 assert!(buf.is_empty());
2494 }
2495
2496 #[test]
2498 fn empty_string_encode_decode() {
2499 let mut buf = Vec::new();
2500 "".encode_binary(&mut buf);
2501 assert!(buf.is_empty());
2502 assert_eq!(decode_str(&buf).unwrap(), "");
2503
2504 buf.clear();
2505 String::new().encode_binary(&mut buf);
2506 assert!(buf.is_empty());
2507 assert_eq!(decode_str(&buf).unwrap(), "");
2508 }
2509
2510 #[test]
2512 fn empty_bytes_encode_decode() {
2513 let mut buf = Vec::new();
2514 let empty: &[u8] = &[];
2515 empty.encode_binary(&mut buf);
2516 assert!(buf.is_empty());
2517 assert_eq!(decode_bytes(&buf).len(), 0);
2518
2519 buf.clear();
2520 Vec::<u8>::new().encode_binary(&mut buf);
2521 assert!(buf.is_empty());
2522 }
2523
2524 #[test]
2526 fn large_string_encode_decode() {
2527 let big = "x".repeat(1_000_000);
2528 let mut buf = Vec::new();
2529 big.as_str().encode_binary(&mut buf);
2530 assert_eq!(buf.len(), 1_000_000);
2531 assert_eq!(decode_str(&buf).unwrap(), big);
2532 }
2533
2534 #[test]
2536 fn uuid_nil() {
2537 let nil = [0u8; 16];
2538 let decoded = decode_uuid(&nil).unwrap();
2539 assert_eq!(decoded, [0u8; 16]);
2540 }
2541
2542 #[test]
2544 fn uuid_max() {
2545 let max = [0xFF; 16];
2546 let decoded = decode_uuid(&max).unwrap();
2547 assert_eq!(decoded, [0xFF; 16]);
2548 }
2549
2550 #[cfg(feature = "uuid")]
2552 #[test]
2553 fn uuid_type_nil_and_max() {
2554 let nil = [0u8; 16];
2555 let uuid = decode_uuid_type(&nil).unwrap();
2556 assert_eq!(uuid, uuid::Uuid::nil());
2557
2558 let max = [0xFF; 16];
2559 let uuid = decode_uuid_type(&max).unwrap();
2560 assert_eq!(uuid, uuid::Uuid::max());
2561 }
2562
2563 #[test]
2567 fn encode_array_bool_empty() {
2568 let arr: &[bool] = &[];
2569 let mut buf = Vec::new();
2570 arr.encode_binary(&mut buf);
2571 let decoded = decode_array_bool(&buf).unwrap();
2572 assert!(decoded.is_empty());
2573 }
2574
2575 #[test]
2576 fn encode_array_bool_single() {
2577 let arr: &[bool] = &[true];
2578 let mut buf = Vec::new();
2579 arr.encode_binary(&mut buf);
2580 let decoded = decode_array_bool(&buf).unwrap();
2581 assert_eq!(decoded, vec![true]);
2582 }
2583
2584 #[test]
2585 fn encode_array_bool_multi() {
2586 let arr: &[bool] = &[true, false, true, false];
2587 let mut buf = Vec::new();
2588 arr.encode_binary(&mut buf);
2589 let decoded = decode_array_bool(&buf).unwrap();
2590 assert_eq!(decoded, vec![true, false, true, false]);
2591 }
2592
2593 #[test]
2594 fn encode_array_bool_vec_delegate() {
2595 let v = vec![false, true];
2596 let mut buf = Vec::new();
2597 v.encode_binary(&mut buf);
2598 let decoded = decode_array_bool(&buf).unwrap();
2599 assert_eq!(decoded, vec![false, true]);
2600 assert_eq!(v.type_oid(), 1000);
2601 }
2602
2603 #[test]
2605 fn encode_array_i16_empty() {
2606 let arr: &[i16] = &[];
2607 let mut buf = Vec::new();
2608 arr.encode_binary(&mut buf);
2609 let decoded = decode_array_i16(&buf).unwrap();
2610 assert!(decoded.is_empty());
2611 }
2612
2613 #[test]
2614 fn encode_array_i16_single() {
2615 let arr: &[i16] = &[42];
2616 let mut buf = Vec::new();
2617 arr.encode_binary(&mut buf);
2618 let decoded = decode_array_i16(&buf).unwrap();
2619 assert_eq!(decoded, vec![42i16]);
2620 }
2621
2622 #[test]
2623 fn encode_array_i16_multi_boundary() {
2624 let arr: &[i16] = &[i16::MIN, -1, 0, 1, i16::MAX];
2625 let mut buf = Vec::new();
2626 arr.encode_binary(&mut buf);
2627 let decoded = decode_array_i16(&buf).unwrap();
2628 assert_eq!(decoded, vec![i16::MIN, -1, 0, 1, i16::MAX]);
2629 }
2630
2631 #[test]
2632 fn encode_array_i16_vec_delegate() {
2633 let v = vec![100i16, 200];
2634 let mut buf = Vec::new();
2635 v.encode_binary(&mut buf);
2636 let decoded = decode_array_i16(&buf).unwrap();
2637 assert_eq!(decoded, vec![100i16, 200]);
2638 assert_eq!(v.type_oid(), 1005);
2639 }
2640
2641 #[test]
2643 fn encode_array_i32_empty() {
2644 let arr: &[i32] = &[];
2645 let mut buf = Vec::new();
2646 arr.encode_binary(&mut buf);
2647 let decoded = decode_array_i32(&buf).unwrap();
2648 assert!(decoded.is_empty());
2649 }
2650
2651 #[test]
2652 fn encode_array_i32_single() {
2653 let arr: &[i32] = &[42];
2654 let mut buf = Vec::new();
2655 arr.encode_binary(&mut buf);
2656 let decoded = decode_array_i32(&buf).unwrap();
2657 assert_eq!(decoded, vec![42]);
2658 }
2659
2660 #[test]
2661 fn encode_array_i32_multi_boundary() {
2662 let arr: &[i32] = &[i32::MIN, -1, 0, 1, i32::MAX];
2663 let mut buf = Vec::new();
2664 arr.encode_binary(&mut buf);
2665 let decoded = decode_array_i32(&buf).unwrap();
2666 assert_eq!(decoded, vec![i32::MIN, -1, 0, 1, i32::MAX]);
2667 }
2668
2669 #[test]
2670 fn encode_array_i32_vec_delegate() {
2671 let v = vec![10, 20, 30];
2672 let mut buf = Vec::new();
2673 v.encode_binary(&mut buf);
2674 let decoded = decode_array_i32(&buf).unwrap();
2675 assert_eq!(decoded, vec![10, 20, 30]);
2676 assert_eq!(v.type_oid(), 1007);
2677 }
2678
2679 #[test]
2681 fn encode_array_i64_empty() {
2682 let arr: &[i64] = &[];
2683 let mut buf = Vec::new();
2684 arr.encode_binary(&mut buf);
2685 let decoded = decode_array_i64(&buf).unwrap();
2686 assert!(decoded.is_empty());
2687 }
2688
2689 #[test]
2690 fn encode_array_i64_single() {
2691 let arr: &[i64] = &[9999999999i64];
2692 let mut buf = Vec::new();
2693 arr.encode_binary(&mut buf);
2694 let decoded = decode_array_i64(&buf).unwrap();
2695 assert_eq!(decoded, vec![9999999999i64]);
2696 }
2697
2698 #[test]
2699 fn encode_array_i64_multi_boundary() {
2700 let arr: &[i64] = &[i64::MIN, -1, 0, 1, i64::MAX];
2701 let mut buf = Vec::new();
2702 arr.encode_binary(&mut buf);
2703 let decoded = decode_array_i64(&buf).unwrap();
2704 assert_eq!(decoded, vec![i64::MIN, -1, 0, 1, i64::MAX]);
2705 }
2706
2707 #[test]
2708 fn encode_array_i64_vec_delegate() {
2709 let v = vec![1i64, 2, 3];
2710 let mut buf = Vec::new();
2711 v.encode_binary(&mut buf);
2712 let decoded = decode_array_i64(&buf).unwrap();
2713 assert_eq!(decoded, vec![1i64, 2, 3]);
2714 assert_eq!(v.type_oid(), 1016);
2715 }
2716
2717 #[test]
2719 fn encode_array_f32_empty() {
2720 let arr: &[f32] = &[];
2721 let mut buf = Vec::new();
2722 arr.encode_binary(&mut buf);
2723 let decoded = decode_array_f32(&buf).unwrap();
2724 assert!(decoded.is_empty());
2725 }
2726
2727 #[test]
2728 fn encode_array_f32_single() {
2729 let arr: &[f32] = &[3.14];
2730 let mut buf = Vec::new();
2731 arr.encode_binary(&mut buf);
2732 let decoded = decode_array_f32(&buf).unwrap();
2733 assert!((decoded[0] - 3.14).abs() < f32::EPSILON);
2734 }
2735
2736 #[test]
2737 fn encode_array_f32_multi_boundary() {
2738 let arr: &[f32] = &[
2739 f32::MIN,
2740 -0.0,
2741 0.0,
2742 f32::MAX,
2743 f32::INFINITY,
2744 f32::NEG_INFINITY,
2745 ];
2746 let mut buf = Vec::new();
2747 arr.encode_binary(&mut buf);
2748 let decoded = decode_array_f32(&buf).unwrap();
2749 assert_eq!(decoded[0], f32::MIN);
2750 assert_eq!(decoded[1].to_bits(), (-0.0f32).to_bits());
2751 assert_eq!(decoded[2].to_bits(), 0.0f32.to_bits());
2752 assert_eq!(decoded[3], f32::MAX);
2753 assert_eq!(decoded[4], f32::INFINITY);
2754 assert_eq!(decoded[5], f32::NEG_INFINITY);
2755 }
2756
2757 #[test]
2758 fn encode_array_f32_vec_delegate() {
2759 let v = vec![1.0f32, 2.0];
2760 let mut buf = Vec::new();
2761 v.encode_binary(&mut buf);
2762 let decoded = decode_array_f32(&buf).unwrap();
2763 assert_eq!(decoded, vec![1.0f32, 2.0]);
2764 assert_eq!(v.type_oid(), 1021);
2765 }
2766
2767 #[test]
2769 fn encode_array_f64_empty() {
2770 let arr: &[f64] = &[];
2771 let mut buf = Vec::new();
2772 arr.encode_binary(&mut buf);
2773 let decoded = decode_array_f64(&buf).unwrap();
2774 assert!(decoded.is_empty());
2775 }
2776
2777 #[test]
2778 fn encode_array_f64_single() {
2779 let arr: &[f64] = &[std::f64::consts::PI];
2780 let mut buf = Vec::new();
2781 arr.encode_binary(&mut buf);
2782 let decoded = decode_array_f64(&buf).unwrap();
2783 assert!((decoded[0] - std::f64::consts::PI).abs() < f64::EPSILON);
2784 }
2785
2786 #[test]
2787 fn encode_array_f64_multi_boundary() {
2788 let arr: &[f64] = &[
2789 f64::MIN,
2790 -0.0,
2791 0.0,
2792 f64::MAX,
2793 f64::INFINITY,
2794 f64::NEG_INFINITY,
2795 ];
2796 let mut buf = Vec::new();
2797 arr.encode_binary(&mut buf);
2798 let decoded = decode_array_f64(&buf).unwrap();
2799 assert_eq!(decoded[0], f64::MIN);
2800 assert_eq!(decoded[1].to_bits(), (-0.0f64).to_bits());
2801 assert_eq!(decoded[2].to_bits(), 0.0f64.to_bits());
2802 assert_eq!(decoded[3], f64::MAX);
2803 assert_eq!(decoded[4], f64::INFINITY);
2804 assert_eq!(decoded[5], f64::NEG_INFINITY);
2805 }
2806
2807 #[test]
2808 fn encode_array_f64_vec_delegate() {
2809 let v = vec![1.0f64, 2.0];
2810 let mut buf = Vec::new();
2811 v.encode_binary(&mut buf);
2812 let decoded = decode_array_f64(&buf).unwrap();
2813 assert_eq!(decoded, vec![1.0f64, 2.0]);
2814 assert_eq!(v.type_oid(), 1022);
2815 }
2816
2817 #[test]
2819 fn encode_array_str_empty() {
2820 let arr: &[&str] = &[];
2821 let mut buf = Vec::new();
2822 arr.encode_binary(&mut buf);
2823 let decoded = decode_array_str(&buf).unwrap();
2824 assert!(decoded.is_empty());
2825 }
2826
2827 #[test]
2828 fn encode_array_str_single() {
2829 let arr: &[&str] = &["hello"];
2830 let mut buf = Vec::new();
2831 arr.encode_binary(&mut buf);
2832 let decoded = decode_array_str(&buf).unwrap();
2833 assert_eq!(decoded, vec!["hello".to_string()]);
2834 }
2835
2836 #[test]
2837 fn encode_array_str_multi() {
2838 let arr: &[&str] = &["hello", "", "world"];
2839 let mut buf = Vec::new();
2840 arr.encode_binary(&mut buf);
2841 let decoded = decode_array_str(&buf).unwrap();
2842 assert_eq!(
2843 decoded,
2844 vec!["hello".to_string(), "".to_string(), "world".to_string()]
2845 );
2846 }
2847
2848 #[test]
2849 fn encode_array_str_boundary_unicode() {
2850 let arr: &[&str] = &["\u{1F600}", "\u{00E9}"];
2851 let mut buf = Vec::new();
2852 arr.encode_binary(&mut buf);
2853 let decoded = decode_array_str(&buf).unwrap();
2854 assert_eq!(
2855 decoded,
2856 vec!["\u{1F600}".to_string(), "\u{00E9}".to_string()]
2857 );
2858 }
2859
2860 #[test]
2861 fn encode_array_vec_string() {
2862 let v = vec!["foo".to_string(), "bar".to_string()];
2863 let mut buf = Vec::new();
2864 v.encode_binary(&mut buf);
2865 let decoded = decode_array_str(&buf).unwrap();
2866 assert_eq!(decoded, vec!["foo".to_string(), "bar".to_string()]);
2867 assert_eq!(v.type_oid(), 1009);
2868 }
2869
2870 #[test]
2871 fn encode_array_slice_string() {
2872 let v = vec!["foo".to_string(), "bar".to_string()];
2873 let slice: &[String] = &v;
2874 let mut buf = Vec::new();
2875 slice.encode_binary(&mut buf);
2876 let decoded = decode_array_str(&buf).unwrap();
2877 assert_eq!(decoded, vec!["foo".to_string(), "bar".to_string()]);
2878 assert_eq!(slice.type_oid(), 1009);
2879 }
2880
2881 #[test]
2882 fn encode_array_slice_string_empty() {
2883 let v: Vec<String> = vec![];
2884 let slice: &[String] = &v;
2885 let mut buf = Vec::new();
2886 slice.encode_binary(&mut buf);
2887 let decoded = decode_array_str(&buf).unwrap();
2888 assert!(decoded.is_empty());
2889 }
2890
2891 #[test]
2892 fn encode_array_ref_slice_string() {
2893 let v = ["alpha".to_string(), "beta".to_string()];
2894 let r: &&[String] = &&v[..];
2895 let mut buf = Vec::new();
2896 r.encode_binary(&mut buf);
2897 let decoded = decode_array_str(&buf).unwrap();
2898 assert_eq!(decoded, vec!["alpha".to_string(), "beta".to_string()]);
2899 assert_eq!(r.type_oid(), 1009);
2900 }
2901
2902 #[test]
2903 fn encode_array_vec_string_empty() {
2904 let v: Vec<String> = vec![];
2905 let mut buf = Vec::new();
2906 v.encode_binary(&mut buf);
2907 let decoded = decode_array_str(&buf).unwrap();
2908 assert!(decoded.is_empty());
2909 }
2910
2911 #[test]
2913 fn encode_array_bytea_empty() {
2914 let arr: &[&[u8]] = &[];
2915 let mut buf = Vec::new();
2916 arr.encode_binary(&mut buf);
2917 let decoded = decode_array_bytea(&buf).unwrap();
2918 assert!(decoded.is_empty());
2919 }
2920
2921 #[test]
2922 fn encode_array_bytea_single() {
2923 let data: &[u8] = &[0xDE, 0xAD];
2924 let arr: &[&[u8]] = &[data];
2925 let mut buf = Vec::new();
2926 arr.encode_binary(&mut buf);
2927 let decoded = decode_array_bytea(&buf).unwrap();
2928 assert_eq!(decoded, vec![vec![0xDE, 0xAD]]);
2929 }
2930
2931 #[test]
2932 fn encode_array_bytea_multi() {
2933 let a: &[u8] = &[1, 2, 3];
2934 let b: &[u8] = &[];
2935 let c: &[u8] = &[0xFF];
2936 let arr: &[&[u8]] = &[a, b, c];
2937 let mut buf = Vec::new();
2938 arr.encode_binary(&mut buf);
2939 let decoded = decode_array_bytea(&buf).unwrap();
2940 assert_eq!(decoded, vec![vec![1, 2, 3], vec![], vec![0xFF]]);
2941 }
2942
2943 #[test]
2944 fn encode_array_vec_vec_u8() {
2945 let v = vec![vec![10u8, 20], vec![30]];
2946 let mut buf = Vec::new();
2947 v.encode_binary(&mut buf);
2948 let decoded = decode_array_bytea(&buf).unwrap();
2949 assert_eq!(decoded, vec![vec![10u8, 20], vec![30]]);
2950 assert_eq!(v.type_oid(), 1001);
2951 }
2952
2953 #[test]
2954 fn encode_array_vec_vec_u8_empty() {
2955 let v: Vec<Vec<u8>> = vec![];
2956 let mut buf = Vec::new();
2957 v.encode_binary(&mut buf);
2958 let decoded = decode_array_bytea(&buf).unwrap();
2959 assert!(decoded.is_empty());
2960 }
2961
2962 #[test]
2964 fn array_type_oids_correct() {
2965 let b: &[bool] = &[];
2966 assert_eq!(b.type_oid(), 1000);
2967 let i2: &[i16] = &[];
2968 assert_eq!(i2.type_oid(), 1005);
2969 let i4: &[i32] = &[];
2970 assert_eq!(i4.type_oid(), 1007);
2971 let i8: &[i64] = &[];
2972 assert_eq!(i8.type_oid(), 1016);
2973 let f4: &[f32] = &[];
2974 assert_eq!(f4.type_oid(), 1021);
2975 let f8: &[f64] = &[];
2976 assert_eq!(f8.type_oid(), 1022);
2977 let t: &[&str] = &[];
2978 assert_eq!(t.type_oid(), 1009);
2979 let by: &[&[u8]] = &[];
2980 assert_eq!(by.type_oid(), 1001);
2981
2982 assert_eq!(Vec::<bool>::new().type_oid(), 1000);
2983 assert_eq!(Vec::<i16>::new().type_oid(), 1005);
2984 assert_eq!(Vec::<i32>::new().type_oid(), 1007);
2985 assert_eq!(Vec::<i64>::new().type_oid(), 1016);
2986 assert_eq!(Vec::<f32>::new().type_oid(), 1021);
2987 assert_eq!(Vec::<f64>::new().type_oid(), 1022);
2988 assert_eq!(Vec::<String>::new().type_oid(), 1009);
2989 assert_eq!(Vec::<Vec<u8>>::new().type_oid(), 1001);
2990 }
2991
2992 #[test]
2994 fn encode_array_empty_ndim_zero() {
2995 let arr: &[i32] = &[];
2996 let mut buf = Vec::new();
2997 arr.encode_binary(&mut buf);
2998 assert_eq!(buf.len(), 12);
3000 let ndim = i32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]);
3001 assert_eq!(ndim, 0, "empty array must have ndim=0");
3002 let elem_oid = i32::from_be_bytes([buf[8], buf[9], buf[10], buf[11]]);
3003 assert_eq!(
3004 elem_oid, 23,
3005 "element OID must be preserved for empty arrays"
3006 );
3007 }
3008
3009 #[test]
3012 fn encode_at_bool() {
3013 let mut dst = [0u8; 1];
3014 assert!(true.encode_at(&mut dst));
3015 assert_eq!(dst[0], 1);
3016 assert!(false.encode_at(&mut dst));
3017 assert_eq!(dst[0], 0);
3018 assert!(!true.encode_at(&mut [0u8; 2]));
3020 }
3021
3022 #[test]
3023 fn encode_at_i16() {
3024 let mut dst = [0u8; 2];
3025 assert!(0x1234i16.encode_at(&mut dst));
3026 assert_eq!(dst, [0x12, 0x34]);
3027 assert!(!42i16.encode_at(&mut [0u8; 4]));
3028 }
3029
3030 #[test]
3031 fn encode_at_i32() {
3032 let mut dst = [0u8; 4];
3033 assert!(42i32.encode_at(&mut dst));
3034 assert_eq!(dst, [0, 0, 0, 42]);
3035 assert!(!42i32.encode_at(&mut [0u8; 8]));
3036 }
3037
3038 #[test]
3039 fn encode_at_i64() {
3040 let mut dst = [0u8; 8];
3041 assert!(1234567890123i64.encode_at(&mut dst));
3042 assert_eq!(dst, 1234567890123i64.to_be_bytes());
3043 assert!(!42i64.encode_at(&mut [0u8; 4]));
3044 }
3045
3046 #[test]
3047 fn encode_at_f32() {
3048 let mut dst = [0u8; 4];
3049 assert!(3.14f32.encode_at(&mut dst));
3050 assert_eq!(dst, 3.14f32.to_be_bytes());
3051 assert!(!3.14f32.encode_at(&mut [0u8; 8]));
3052 }
3053
3054 #[test]
3055 fn encode_at_f64() {
3056 let mut dst = [0u8; 8];
3057 assert!(3.14f64.encode_at(&mut dst));
3058 assert_eq!(dst, 3.14f64.to_be_bytes());
3059 assert!(!3.14f64.encode_at(&mut [0u8; 4]));
3060 }
3061
3062 #[test]
3063 fn encode_at_u32() {
3064 let mut dst = [0u8; 4];
3065 assert!(42u32.encode_at(&mut dst));
3066 assert_eq!(dst, 42u32.to_be_bytes());
3067 }
3068
3069 #[test]
3070 fn encode_at_str_default_fallback() {
3071 let s: &str = "hello";
3073 let mut dst = [0u8; 5];
3074 assert!(s.encode_at(&mut dst));
3075 assert_eq!(&dst, b"hello");
3076 assert!(!s.encode_at(&mut [0u8; 3]));
3078 }
3079
3080 #[test]
3081 fn encode_at_matches_encode_binary() {
3082 fn check<T: Encode>(val: T, expected_len: usize) {
3085 let mut buf = Vec::new();
3086 val.encode_binary(&mut buf);
3087 assert_eq!(buf.len(), expected_len);
3088 let mut dst = vec![0u8; expected_len];
3089 assert!(val.encode_at(&mut dst));
3090 assert_eq!(
3091 buf, dst,
3092 "encode_at must produce same bytes as encode_binary"
3093 );
3094 }
3095 check(true, 1);
3096 check(false, 1);
3097 check(42i16, 2);
3098 check(i16::MAX, 2);
3099 check(42i32, 4);
3100 check(i32::MIN, 4);
3101 check(42i64, 8);
3102 check(3.14f32, 4);
3103 check(3.14f64, 8);
3104 check(42u32, 4);
3105 }
3106
3107 #[test]
3110 fn str_10kb_roundtrip() {
3111 let big = "A".repeat(10 * 1024);
3112 let mut buf = Vec::new();
3113 big.as_str().encode_binary(&mut buf);
3114 assert_eq!(buf.len(), 10 * 1024);
3115 assert_eq!(decode_str(&buf).unwrap(), big);
3116 }
3117
3118 #[test]
3121 fn empty_vec_u8_encode_roundtrip() {
3122 let mut buf = Vec::new();
3123 Vec::<u8>::new().encode_binary(&mut buf);
3124 assert!(buf.is_empty(), "empty Vec<u8> should produce no bytes");
3125 assert_eq!(decode_bytes(&buf).len(), 0);
3126 }
3127
3128 #[test]
3131 fn f32_min_max_roundtrip() {
3132 let mut buf = Vec::new();
3133 f32::MIN.encode_binary(&mut buf);
3134 assert_eq!(decode_f32(&buf).unwrap(), f32::MIN);
3135
3136 buf.clear();
3137 f32::MAX.encode_binary(&mut buf);
3138 assert_eq!(decode_f32(&buf).unwrap(), f32::MAX);
3139 }
3140
3141 #[test]
3144 fn f64_min_max_roundtrip() {
3145 let mut buf = Vec::new();
3146 f64::MIN.encode_binary(&mut buf);
3147 assert_eq!(decode_f64(&buf).unwrap(), f64::MIN);
3148
3149 buf.clear();
3150 f64::MAX.encode_binary(&mut buf);
3151 assert_eq!(decode_f64(&buf).unwrap(), f64::MAX);
3152 }
3153
3154 #[test]
3157 fn i32_zero_roundtrip() {
3158 let mut buf = Vec::new();
3159 0i32.encode_binary(&mut buf);
3160 assert_eq!(decode_i32(&buf).unwrap(), 0);
3161 }
3162
3163 #[test]
3166 fn i64_zero_roundtrip() {
3167 let mut buf = Vec::new();
3168 0i64.encode_binary(&mut buf);
3169 assert_eq!(decode_i64(&buf).unwrap(), 0);
3170 }
3171
3172 #[test]
3175 fn i16_zero_roundtrip() {
3176 let mut buf = Vec::new();
3177 0i16.encode_binary(&mut buf);
3178 assert_eq!(decode_i16(&buf).unwrap(), 0);
3179 }
3180
3181 #[test]
3184 fn f32_subnormal_roundtrip() {
3185 let mut buf = Vec::new();
3186 f32::MIN_POSITIVE.encode_binary(&mut buf);
3187 assert_eq!(decode_f32(&buf).unwrap(), f32::MIN_POSITIVE);
3188 }
3189
3190 #[test]
3193 fn f64_subnormal_roundtrip() {
3194 let mut buf = Vec::new();
3195 f64::MIN_POSITIVE.encode_binary(&mut buf);
3196 assert_eq!(decode_f64(&buf).unwrap(), f64::MIN_POSITIVE);
3197 }
3198
3199 #[test]
3202 fn f32_nan_bit_preservation() {
3203 let mut buf = Vec::new();
3204 f32::NAN.encode_binary(&mut buf);
3205 let decoded = decode_f32(&buf).unwrap();
3206 assert!(decoded.is_nan());
3207 assert_eq!(decoded.to_bits(), f32::NAN.to_bits());
3209 }
3210
3211 #[test]
3214 fn f64_nan_bit_preservation() {
3215 let mut buf = Vec::new();
3216 f64::NAN.encode_binary(&mut buf);
3217 let decoded = decode_f64(&buf).unwrap();
3218 assert!(decoded.is_nan());
3219 assert_eq!(decoded.to_bits(), f64::NAN.to_bits());
3220 }
3221
3222 #[test]
3225 fn option_bool_some_roundtrip() {
3226 let val: Option<bool> = Some(true);
3227 assert!(!val.is_null());
3228 assert_eq!(val.type_oid(), 16);
3229 let mut buf = Vec::new();
3230 val.encode_binary(&mut buf);
3231 assert!(decode_bool(&buf).unwrap());
3232 }
3233
3234 #[test]
3235 fn option_bool_none_is_null() {
3236 let val: Option<bool> = None;
3237 assert!(val.is_null());
3238 assert_eq!(val.type_oid(), 16); let mut buf = Vec::new();
3240 val.encode_binary(&mut buf);
3241 assert!(buf.is_empty());
3242 }
3243
3244 #[test]
3245 fn option_i16_some_roundtrip() {
3246 let val: Option<i16> = Some(i16::MIN);
3247 assert!(!val.is_null());
3248 assert_eq!(val.type_oid(), 21);
3249 let mut buf = Vec::new();
3250 val.encode_binary(&mut buf);
3251 assert_eq!(decode_i16(&buf).unwrap(), i16::MIN);
3252 }
3253
3254 #[test]
3255 fn option_i16_none_is_null() {
3256 let val: Option<i16> = None;
3257 assert!(val.is_null());
3258 assert_eq!(val.type_oid(), 21);
3259 let mut buf = Vec::new();
3260 val.encode_binary(&mut buf);
3261 assert!(buf.is_empty());
3262 }
3263
3264 #[test]
3265 fn option_i64_some_roundtrip() {
3266 let val: Option<i64> = Some(i64::MAX);
3267 assert!(!val.is_null());
3268 assert_eq!(val.type_oid(), 20);
3269 let mut buf = Vec::new();
3270 val.encode_binary(&mut buf);
3271 assert_eq!(decode_i64(&buf).unwrap(), i64::MAX);
3272 }
3273
3274 #[test]
3275 fn option_i64_none_is_null() {
3276 let val: Option<i64> = None;
3277 assert!(val.is_null());
3278 assert_eq!(val.type_oid(), 20);
3279 let mut buf = Vec::new();
3280 val.encode_binary(&mut buf);
3281 assert!(buf.is_empty());
3282 }
3283
3284 #[test]
3285 fn option_f32_some_roundtrip() {
3286 let val: Option<f32> = Some(f32::INFINITY);
3287 assert!(!val.is_null());
3288 assert_eq!(val.type_oid(), 700);
3289 let mut buf = Vec::new();
3290 val.encode_binary(&mut buf);
3291 assert_eq!(decode_f32(&buf).unwrap(), f32::INFINITY);
3292 }
3293
3294 #[test]
3295 fn option_f32_none_is_null() {
3296 let val: Option<f32> = None;
3297 assert!(val.is_null());
3298 assert_eq!(val.type_oid(), 700);
3299 let mut buf = Vec::new();
3300 val.encode_binary(&mut buf);
3301 assert!(buf.is_empty());
3302 }
3303
3304 #[test]
3305 fn option_f64_some_nan_roundtrip() {
3306 let val: Option<f64> = Some(f64::NAN);
3307 assert!(!val.is_null());
3308 assert_eq!(val.type_oid(), 701);
3309 let mut buf = Vec::new();
3310 val.encode_binary(&mut buf);
3311 assert!(decode_f64(&buf).unwrap().is_nan());
3312 }
3313
3314 #[test]
3315 fn option_f64_none_is_null() {
3316 let val: Option<f64> = None;
3317 assert!(val.is_null());
3318 assert_eq!(val.type_oid(), 701);
3319 let mut buf = Vec::new();
3320 val.encode_binary(&mut buf);
3321 assert!(buf.is_empty());
3322 }
3323
3324 #[test]
3325 fn option_string_some_roundtrip() {
3326 let val: Option<String> = Some("hello".to_owned());
3327 assert!(!val.is_null());
3328 assert_eq!(val.type_oid(), 25);
3329 let mut buf = Vec::new();
3330 val.encode_binary(&mut buf);
3331 assert_eq!(decode_str(&buf).unwrap(), "hello");
3332 }
3333
3334 #[test]
3335 fn option_string_none_is_null() {
3336 let val: Option<String> = None;
3337 assert!(val.is_null());
3338 assert_eq!(val.type_oid(), 25);
3339 let mut buf = Vec::new();
3340 val.encode_binary(&mut buf);
3341 assert!(buf.is_empty());
3342 }
3343
3344 #[test]
3345 fn option_vec_u8_some_roundtrip() {
3346 let val: Option<Vec<u8>> = Some(vec![0xDE, 0xAD]);
3347 assert!(!val.is_null());
3348 assert_eq!(val.type_oid(), 17);
3349 let mut buf = Vec::new();
3350 val.encode_binary(&mut buf);
3351 assert_eq!(decode_bytes(&buf), &[0xDE, 0xAD]);
3352 }
3353
3354 #[test]
3355 fn option_vec_u8_none_is_null() {
3356 let val: Option<Vec<u8>> = None;
3357 assert!(val.is_null());
3358 assert_eq!(val.type_oid(), 17);
3359 let mut buf = Vec::new();
3360 val.encode_binary(&mut buf);
3361 assert!(buf.is_empty());
3362 }
3363
3364 #[test]
3367 fn encode_at_vec_u8_same_size() {
3368 let v = vec![1u8, 2, 3];
3369 let mut dst = [0u8; 3];
3370 assert!(v.encode_at(&mut dst));
3371 assert_eq!(dst, [1, 2, 3]);
3372 }
3373
3374 #[test]
3375 fn encode_at_vec_u8_wrong_size() {
3376 let v = vec![1u8, 2, 3];
3377 let mut dst = [0u8; 5];
3378 assert!(!v.encode_at(&mut dst));
3379 }
3380
3381 #[test]
3382 fn encode_at_byte_slice_same_size() {
3383 let data: &[u8] = &[0xAA, 0xBB];
3384 let mut dst = [0u8; 2];
3385 assert!(data.encode_at(&mut dst));
3386 assert_eq!(dst, [0xAA, 0xBB]);
3387 }
3388
3389 #[test]
3390 fn encode_at_byte_slice_wrong_size() {
3391 let data: &[u8] = &[0xAA, 0xBB];
3392 let mut dst = [0u8; 4];
3393 assert!(!data.encode_at(&mut dst));
3394 }
3395
3396 #[test]
3397 fn encode_at_string_same_size() {
3398 let s = String::from("hi");
3399 let mut dst = [0u8; 2];
3400 assert!(s.encode_at(&mut dst));
3401 assert_eq!(&dst, b"hi");
3402 }
3403
3404 #[test]
3405 fn encode_at_string_wrong_size() {
3406 let s = String::from("hi");
3407 let mut dst = [0u8; 5];
3408 assert!(!s.encode_at(&mut dst));
3409 }
3410
3411 #[test]
3414 fn encode_param_null_option() {
3415 let val: Option<i32> = None;
3419 let mut buf = Vec::new();
3420 encode_param(&mut buf, &val);
3421 assert_eq!(buf.len(), 4);
3424 let len = i32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]);
3425 assert_eq!(len, 0);
3426 }
3427
3428 #[test]
3431 fn decode_array_negative_element_count() {
3432 let mut data = Vec::new();
3433 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);
3439 assert!(result.is_err(), "negative element count should error");
3440 assert!(result.unwrap_err().to_string().contains("negative"));
3441 }
3442
3443 #[test]
3446 fn decode_array_excessive_element_count() {
3447 let mut data = Vec::new();
3448 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);
3454 assert!(result.is_err(), "excessive element count should error");
3455 assert!(result.unwrap_err().to_string().contains("exceeds limit"));
3456 }
3457
3458 #[test]
3461 fn decode_array_header_too_short() {
3462 let data = [0u8; 8]; let result = decode_array_i32(&data);
3464 assert!(result.is_err(), "header too short should error");
3465 }
3466
3467 #[test]
3470 fn decode_array_truncated_dimension_header() {
3471 let mut data = Vec::new();
3472 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);
3477 assert!(result.is_err(), "truncated dimension header should error");
3478 }
3479
3480 mod proptest_fuzz {
3481 use super::*;
3482 use proptest::prelude::*;
3483
3484 proptest! {
3485 #[test]
3486 fn i32_roundtrip(val: i32) {
3487 let mut buf = Vec::new();
3488 val.encode_binary(&mut buf);
3489 let decoded = decode_i32(&buf).unwrap();
3490 prop_assert_eq!(decoded, val);
3491 }
3492
3493 #[test]
3494 fn i64_roundtrip(val: i64) {
3495 let mut buf = Vec::new();
3496 val.encode_binary(&mut buf);
3497 let decoded = decode_i64(&buf).unwrap();
3498 prop_assert_eq!(decoded, val);
3499 }
3500
3501 #[test]
3502 fn i16_roundtrip(val: i16) {
3503 let mut buf = Vec::new();
3504 val.encode_binary(&mut buf);
3505 let decoded = decode_i16(&buf).unwrap();
3506 prop_assert_eq!(decoded, val);
3507 }
3508
3509 #[test]
3510 fn f32_roundtrip(val: f32) {
3511 let mut buf = Vec::new();
3512 val.encode_binary(&mut buf);
3513 let decoded = decode_f32(&buf).unwrap();
3514 if val.is_nan() {
3515 prop_assert!(decoded.is_nan());
3516 } else {
3517 prop_assert_eq!(decoded, val);
3518 }
3519 }
3520
3521 #[test]
3522 fn f64_roundtrip(val: f64) {
3523 let mut buf = Vec::new();
3524 val.encode_binary(&mut buf);
3525 let decoded = decode_f64(&buf).unwrap();
3526 if val.is_nan() {
3527 prop_assert!(decoded.is_nan());
3528 } else {
3529 prop_assert_eq!(decoded, val);
3530 }
3531 }
3532
3533 #[test]
3534 fn bool_roundtrip(val: bool) {
3535 let mut buf = Vec::new();
3536 val.encode_binary(&mut buf);
3537 let decoded = decode_bool(&buf).unwrap();
3538 prop_assert_eq!(decoded, val);
3539 }
3540
3541 #[test]
3542 fn str_roundtrip(val in "\\PC*") {
3543 let mut buf = Vec::new();
3544 val.as_str().encode_binary(&mut buf);
3545 let decoded = decode_str(&buf).unwrap();
3546 prop_assert_eq!(decoded, val.as_str());
3547 }
3548
3549 #[test]
3550 fn decode_i32_arbitrary_never_panics(data in proptest::collection::vec(any::<u8>(), 0..16)) {
3551 let _ = decode_i32(&data);
3552 }
3553
3554 #[test]
3555 fn decode_str_arbitrary_never_panics(data in proptest::collection::vec(any::<u8>(), 0..1024)) {
3556 let _ = decode_str(&data);
3557 }
3558 }
3559 }
3560
3561 #[test]
3566 fn option_none_type_oid_scalars() {
3567 assert_eq!(None::<bool>.type_oid(), 16);
3569 assert_eq!(None::<i16>.type_oid(), 21);
3570 assert_eq!(None::<i32>.type_oid(), 23);
3571 assert_eq!(None::<i64>.type_oid(), 20);
3572 assert_eq!(None::<f32>.type_oid(), 700);
3573 assert_eq!(None::<f64>.type_oid(), 701);
3574 assert_eq!(None::<String>.type_oid(), 25);
3575 assert_eq!(None::<Vec<u8>>.type_oid(), 17);
3576 assert_eq!(None::<u32>.type_oid(), 26);
3577
3578 assert_eq!(Some(true).type_oid(), 16);
3580 assert_eq!(Some(0i16).type_oid(), 21);
3581 assert_eq!(Some(0i32).type_oid(), 23);
3582 assert_eq!(Some(0i64).type_oid(), 20);
3583 assert_eq!(Some(0f32).type_oid(), 700);
3584 assert_eq!(Some(0f64).type_oid(), 701);
3585 assert_eq!(Some(String::new()).type_oid(), 25);
3586 assert_eq!(Some(Vec::<u8>::new()).type_oid(), 17);
3587 assert_eq!(Some(0u32).type_oid(), 26);
3588 }
3589
3590 #[test]
3591 fn option_none_type_oid_arrays() {
3592 assert_eq!(None::<Vec<bool>>.type_oid(), 1000);
3593 assert_eq!(None::<Vec<i16>>.type_oid(), 1005);
3594 assert_eq!(None::<Vec<i32>>.type_oid(), 1007);
3595 assert_eq!(None::<Vec<i64>>.type_oid(), 1016);
3596 assert_eq!(None::<Vec<f32>>.type_oid(), 1021);
3597 assert_eq!(None::<Vec<f64>>.type_oid(), 1022);
3598 assert_eq!(None::<Vec<String>>.type_oid(), 1009);
3599 assert_eq!(None::<Vec<Vec<u8>>>.type_oid(), 1001);
3600 }
3601
3602 #[test]
3603 fn option_none_type_oid_nested_option() {
3604 assert_eq!(None::<Option<i32>>.type_oid(), 23);
3606 assert_eq!(Some(None::<i32>).type_oid(), 23);
3607 assert_eq!(Some(Some(42i32)).type_oid(), 23);
3608 }
3609
3610 #[cfg(feature = "uuid")]
3611 #[test]
3612 fn option_none_type_oid_uuid() {
3613 assert_eq!(None::<uuid::Uuid>.type_oid(), 2950);
3614 }
3615
3616 #[cfg(feature = "time")]
3617 #[test]
3618 fn option_none_type_oid_time() {
3619 assert_eq!(None::<time::OffsetDateTime>.type_oid(), 1184);
3620 assert_eq!(None::<time::Date>.type_oid(), 1082);
3621 assert_eq!(None::<time::Time>.type_oid(), 1083);
3622 assert_eq!(None::<time::PrimitiveDateTime>.type_oid(), 1114);
3623 }
3624
3625 #[cfg(feature = "chrono")]
3626 #[test]
3627 fn option_none_type_oid_chrono() {
3628 assert_eq!(None::<chrono::NaiveDateTime>.type_oid(), 1114);
3629 assert_eq!(None::<chrono::DateTime<chrono::Utc>>.type_oid(), 1184);
3630 assert_eq!(None::<chrono::NaiveDate>.type_oid(), 1082);
3631 assert_eq!(None::<chrono::NaiveTime>.type_oid(), 1083);
3632 }
3633
3634 #[cfg(feature = "decimal")]
3635 #[test]
3636 fn option_none_type_oid_decimal() {
3637 assert_eq!(None::<rust_decimal::Decimal>.type_oid(), 1700);
3638 }
3639
3640 #[test]
3641 fn pg_type_oid_static_all_types() {
3642 assert_eq!(bool::pg_type_oid(), 16);
3644 assert_eq!(i16::pg_type_oid(), 21);
3645 assert_eq!(i32::pg_type_oid(), 23);
3646 assert_eq!(i64::pg_type_oid(), 20);
3647 assert_eq!(f32::pg_type_oid(), 700);
3648 assert_eq!(f64::pg_type_oid(), 701);
3649 assert_eq!(<&str>::pg_type_oid(), 25);
3650 assert_eq!(String::pg_type_oid(), 25);
3651 assert_eq!(<&[u8]>::pg_type_oid(), 17);
3652 assert_eq!(Vec::<u8>::pg_type_oid(), 17);
3653 assert_eq!(u32::pg_type_oid(), 26);
3654
3655 assert_eq!(<Option<i32>>::pg_type_oid(), 23);
3657 assert_eq!(<Option<String>>::pg_type_oid(), 25);
3658 assert_eq!(<Option<bool>>::pg_type_oid(), 16);
3659 assert_eq!(<Option<i64>>::pg_type_oid(), 20);
3660 assert_eq!(<Option<f64>>::pg_type_oid(), 701);
3661 assert_eq!(<Option<Vec<u8>>>::pg_type_oid(), 17);
3662
3663 assert_eq!(<&[bool]>::pg_type_oid(), 1000);
3665 assert_eq!(Vec::<bool>::pg_type_oid(), 1000);
3666 assert_eq!(<&[i16]>::pg_type_oid(), 1005);
3667 assert_eq!(Vec::<i16>::pg_type_oid(), 1005);
3668 assert_eq!(<&[i32]>::pg_type_oid(), 1007);
3669 assert_eq!(Vec::<i32>::pg_type_oid(), 1007);
3670 assert_eq!(<&[i64]>::pg_type_oid(), 1016);
3671 assert_eq!(Vec::<i64>::pg_type_oid(), 1016);
3672 assert_eq!(<&[f32]>::pg_type_oid(), 1021);
3673 assert_eq!(Vec::<f32>::pg_type_oid(), 1021);
3674 assert_eq!(<&[f64]>::pg_type_oid(), 1022);
3675 assert_eq!(Vec::<f64>::pg_type_oid(), 1022);
3676 assert_eq!(<&[&str]>::pg_type_oid(), 1009);
3677 assert_eq!(Vec::<String>::pg_type_oid(), 1009);
3678 assert_eq!(<&[String]>::pg_type_oid(), 1009);
3679 assert_eq!(<&[&[u8]]>::pg_type_oid(), 1001);
3680 assert_eq!(<&[Vec<u8>]>::pg_type_oid(), 1001);
3681 assert_eq!(Vec::<Vec<u8>>::pg_type_oid(), 1001);
3682 }
3683}