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