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