1use crate::DriverError;
9
10pub trait Encode {
27 fn encode_binary(&self, buf: &mut Vec<u8>);
29
30 fn type_oid(&self) -> u32;
32
33 fn is_null(&self) -> bool {
38 false
39 }
40
41 fn encode_at(&self, dst: &mut [u8]) -> bool {
51 let mut tmp = Vec::with_capacity(dst.len());
53 self.encode_binary(&mut tmp);
54 if tmp.len() == dst.len() {
55 dst.copy_from_slice(&tmp);
56 true
57 } else {
58 false
59 }
60 }
61}
62
63impl Encode for bool {
66 #[inline]
67 fn encode_binary(&self, buf: &mut Vec<u8>) {
68 buf.push(if *self { 1 } else { 0 });
69 }
70
71 #[inline]
72 fn type_oid(&self) -> u32 {
73 16 }
75
76 #[inline]
77 fn encode_at(&self, dst: &mut [u8]) -> bool {
78 if dst.len() != 1 {
79 return false;
80 }
81 dst[0] = if *self { 1 } else { 0 };
82 true
83 }
84}
85
86impl Encode for i16 {
87 #[inline]
88 fn encode_binary(&self, buf: &mut Vec<u8>) {
89 buf.extend_from_slice(&self.to_be_bytes());
90 }
91
92 #[inline]
93 fn type_oid(&self) -> u32 {
94 21 }
96
97 #[inline]
98 fn encode_at(&self, dst: &mut [u8]) -> bool {
99 if dst.len() != 2 {
100 return false;
101 }
102 dst.copy_from_slice(&self.to_be_bytes());
103 true
104 }
105}
106
107impl Encode for i32 {
108 #[inline]
109 fn encode_binary(&self, buf: &mut Vec<u8>) {
110 buf.extend_from_slice(&self.to_be_bytes());
111 }
112
113 #[inline]
114 fn type_oid(&self) -> u32 {
115 23 }
117
118 #[inline]
119 fn encode_at(&self, dst: &mut [u8]) -> bool {
120 if dst.len() != 4 {
121 return false;
122 }
123 dst.copy_from_slice(&self.to_be_bytes());
124 true
125 }
126}
127
128impl Encode for i64 {
129 #[inline]
130 fn encode_binary(&self, buf: &mut Vec<u8>) {
131 buf.extend_from_slice(&self.to_be_bytes());
132 }
133
134 #[inline]
135 fn type_oid(&self) -> u32 {
136 20 }
138
139 #[inline]
140 fn encode_at(&self, dst: &mut [u8]) -> bool {
141 if dst.len() != 8 {
142 return false;
143 }
144 dst.copy_from_slice(&self.to_be_bytes());
145 true
146 }
147}
148
149impl Encode for f32 {
150 #[inline]
151 fn encode_binary(&self, buf: &mut Vec<u8>) {
152 buf.extend_from_slice(&self.to_be_bytes());
153 }
154
155 #[inline]
156 fn type_oid(&self) -> u32 {
157 700 }
159
160 #[inline]
161 fn encode_at(&self, dst: &mut [u8]) -> bool {
162 if dst.len() != 4 {
163 return false;
164 }
165 dst.copy_from_slice(&self.to_be_bytes());
166 true
167 }
168}
169
170impl Encode for f64 {
171 #[inline]
172 fn encode_binary(&self, buf: &mut Vec<u8>) {
173 buf.extend_from_slice(&self.to_be_bytes());
174 }
175
176 #[inline]
177 fn type_oid(&self) -> u32 {
178 701 }
180
181 #[inline]
182 fn encode_at(&self, dst: &mut [u8]) -> bool {
183 if dst.len() != 8 {
184 return false;
185 }
186 dst.copy_from_slice(&self.to_be_bytes());
187 true
188 }
189}
190
191impl Encode for &str {
192 #[inline]
193 fn encode_binary(&self, buf: &mut Vec<u8>) {
194 buf.extend_from_slice(self.as_bytes());
195 }
196
197 #[inline]
198 fn type_oid(&self) -> u32 {
199 25 }
201}
202
203impl Encode for String {
204 #[inline]
205 fn encode_binary(&self, buf: &mut Vec<u8>) {
206 buf.extend_from_slice(self.as_bytes());
207 }
208
209 #[inline]
210 fn type_oid(&self) -> u32 {
211 25 }
213}
214
215impl Encode for &[u8] {
216 #[inline]
217 fn encode_binary(&self, buf: &mut Vec<u8>) {
218 buf.extend_from_slice(self);
219 }
220
221 #[inline]
222 fn type_oid(&self) -> u32 {
223 17 }
225}
226
227impl Encode for Vec<u8> {
228 #[inline]
229 fn encode_binary(&self, buf: &mut Vec<u8>) {
230 buf.extend_from_slice(self);
231 }
232
233 #[inline]
234 fn type_oid(&self) -> u32 {
235 17 }
237}
238
239impl Encode for u32 {
240 #[inline]
241 fn encode_binary(&self, buf: &mut Vec<u8>) {
242 buf.extend_from_slice(&self.to_be_bytes());
243 }
244
245 #[inline]
246 fn type_oid(&self) -> u32 {
247 26 }
249
250 #[inline]
251 fn encode_at(&self, dst: &mut [u8]) -> bool {
252 if dst.len() != 4 {
253 return false;
254 }
255 dst.copy_from_slice(&self.to_be_bytes());
256 true
257 }
258}
259
260impl<T: Encode> Encode for Option<T> {
263 #[inline]
264 fn encode_binary(&self, buf: &mut Vec<u8>) {
265 if let Some(val) = self {
266 val.encode_binary(buf);
267 }
268 }
271
272 #[inline]
273 fn type_oid(&self) -> u32 {
274 match self {
279 Some(val) => val.type_oid(),
280 None => 0,
281 }
282 }
283
284 #[inline]
285 fn is_null(&self) -> bool {
286 self.is_none()
287 }
288}
289
290#[cfg(feature = "uuid")]
293impl Encode for uuid::Uuid {
294 #[inline]
295 fn encode_binary(&self, buf: &mut Vec<u8>) {
296 buf.extend_from_slice(self.as_bytes());
297 }
298
299 #[inline]
300 fn type_oid(&self) -> u32 {
301 2950 }
303
304 #[inline]
305 fn encode_at(&self, dst: &mut [u8]) -> bool {
306 if dst.len() != 16 {
307 return false;
308 }
309 dst.copy_from_slice(self.as_bytes());
310 true
311 }
312}
313
314#[cfg(feature = "time")]
315impl Encode for time::OffsetDateTime {
316 #[inline]
317 fn encode_binary(&self, buf: &mut Vec<u8>) {
318 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
319 }
320
321 #[inline]
322 fn type_oid(&self) -> u32 {
323 1184 }
325
326 #[inline]
327 fn encode_at(&self, dst: &mut [u8]) -> bool {
328 if dst.len() != 8 {
329 return false;
330 }
331 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
332 true
333 }
334}
335
336#[cfg(feature = "time")]
337trait OffsetDateTimeExt {
338 fn encode_pg_micros(&self) -> i64;
339}
340
341#[cfg(feature = "time")]
342impl OffsetDateTimeExt for time::OffsetDateTime {
343 #[inline]
344 fn encode_pg_micros(&self) -> i64 {
345 let pg_epoch =
348 time::OffsetDateTime::from_unix_timestamp(946_684_800).expect("PG epoch is valid");
349 let diff = *self - pg_epoch;
350 let micros_128 = diff.whole_microseconds();
351 if micros_128 >= i64::MIN as i128 && micros_128 <= i64::MAX as i128 {
352 micros_128 as i64
353 } else {
354 if micros_128 < 0 { i64::MIN } else { i64::MAX }
355 }
356 }
357}
358
359#[cfg(feature = "time")]
360impl Encode for time::Date {
361 #[inline]
362 fn encode_binary(&self, buf: &mut Vec<u8>) {
363 buf.extend_from_slice(&self.encode_pg_days().to_be_bytes());
364 }
365
366 #[inline]
367 fn type_oid(&self) -> u32 {
368 1082 }
370
371 #[inline]
372 fn encode_at(&self, dst: &mut [u8]) -> bool {
373 if dst.len() != 4 {
374 return false;
375 }
376 dst.copy_from_slice(&self.encode_pg_days().to_be_bytes());
377 true
378 }
379}
380
381#[cfg(feature = "time")]
382trait DateExt {
383 fn encode_pg_days(&self) -> i32;
384}
385
386#[cfg(feature = "time")]
387impl DateExt for time::Date {
388 #[inline]
389 fn encode_pg_days(&self) -> i32 {
390 let pg_epoch = time::Date::from_calendar_date(2000, time::Month::January, 1)
392 .expect("PG epoch date is valid");
393 let days_i64 = (*self - pg_epoch).whole_days();
394 i32::try_from(days_i64).unwrap_or(if days_i64 < 0 { i32::MIN } else { i32::MAX })
395 }
396}
397
398#[cfg(feature = "time")]
399impl Encode for time::Time {
400 #[inline]
401 fn encode_binary(&self, buf: &mut Vec<u8>) {
402 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
403 }
404
405 #[inline]
406 fn type_oid(&self) -> u32 {
407 1083 }
409
410 #[inline]
411 fn encode_at(&self, dst: &mut [u8]) -> bool {
412 if dst.len() != 8 {
413 return false;
414 }
415 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
416 true
417 }
418}
419
420#[cfg(feature = "time")]
421trait TimeExt {
422 fn encode_pg_micros(&self) -> i64;
423}
424
425#[cfg(feature = "time")]
426impl TimeExt for time::Time {
427 #[inline]
428 fn encode_pg_micros(&self) -> i64 {
429 let midnight = time::Time::MIDNIGHT;
431 let diff = *self - midnight;
432 diff.whole_microseconds() as i64
433 }
434}
435
436#[cfg(feature = "time")]
437impl Encode for time::PrimitiveDateTime {
438 #[inline]
439 fn encode_binary(&self, buf: &mut Vec<u8>) {
440 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
441 }
442
443 #[inline]
444 fn type_oid(&self) -> u32 {
445 1114 }
447
448 #[inline]
449 fn encode_at(&self, dst: &mut [u8]) -> bool {
450 if dst.len() != 8 {
451 return false;
452 }
453 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
454 true
455 }
456}
457
458#[cfg(feature = "time")]
459trait PrimitiveDateTimeExt {
460 fn encode_pg_micros(&self) -> i64;
461}
462
463#[cfg(feature = "time")]
464impl PrimitiveDateTimeExt for time::PrimitiveDateTime {
465 #[inline]
466 fn encode_pg_micros(&self) -> i64 {
467 let pg_epoch =
470 time::OffsetDateTime::from_unix_timestamp(946_684_800).expect("PG epoch is valid");
471 let as_utc = self.assume_utc();
472 let diff = as_utc - pg_epoch;
473 let micros_128 = diff.whole_microseconds();
474 if micros_128 >= i64::MIN as i128 && micros_128 <= i64::MAX as i128 {
475 micros_128 as i64
476 } else {
477 if micros_128 < 0 { i64::MIN } else { i64::MAX }
478 }
479 }
480}
481
482#[cfg(feature = "chrono")]
483impl Encode for chrono::NaiveDateTime {
484 #[inline]
485 fn encode_binary(&self, buf: &mut Vec<u8>) {
486 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
487 }
488
489 #[inline]
490 fn type_oid(&self) -> u32 {
491 1114 }
493
494 #[inline]
495 fn encode_at(&self, dst: &mut [u8]) -> bool {
496 if dst.len() != 8 {
497 return false;
498 }
499 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
500 true
501 }
502}
503
504#[cfg(feature = "chrono")]
505trait NaiveDateTimeExt {
506 fn encode_pg_micros(&self) -> i64;
507}
508
509#[cfg(feature = "chrono")]
510impl NaiveDateTimeExt for chrono::NaiveDateTime {
511 #[inline]
512 fn encode_pg_micros(&self) -> i64 {
513 let pg_epoch_unix_micros: i64 = 946_684_800 * 1_000_000;
515 let unix_micros = self.and_utc().timestamp_micros();
516 unix_micros.saturating_sub(pg_epoch_unix_micros)
517 }
518}
519
520#[cfg(feature = "chrono")]
521impl Encode for chrono::DateTime<chrono::Utc> {
522 #[inline]
523 fn encode_binary(&self, buf: &mut Vec<u8>) {
524 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
525 }
526
527 #[inline]
528 fn type_oid(&self) -> u32 {
529 1184 }
531
532 #[inline]
533 fn encode_at(&self, dst: &mut [u8]) -> bool {
534 if dst.len() != 8 {
535 return false;
536 }
537 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
538 true
539 }
540}
541
542#[cfg(feature = "chrono")]
543trait ChronoDateTimeUtcExt {
544 fn encode_pg_micros(&self) -> i64;
545}
546
547#[cfg(feature = "chrono")]
548impl ChronoDateTimeUtcExt for chrono::DateTime<chrono::Utc> {
549 #[inline]
550 fn encode_pg_micros(&self) -> i64 {
551 let pg_epoch_unix_micros: i64 = 946_684_800 * 1_000_000;
553 let unix_micros = self.timestamp_micros();
554 unix_micros.saturating_sub(pg_epoch_unix_micros)
555 }
556}
557
558#[cfg(feature = "chrono")]
559impl Encode for chrono::NaiveDate {
560 #[inline]
561 fn encode_binary(&self, buf: &mut Vec<u8>) {
562 buf.extend_from_slice(&self.encode_pg_days().to_be_bytes());
563 }
564
565 #[inline]
566 fn type_oid(&self) -> u32 {
567 1082 }
569
570 #[inline]
571 fn encode_at(&self, dst: &mut [u8]) -> bool {
572 if dst.len() != 4 {
573 return false;
574 }
575 dst.copy_from_slice(&self.encode_pg_days().to_be_bytes());
576 true
577 }
578}
579
580#[cfg(feature = "chrono")]
581trait ChronoNaiveDateExt {
582 fn encode_pg_days(&self) -> i32;
583}
584
585#[cfg(feature = "chrono")]
586impl ChronoNaiveDateExt for chrono::NaiveDate {
587 #[inline]
588 fn encode_pg_days(&self) -> i32 {
589 let pg_epoch = chrono::NaiveDate::from_ymd_opt(2000, 1, 1).expect("PG epoch date valid");
590 let days_i64 = (*self - pg_epoch).num_days();
591 i32::try_from(days_i64).unwrap_or(if days_i64 < 0 { i32::MIN } else { i32::MAX })
592 }
593}
594
595#[cfg(feature = "chrono")]
596impl Encode for chrono::NaiveTime {
597 #[inline]
598 fn encode_binary(&self, buf: &mut Vec<u8>) {
599 buf.extend_from_slice(&self.encode_pg_micros().to_be_bytes());
600 }
601
602 #[inline]
603 fn type_oid(&self) -> u32 {
604 1083 }
606
607 #[inline]
608 fn encode_at(&self, dst: &mut [u8]) -> bool {
609 if dst.len() != 8 {
610 return false;
611 }
612 dst.copy_from_slice(&self.encode_pg_micros().to_be_bytes());
613 true
614 }
615}
616
617#[cfg(feature = "chrono")]
618trait ChronoNaiveTimeExt {
619 fn encode_pg_micros(&self) -> i64;
620}
621
622#[cfg(feature = "chrono")]
623impl ChronoNaiveTimeExt for chrono::NaiveTime {
624 #[inline]
625 fn encode_pg_micros(&self) -> i64 {
626 let midnight = chrono::NaiveTime::from_hms_opt(0, 0, 0).expect("midnight is always valid");
628 let diff = *self - midnight;
629 diff.num_microseconds()
631 .expect("time-of-day difference always fits i64")
632 }
633}
634
635#[cfg(feature = "decimal")]
636impl Encode for rust_decimal::Decimal {
637 fn encode_binary(&self, buf: &mut Vec<u8>) {
638 if self.is_zero() {
648 let dscale = i16::try_from(self.scale()).unwrap_or(i16::MAX);
650 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;
655 }
656
657 let sign: i16 = if self.is_sign_negative() {
658 0x4000
659 } else {
660 0x0000
661 };
662 let scale = self.scale();
663
664 let abs = self.abs();
666 let mut mantissa = abs.mantissa().unsigned_abs();
667
668 let mut decimal_digits: smallvec::SmallVec<[i16; 32]> = smallvec::SmallVec::new();
670 while mantissa > 0 {
671 decimal_digits.push((mantissa % 10) as i16);
672 mantissa /= 10;
673 }
674 decimal_digits.reverse();
675
676 let total_digits = decimal_digits.len();
680 let int_len = total_digits.saturating_sub(scale as usize);
681
682 let int_pad = if int_len > 0 {
684 (4 - (int_len % 4)) % 4
685 } else {
686 0
687 };
688 let frac_len = total_digits - int_len;
690 let frac_pad = (4 - (frac_len % 4)) % 4;
691
692 let mut padded: smallvec::SmallVec<[i16; 32]> = smallvec::SmallVec::new();
693 padded.extend(std::iter::repeat_n(0i16, int_pad));
694 padded.extend_from_slice(&decimal_digits);
695 padded.extend(std::iter::repeat_n(0i16, frac_pad));
696
697 let mut pg_digits: smallvec::SmallVec<[i16; 12]> = smallvec::SmallVec::new();
699 for chunk in padded.chunks(4) {
700 let d = chunk[0] * 1000 + chunk[1] * 100 + chunk[2] * 10 + chunk[3];
701 pg_digits.push(d);
702 }
703
704 let int_groups = (int_len + int_pad) / 4;
706 while pg_digits.len() > int_groups && pg_digits.last().copied() == Some(0) {
707 pg_digits.pop();
708 }
709
710 let ndigits = pg_digits.len() as i16;
711
712 let weight: i16 = if int_len > 0 {
714 let w = (int_len + int_pad) / 4 - 1;
715 w as i16
716 } else {
717 let w = -((scale as usize - frac_len + frac_pad) as i32 / 4 + 1);
720 w.clamp(i16::MIN as i32, i16::MAX as i32) as i16
722 };
723
724 let dscale = i16::try_from(scale).unwrap_or(i16::MAX);
725 buf.extend_from_slice(&ndigits.to_be_bytes());
726 buf.extend_from_slice(&weight.to_be_bytes());
727 buf.extend_from_slice(&sign.to_be_bytes());
728 buf.extend_from_slice(&dscale.to_be_bytes());
729 for d in &pg_digits {
730 buf.extend_from_slice(&d.to_be_bytes());
731 }
732 }
733
734 #[inline]
735 fn type_oid(&self) -> u32 {
736 1700 }
738}
739
740#[inline]
748pub fn decode_bool(data: &[u8]) -> Result<bool, DriverError> {
749 if data.len() != 1 {
750 return Err(DriverError::Protocol(format!(
751 "bool: expected 1 byte, got {}",
752 data.len()
753 )));
754 }
755 Ok(data[0] != 0)
756}
757
758#[inline]
760pub fn decode_i16(data: &[u8]) -> Result<i16, DriverError> {
761 if data.len() != 2 {
762 return Err(DriverError::Protocol(format!(
763 "i16: expected 2 bytes, got {}",
764 data.len()
765 )));
766 }
767 Ok(i16::from_be_bytes([data[0], data[1]]))
768}
769
770#[inline]
772pub fn decode_i32(data: &[u8]) -> Result<i32, DriverError> {
773 if data.len() != 4 {
774 return Err(DriverError::Protocol(format!(
775 "i32: expected 4 bytes, got {}",
776 data.len()
777 )));
778 }
779 Ok(i32::from_be_bytes([data[0], data[1], data[2], data[3]]))
780}
781
782#[inline]
784pub fn decode_i64(data: &[u8]) -> Result<i64, DriverError> {
785 if data.len() != 8 {
786 return Err(DriverError::Protocol(format!(
787 "i64: expected 8 bytes, got {}",
788 data.len()
789 )));
790 }
791 Ok(i64::from_be_bytes([
792 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
793 ]))
794}
795
796#[inline]
798pub fn decode_f32(data: &[u8]) -> Result<f32, DriverError> {
799 if data.len() != 4 {
800 return Err(DriverError::Protocol(format!(
801 "f32: expected 4 bytes, got {}",
802 data.len()
803 )));
804 }
805 Ok(f32::from_be_bytes([data[0], data[1], data[2], data[3]]))
806}
807
808#[inline]
810pub fn decode_f64(data: &[u8]) -> Result<f64, DriverError> {
811 if data.len() != 8 {
812 return Err(DriverError::Protocol(format!(
813 "f64: expected 8 bytes, got {}",
814 data.len()
815 )));
816 }
817 Ok(f64::from_be_bytes([
818 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
819 ]))
820}
821
822#[inline]
828pub fn decode_str(data: &[u8]) -> Result<&str, DriverError> {
829 simdutf8::basic::from_utf8(data)
830 .map_err(|e| DriverError::Protocol(format!("invalid UTF-8 in text column: {e}")))
831}
832
833#[inline]
835pub fn decode_bytes(data: &[u8]) -> &[u8] {
836 data
837}
838
839#[inline]
841pub fn decode_uuid(data: &[u8]) -> Result<[u8; 16], DriverError> {
842 if data.len() != 16 {
843 return Err(DriverError::Protocol(format!(
844 "uuid: expected 16 bytes, got {}",
845 data.len()
846 )));
847 }
848 let mut uuid = [0u8; 16];
849 uuid.copy_from_slice(data);
850 Ok(uuid)
851}
852
853pub fn encode_param(buf: &mut Vec<u8>, param: &dyn Encode) {
857 let start = buf.len();
858 buf.extend_from_slice(&[0u8; 4]); param.encode_binary(buf);
860 let data_len = (buf.len() - start - 4) as i32;
861 buf[start..start + 4].copy_from_slice(&data_len.to_be_bytes());
862}
863
864fn encode_array_header(buf: &mut Vec<u8>, n_elements: usize, elem_oid: u32) {
871 if n_elements == 0 {
872 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;
876 }
877 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()); }
883
884impl Encode for [bool] {
887 fn encode_binary(&self, buf: &mut Vec<u8>) {
888 encode_array_header(buf, self.len(), 16);
889 for val in self {
890 buf.extend_from_slice(&1i32.to_be_bytes()); buf.push(if *val { 1 } else { 0 });
892 }
893 }
894
895 #[inline]
896 fn type_oid(&self) -> u32 {
897 1000 }
899}
900
901impl Encode for &[bool] {
902 #[inline]
903 fn encode_binary(&self, buf: &mut Vec<u8>) {
904 (**self).encode_binary(buf);
905 }
906
907 #[inline]
908 fn type_oid(&self) -> u32 {
909 1000
910 }
911}
912
913impl Encode for Vec<bool> {
914 #[inline]
915 fn encode_binary(&self, buf: &mut Vec<u8>) {
916 self.as_slice().encode_binary(buf);
917 }
918
919 #[inline]
920 fn type_oid(&self) -> u32 {
921 1000
922 }
923}
924
925impl Encode for [i16] {
926 fn encode_binary(&self, buf: &mut Vec<u8>) {
927 encode_array_header(buf, self.len(), 21);
928 for val in self {
929 buf.extend_from_slice(&2i32.to_be_bytes()); buf.extend_from_slice(&val.to_be_bytes());
931 }
932 }
933
934 #[inline]
935 fn type_oid(&self) -> u32 {
936 1005 }
938}
939
940impl Encode for &[i16] {
941 #[inline]
942 fn encode_binary(&self, buf: &mut Vec<u8>) {
943 (**self).encode_binary(buf);
944 }
945
946 #[inline]
947 fn type_oid(&self) -> u32 {
948 1005
949 }
950}
951
952impl Encode for Vec<i16> {
953 #[inline]
954 fn encode_binary(&self, buf: &mut Vec<u8>) {
955 self.as_slice().encode_binary(buf);
956 }
957
958 #[inline]
959 fn type_oid(&self) -> u32 {
960 1005
961 }
962}
963
964impl Encode for [i32] {
965 fn encode_binary(&self, buf: &mut Vec<u8>) {
966 encode_array_header(buf, self.len(), 23);
967 for val in self {
968 buf.extend_from_slice(&4i32.to_be_bytes()); buf.extend_from_slice(&val.to_be_bytes());
970 }
971 }
972
973 #[inline]
974 fn type_oid(&self) -> u32 {
975 1007 }
977}
978
979impl Encode for &[i32] {
980 #[inline]
981 fn encode_binary(&self, buf: &mut Vec<u8>) {
982 (**self).encode_binary(buf);
983 }
984
985 #[inline]
986 fn type_oid(&self) -> u32 {
987 1007
988 }
989}
990
991impl Encode for Vec<i32> {
992 #[inline]
993 fn encode_binary(&self, buf: &mut Vec<u8>) {
994 self.as_slice().encode_binary(buf);
995 }
996
997 #[inline]
998 fn type_oid(&self) -> u32 {
999 1007
1000 }
1001}
1002
1003impl Encode for [i64] {
1004 fn encode_binary(&self, buf: &mut Vec<u8>) {
1005 encode_array_header(buf, self.len(), 20);
1006 for val in self {
1007 buf.extend_from_slice(&8i32.to_be_bytes()); buf.extend_from_slice(&val.to_be_bytes());
1009 }
1010 }
1011
1012 #[inline]
1013 fn type_oid(&self) -> u32 {
1014 1016 }
1016}
1017
1018impl Encode for &[i64] {
1019 #[inline]
1020 fn encode_binary(&self, buf: &mut Vec<u8>) {
1021 (**self).encode_binary(buf);
1022 }
1023
1024 #[inline]
1025 fn type_oid(&self) -> u32 {
1026 1016
1027 }
1028}
1029
1030impl Encode for Vec<i64> {
1031 #[inline]
1032 fn encode_binary(&self, buf: &mut Vec<u8>) {
1033 self.as_slice().encode_binary(buf);
1034 }
1035
1036 #[inline]
1037 fn type_oid(&self) -> u32 {
1038 1016
1039 }
1040}
1041
1042impl Encode for [f32] {
1043 fn encode_binary(&self, buf: &mut Vec<u8>) {
1044 encode_array_header(buf, self.len(), 700);
1045 for val in self {
1046 buf.extend_from_slice(&4i32.to_be_bytes()); buf.extend_from_slice(&val.to_be_bytes());
1048 }
1049 }
1050
1051 #[inline]
1052 fn type_oid(&self) -> u32 {
1053 1021 }
1055}
1056
1057impl Encode for &[f32] {
1058 #[inline]
1059 fn encode_binary(&self, buf: &mut Vec<u8>) {
1060 (**self).encode_binary(buf);
1061 }
1062
1063 #[inline]
1064 fn type_oid(&self) -> u32 {
1065 1021
1066 }
1067}
1068
1069impl Encode for Vec<f32> {
1070 #[inline]
1071 fn encode_binary(&self, buf: &mut Vec<u8>) {
1072 self.as_slice().encode_binary(buf);
1073 }
1074
1075 #[inline]
1076 fn type_oid(&self) -> u32 {
1077 1021
1078 }
1079}
1080
1081impl Encode for [f64] {
1082 fn encode_binary(&self, buf: &mut Vec<u8>) {
1083 encode_array_header(buf, self.len(), 701);
1084 for val in self {
1085 buf.extend_from_slice(&8i32.to_be_bytes()); buf.extend_from_slice(&val.to_be_bytes());
1087 }
1088 }
1089
1090 #[inline]
1091 fn type_oid(&self) -> u32 {
1092 1022 }
1094}
1095
1096impl Encode for &[f64] {
1097 #[inline]
1098 fn encode_binary(&self, buf: &mut Vec<u8>) {
1099 (**self).encode_binary(buf);
1100 }
1101
1102 #[inline]
1103 fn type_oid(&self) -> u32 {
1104 1022
1105 }
1106}
1107
1108impl Encode for Vec<f64> {
1109 #[inline]
1110 fn encode_binary(&self, buf: &mut Vec<u8>) {
1111 self.as_slice().encode_binary(buf);
1112 }
1113
1114 #[inline]
1115 fn type_oid(&self) -> u32 {
1116 1022
1117 }
1118}
1119
1120impl Encode for [&str] {
1121 fn encode_binary(&self, buf: &mut Vec<u8>) {
1122 encode_array_header(buf, self.len(), 25);
1123 for val in self {
1124 let bytes = val.as_bytes();
1125 buf.extend_from_slice(&(bytes.len() as i32).to_be_bytes());
1126 buf.extend_from_slice(bytes);
1127 }
1128 }
1129
1130 #[inline]
1131 fn type_oid(&self) -> u32 {
1132 1009 }
1134}
1135
1136impl Encode for &[&str] {
1137 #[inline]
1138 fn encode_binary(&self, buf: &mut Vec<u8>) {
1139 (**self).encode_binary(buf);
1140 }
1141
1142 #[inline]
1143 fn type_oid(&self) -> u32 {
1144 1009
1145 }
1146}
1147
1148impl Encode for Vec<String> {
1149 fn encode_binary(&self, buf: &mut Vec<u8>) {
1150 encode_array_header(buf, self.len(), 25);
1151 for val in self {
1152 let bytes = val.as_bytes();
1153 buf.extend_from_slice(&(bytes.len() as i32).to_be_bytes());
1154 buf.extend_from_slice(bytes);
1155 }
1156 }
1157
1158 #[inline]
1159 fn type_oid(&self) -> u32 {
1160 1009 }
1162}
1163
1164impl Encode for [&[u8]] {
1165 fn encode_binary(&self, buf: &mut Vec<u8>) {
1166 encode_array_header(buf, self.len(), 17);
1167 for val in self {
1168 buf.extend_from_slice(&(val.len() as i32).to_be_bytes());
1169 buf.extend_from_slice(val);
1170 }
1171 }
1172
1173 #[inline]
1174 fn type_oid(&self) -> u32 {
1175 1001 }
1177}
1178
1179impl Encode for &[&[u8]] {
1180 #[inline]
1181 fn encode_binary(&self, buf: &mut Vec<u8>) {
1182 (**self).encode_binary(buf);
1183 }
1184
1185 #[inline]
1186 fn type_oid(&self) -> u32 {
1187 1001
1188 }
1189}
1190
1191impl Encode for [Vec<u8>] {
1192 fn encode_binary(&self, buf: &mut Vec<u8>) {
1193 encode_array_header(buf, self.len(), 17);
1194 for val in self {
1195 buf.extend_from_slice(&(val.len() as i32).to_be_bytes());
1196 buf.extend_from_slice(val);
1197 }
1198 }
1199
1200 #[inline]
1201 fn type_oid(&self) -> u32 {
1202 1001 }
1204}
1205
1206impl Encode for &[Vec<u8>] {
1207 #[inline]
1208 fn encode_binary(&self, buf: &mut Vec<u8>) {
1209 (**self).encode_binary(buf);
1210 }
1211
1212 #[inline]
1213 fn type_oid(&self) -> u32 {
1214 1001
1215 }
1216}
1217
1218impl Encode for Vec<Vec<u8>> {
1219 #[inline]
1220 fn encode_binary(&self, buf: &mut Vec<u8>) {
1221 self.as_slice().encode_binary(buf);
1222 }
1223
1224 #[inline]
1225 fn type_oid(&self) -> u32 {
1226 1001 }
1228}
1229
1230fn decode_array_elements(data: &[u8]) -> Result<Vec<&[u8]>, DriverError> {
1241 if data.len() < 12 {
1242 return Err(DriverError::Protocol(format!(
1243 "array: expected >= 12 bytes header, got {}",
1244 data.len()
1245 )));
1246 }
1247 let ndim = i32::from_be_bytes([data[0], data[1], data[2], data[3]]);
1248 if ndim == 0 {
1249 return Ok(Vec::new());
1250 }
1251 if ndim != 1 {
1252 return Err(DriverError::Protocol(format!(
1253 "array: only 1-dimensional arrays supported, got {ndim}"
1254 )));
1255 }
1256 if data.len() < 20 {
1258 return Err(DriverError::Protocol(
1259 "array: truncated dimension header".into(),
1260 ));
1261 }
1262 let n_elements_raw = i32::from_be_bytes([data[12], data[13], data[14], data[15]]);
1263 if n_elements_raw < 0 {
1264 return Err(DriverError::Protocol(
1265 "array: negative element count".into(),
1266 ));
1267 }
1268 let n_elements = n_elements_raw as usize;
1269 let mut pos = 20;
1271 let mut elements = Vec::with_capacity(n_elements);
1272 for _ in 0..n_elements {
1273 if pos + 4 > data.len() {
1274 return Err(DriverError::Protocol("array: truncated element".into()));
1275 }
1276 let elem_len = i32::from_be_bytes([data[pos], data[pos + 1], data[pos + 2], data[pos + 3]]);
1277 pos += 4;
1278 if elem_len < 0 {
1279 continue;
1281 }
1282 let elem_len = elem_len as usize;
1283 if pos + elem_len > data.len() {
1284 return Err(DriverError::Protocol(
1285 "array: truncated element data".into(),
1286 ));
1287 }
1288 elements.push(&data[pos..pos + elem_len]);
1289 pos += elem_len;
1290 }
1291 Ok(elements)
1292}
1293
1294pub fn decode_array_i32(data: &[u8]) -> Result<Vec<i32>, DriverError> {
1296 decode_array_elements(data)?
1297 .into_iter()
1298 .map(decode_i32)
1299 .collect()
1300}
1301
1302pub fn decode_array_i16(data: &[u8]) -> Result<Vec<i16>, DriverError> {
1304 decode_array_elements(data)?
1305 .into_iter()
1306 .map(decode_i16)
1307 .collect()
1308}
1309
1310pub fn decode_array_i64(data: &[u8]) -> Result<Vec<i64>, DriverError> {
1312 decode_array_elements(data)?
1313 .into_iter()
1314 .map(decode_i64)
1315 .collect()
1316}
1317
1318pub fn decode_array_f32(data: &[u8]) -> Result<Vec<f32>, DriverError> {
1320 decode_array_elements(data)?
1321 .into_iter()
1322 .map(decode_f32)
1323 .collect()
1324}
1325
1326pub fn decode_array_f64(data: &[u8]) -> Result<Vec<f64>, DriverError> {
1328 decode_array_elements(data)?
1329 .into_iter()
1330 .map(decode_f64)
1331 .collect()
1332}
1333
1334pub fn decode_array_bool(data: &[u8]) -> Result<Vec<bool>, DriverError> {
1336 decode_array_elements(data)?
1337 .into_iter()
1338 .map(decode_bool)
1339 .collect()
1340}
1341
1342pub fn decode_array_str(data: &[u8]) -> Result<Vec<String>, DriverError> {
1344 decode_array_elements(data)?
1345 .into_iter()
1346 .map(|d| decode_str(d).map(|s| s.to_owned()))
1347 .collect()
1348}
1349
1350pub fn decode_array_bytea(data: &[u8]) -> Result<Vec<Vec<u8>>, DriverError> {
1352 Ok(decode_array_elements(data)?
1353 .into_iter()
1354 .map(|d| d.to_vec())
1355 .collect())
1356}
1357
1358#[cfg(feature = "uuid")]
1362#[inline]
1363pub fn decode_uuid_type(data: &[u8]) -> Result<uuid::Uuid, DriverError> {
1364 let bytes = decode_uuid(data)?;
1365 Ok(uuid::Uuid::from_bytes(bytes))
1366}
1367
1368#[cfg(feature = "time")]
1370#[inline]
1371pub fn decode_timestamptz_time(data: &[u8]) -> Result<time::OffsetDateTime, DriverError> {
1372 let micros = decode_i64(data)?;
1373 let unix_micros = micros + 946_684_800i64 * 1_000_000;
1375 let secs = unix_micros.div_euclid(1_000_000);
1376 let nanos = (unix_micros.rem_euclid(1_000_000) * 1000) as i128;
1377 time::OffsetDateTime::from_unix_timestamp_nanos(secs as i128 * 1_000_000_000 + nanos)
1378 .map_err(|e| DriverError::Protocol(format!("timestamptz decode: {e}")))
1379}
1380
1381#[cfg(feature = "time")]
1383#[inline]
1384pub fn decode_date_time(data: &[u8]) -> Result<time::Date, DriverError> {
1385 let days = decode_i32(data)?;
1386 let pg_epoch = time::Date::from_calendar_date(2000, time::Month::January, 1)
1387 .expect("PG epoch date is valid");
1388 pg_epoch
1389 .checked_add(time::Duration::days(days as i64))
1390 .ok_or_else(|| DriverError::Protocol(format!("date out of range: {days} days")))
1391}
1392
1393#[cfg(feature = "time")]
1395#[inline]
1396pub fn decode_time_time(data: &[u8]) -> Result<time::Time, DriverError> {
1397 let micros = decode_i64(data)?;
1398
1399 if !(0..86_400_000_000).contains(µs) {
1401 return Err(DriverError::Protocol(format!(
1402 "time out of range: {micros}us (must be 0..86_400_000_000)"
1403 )));
1404 }
1405 let total_secs = micros / 1_000_000;
1406 let h = (total_secs / 3600) as u8;
1407 let m = ((total_secs % 3600) / 60) as u8;
1408 let s = (total_secs % 60) as u8;
1409 let micro = (micros % 1_000_000) as u32;
1410 time::Time::from_hms_micro(h, m, s, micro)
1411 .map_err(|e| DriverError::Protocol(format!("time decode: {e}")))
1412}
1413
1414#[cfg(feature = "chrono")]
1416#[inline]
1417pub fn decode_timestamptz_chrono(
1418 data: &[u8],
1419) -> Result<chrono::DateTime<chrono::Utc>, DriverError> {
1420 let micros = decode_i64(data)?;
1421 let pg_epoch_unix_micros: i64 = 946_684_800 * 1_000_000;
1422 let unix_micros = micros + pg_epoch_unix_micros;
1423 let secs = unix_micros.div_euclid(1_000_000);
1424 let nsecs = (unix_micros.rem_euclid(1_000_000) * 1000) as u32;
1425 chrono::DateTime::from_timestamp(secs, nsecs)
1426 .ok_or_else(|| DriverError::Protocol(format!("timestamptz out of range: {micros}us")))
1427}
1428
1429#[cfg(feature = "chrono")]
1431#[inline]
1432pub fn decode_date_chrono(data: &[u8]) -> Result<chrono::NaiveDate, DriverError> {
1433 let days = decode_i32(data)?;
1434 let pg_epoch = chrono::NaiveDate::from_ymd_opt(2000, 1, 1).expect("PG epoch valid");
1435
1436 let result = if days >= 0 {
1438 pg_epoch.checked_add_days(chrono::Days::new(days as u64))
1439 } else {
1440 pg_epoch.checked_sub_days(chrono::Days::new(days.unsigned_abs() as u64))
1441 };
1442 result.ok_or_else(|| DriverError::Protocol(format!("date out of range: {days} days")))
1443}
1444
1445#[cfg(feature = "chrono")]
1447#[inline]
1448pub fn decode_time_chrono(data: &[u8]) -> Result<chrono::NaiveTime, DriverError> {
1449 let micros = decode_i64(data)?;
1450
1451 if !(0..86_400_000_000).contains(µs) {
1453 return Err(DriverError::Protocol(format!(
1454 "time out of range: {micros}us (must be 0..86_400_000_000)"
1455 )));
1456 }
1457 let total_secs = (micros / 1_000_000) as u32;
1458 let micro = (micros % 1_000_000) as u32;
1459 chrono::NaiveTime::from_num_seconds_from_midnight_opt(total_secs, micro * 1000)
1460 .ok_or_else(|| DriverError::Protocol(format!("time out of range: {micros}us")))
1461}
1462
1463#[cfg(feature = "decimal")]
1470pub fn decode_numeric_decimal(data: &[u8]) -> Result<rust_decimal::Decimal, DriverError> {
1471 if data.len() < 8 {
1472 return Err(DriverError::Protocol(format!(
1473 "numeric: expected >= 8 bytes header, got {}",
1474 data.len()
1475 )));
1476 }
1477 let ndigits = i16::from_be_bytes([data[0], data[1]]) as usize;
1478 let weight = i16::from_be_bytes([data[2], data[3]]) as i32;
1479 let sign = i16::from_be_bytes([data[4], data[5]]);
1480 let _dscale = i16::from_be_bytes([data[6], data[7]]) as u32;
1481
1482 if data.len() != 8 + ndigits * 2 {
1483 return Err(DriverError::Protocol(format!(
1484 "numeric: expected {} bytes, got {}",
1485 8 + ndigits * 2,
1486 data.len()
1487 )));
1488 }
1489
1490 if ndigits == 0 {
1491 return Ok(rust_decimal::Decimal::ZERO);
1492 }
1493
1494 let mut digits: smallvec::SmallVec<[i64; 16]> = smallvec::SmallVec::with_capacity(ndigits);
1496 for i in 0..ndigits {
1497 let off = 8 + i * 2;
1498 digits.push(i16::from_be_bytes([data[off], data[off + 1]]) as i64);
1499 }
1500
1501 let mut mantissa: u128 = 0;
1504 for &d in &digits {
1505 mantissa = mantissa
1506 .checked_mul(10_000)
1507 .and_then(|m| m.checked_add(d as u128))
1508 .ok_or_else(|| DriverError::Protocol("numeric value too large for Decimal".into()))?;
1509 }
1510
1511 let exponent = 4 * (weight - ndigits as i32 + 1);
1515 let result = if exponent >= 0 {
1516 let factor = 10u128
1518 .checked_pow(exponent as u32)
1519 .ok_or_else(|| DriverError::Protocol("numeric exponent too large".into()))?;
1520 let m = mantissa
1521 .checked_mul(factor)
1522 .ok_or_else(|| DriverError::Protocol("numeric value too large for Decimal".into()))?;
1523 if m > u128::from(u64::MAX) {
1524 let s = m.to_string();
1526 s.parse::<rust_decimal::Decimal>()
1527 .map_err(|e| DriverError::Protocol(format!("numeric parse error: {e}")))?
1528 } else {
1529 rust_decimal::Decimal::from_i128_with_scale(m as i128, 0)
1530 }
1531 } else {
1532 let scale = (-exponent) as u32;
1534 if mantissa <= u128::from(u64::MAX) {
1536 rust_decimal::Decimal::from_i128_with_scale(mantissa as i128, scale)
1537 } else {
1538 let mut s = mantissa.to_string();
1540 if scale as usize >= s.len() {
1541 let zeros = scale as usize - s.len() + 1;
1542 s = format!("0.{}{s}", "0".repeat(zeros));
1543 } else {
1544 let dot_pos = s.len() - scale as usize;
1545 s.insert(dot_pos, '.');
1546 }
1547 s.parse::<rust_decimal::Decimal>()
1548 .map_err(|e| DriverError::Protocol(format!("numeric parse error: {e}")))?
1549 }
1550 };
1551
1552 if sign == 0x4000 {
1553 Ok(-result)
1554 } else {
1555 Ok(result)
1556 }
1557}
1558
1559#[cfg(test)]
1560#[allow(clippy::approx_constant)]
1561mod tests {
1562 use super::*;
1563
1564 #[test]
1567 fn bool_roundtrip() {
1568 let mut buf = Vec::new();
1569 true.encode_binary(&mut buf);
1570 assert!(decode_bool(&buf).unwrap());
1571
1572 buf.clear();
1573 false.encode_binary(&mut buf);
1574 assert!(!decode_bool(&buf).unwrap());
1575 }
1576
1577 #[test]
1578 fn i16_roundtrip() {
1579 let mut buf = Vec::new();
1580 12345i16.encode_binary(&mut buf);
1581 assert_eq!(decode_i16(&buf).unwrap(), 12345);
1582
1583 buf.clear();
1584 (-1i16).encode_binary(&mut buf);
1585 assert_eq!(decode_i16(&buf).unwrap(), -1);
1586
1587 buf.clear();
1588 i16::MIN.encode_binary(&mut buf);
1589 assert_eq!(decode_i16(&buf).unwrap(), i16::MIN);
1590
1591 buf.clear();
1592 i16::MAX.encode_binary(&mut buf);
1593 assert_eq!(decode_i16(&buf).unwrap(), i16::MAX);
1594 }
1595
1596 #[test]
1597 fn i32_roundtrip() {
1598 let mut buf = Vec::new();
1599 42i32.encode_binary(&mut buf);
1600 assert_eq!(buf, &[0, 0, 0, 42]);
1601 assert_eq!(decode_i32(&buf).unwrap(), 42);
1602
1603 buf.clear();
1604 i32::MAX.encode_binary(&mut buf);
1605 assert_eq!(decode_i32(&buf).unwrap(), i32::MAX);
1606
1607 buf.clear();
1608 i32::MIN.encode_binary(&mut buf);
1609 assert_eq!(decode_i32(&buf).unwrap(), i32::MIN);
1610 }
1611
1612 #[test]
1613 fn i64_roundtrip() {
1614 let mut buf = Vec::new();
1615 1234567890123i64.encode_binary(&mut buf);
1616 assert_eq!(decode_i64(&buf).unwrap(), 1234567890123);
1617 }
1618
1619 #[test]
1620 fn f32_roundtrip() {
1621 let mut buf = Vec::new();
1622 3.14f32.encode_binary(&mut buf);
1623 let decoded = decode_f32(&buf).unwrap();
1624 assert!((decoded - 3.14).abs() < f32::EPSILON);
1625 }
1626
1627 #[test]
1628 fn f64_roundtrip() {
1629 let mut buf = Vec::new();
1630 std::f64::consts::PI.encode_binary(&mut buf);
1631 let decoded = decode_f64(&buf).unwrap();
1632 assert!((decoded - std::f64::consts::PI).abs() < f64::EPSILON);
1633 }
1634
1635 #[test]
1636 fn str_roundtrip() {
1637 let mut buf = Vec::new();
1638 "hello world".encode_binary(&mut buf);
1639 assert_eq!(decode_str(&buf).unwrap(), "hello world");
1640 }
1641
1642 #[test]
1643 fn string_roundtrip() {
1644 let mut buf = Vec::new();
1645 let s = String::from("test string");
1646 s.encode_binary(&mut buf);
1647 assert_eq!(decode_str(&buf).unwrap(), "test string");
1648 }
1649
1650 #[test]
1651 fn bytes_roundtrip() {
1652 let mut buf = Vec::new();
1653 let data: &[u8] = &[0xDE, 0xAD, 0xBE, 0xEF];
1654 data.encode_binary(&mut buf);
1655 assert_eq!(decode_bytes(&buf), data);
1656 }
1657
1658 #[test]
1659 fn vec_u8_roundtrip() {
1660 let mut buf = Vec::new();
1661 let data = vec![1u8, 2, 3, 4, 5];
1662 data.encode_binary(&mut buf);
1663 assert_eq!(decode_bytes(&buf), &[1, 2, 3, 4, 5]);
1664 }
1665
1666 #[test]
1667 fn u32_encode() {
1668 let mut buf = Vec::new();
1669 42u32.encode_binary(&mut buf);
1670 assert_eq!(buf, &[0, 0, 0, 42]);
1671 }
1672
1673 #[test]
1674 fn uuid_roundtrip() {
1675 let uuid_bytes: [u8; 16] = [
1676 0x55, 0x0e, 0x84, 0x00, 0xe2, 0x9b, 0x41, 0xd4, 0xa7, 0x16, 0x44, 0x66, 0x55, 0x44,
1677 0x00, 0x00,
1678 ];
1679 let decoded = decode_uuid(&uuid_bytes).unwrap();
1680 assert_eq!(decoded, uuid_bytes);
1681 }
1682
1683 #[test]
1686 fn decode_bool_wrong_length() {
1687 assert!(decode_bool(&[]).is_err());
1688 assert!(decode_bool(&[0, 0]).is_err());
1689 }
1690
1691 #[test]
1692 fn decode_i32_wrong_length() {
1693 assert!(decode_i32(&[0, 0, 0]).is_err());
1694 assert!(decode_i32(&[0, 0, 0, 0, 0]).is_err());
1695 }
1696
1697 #[test]
1698 fn decode_i64_wrong_length() {
1699 assert!(decode_i64(&[0; 7]).is_err());
1700 assert!(decode_i64(&[0; 9]).is_err());
1701 }
1702
1703 #[test]
1704 fn decode_f32_wrong_length() {
1705 assert!(decode_f32(&[0; 3]).is_err());
1706 }
1707
1708 #[test]
1709 fn decode_f64_wrong_length() {
1710 assert!(decode_f64(&[0; 7]).is_err());
1711 }
1712
1713 #[test]
1714 fn decode_str_invalid_utf8() {
1715 assert!(decode_str(&[0xFF, 0xFE]).is_err());
1716 }
1717
1718 #[test]
1719 fn decode_uuid_wrong_length() {
1720 assert!(decode_uuid(&[0; 15]).is_err());
1721 assert!(decode_uuid(&[0; 17]).is_err());
1722 }
1723
1724 #[test]
1725 fn empty_str_decode() {
1726 assert_eq!(decode_str(&[]).unwrap(), "");
1727 }
1728
1729 #[test]
1730 fn empty_bytes_decode() {
1731 assert_eq!(decode_bytes(&[]).len(), 0);
1732 }
1733
1734 #[test]
1737 fn type_oids_correct() {
1738 assert_eq!(true.type_oid(), 16);
1739 assert_eq!(0i16.type_oid(), 21);
1740 assert_eq!(0i32.type_oid(), 23);
1741 assert_eq!(0i64.type_oid(), 20);
1742 assert_eq!(0f32.type_oid(), 700);
1743 assert_eq!(0f64.type_oid(), 701);
1744 assert_eq!("".type_oid(), 25);
1745 assert_eq!(String::new().type_oid(), 25);
1746 let b: &[u8] = &[];
1747 assert_eq!(b.type_oid(), 17);
1748 assert_eq!(Vec::<u8>::new().type_oid(), 17);
1749 assert_eq!(0u32.type_oid(), 26);
1750 }
1751
1752 #[test]
1755 fn encode_param_i32() {
1756 let mut buf = Vec::new();
1757 encode_param(&mut buf, &42i32);
1758 assert_eq!(buf.len(), 8);
1760 let len = i32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]);
1761 assert_eq!(len, 4);
1762 let val = i32::from_be_bytes([buf[4], buf[5], buf[6], buf[7]]);
1763 assert_eq!(val, 42);
1764 }
1765
1766 #[test]
1767 fn encode_param_str() {
1768 let mut buf = Vec::new();
1769 encode_param(&mut buf, &"hello");
1770 assert_eq!(buf.len(), 9);
1772 let len = i32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]);
1773 assert_eq!(len, 5);
1774 assert_eq!(&buf[4..], b"hello");
1775 }
1776
1777 #[test]
1778 fn option_none_is_null() {
1779 let val: Option<i32> = None;
1780 assert!(val.is_null());
1781 assert_eq!(val.type_oid(), 0);
1782 }
1783
1784 #[test]
1785 fn option_some_encodes() {
1786 let val: Option<i32> = Some(42);
1787 assert!(!val.is_null());
1788 assert_eq!(val.type_oid(), 23);
1789 let mut buf = Vec::new();
1790 val.encode_binary(&mut buf);
1791 assert_eq!(buf, &[0, 0, 0, 42]);
1792 }
1793
1794 #[test]
1795 fn option_none_encode_is_noop() {
1796 let val: Option<i32> = None;
1797 let mut buf = Vec::new();
1798 val.encode_binary(&mut buf);
1799 assert!(buf.is_empty(), "None encode should produce no bytes");
1800 }
1801
1802 #[test]
1806 fn decode_i16_wrong_length() {
1807 assert!(decode_i16(&[]).is_err());
1808 assert!(decode_i16(&[0]).is_err());
1809 assert!(decode_i16(&[0, 0, 0]).is_err());
1810 }
1811
1812 #[test]
1814 fn f32_nan_roundtrip() {
1815 let mut buf = Vec::new();
1816 f32::NAN.encode_binary(&mut buf);
1817 let decoded = decode_f32(&buf).unwrap();
1818 assert!(decoded.is_nan(), "NaN should survive roundtrip");
1819 }
1820
1821 #[test]
1823 fn f64_nan_roundtrip() {
1824 let mut buf = Vec::new();
1825 f64::NAN.encode_binary(&mut buf);
1826 let decoded = decode_f64(&buf).unwrap();
1827 assert!(decoded.is_nan(), "NaN should survive roundtrip");
1828 }
1829
1830 #[test]
1832 fn f32_infinity_roundtrip() {
1833 let mut buf = Vec::new();
1834 f32::INFINITY.encode_binary(&mut buf);
1835 assert_eq!(decode_f32(&buf).unwrap(), f32::INFINITY);
1836
1837 buf.clear();
1838 f32::NEG_INFINITY.encode_binary(&mut buf);
1839 assert_eq!(decode_f32(&buf).unwrap(), f32::NEG_INFINITY);
1840 }
1841
1842 #[test]
1844 fn f64_infinity_roundtrip() {
1845 let mut buf = Vec::new();
1846 f64::INFINITY.encode_binary(&mut buf);
1847 assert_eq!(decode_f64(&buf).unwrap(), f64::INFINITY);
1848
1849 buf.clear();
1850 f64::NEG_INFINITY.encode_binary(&mut buf);
1851 assert_eq!(decode_f64(&buf).unwrap(), f64::NEG_INFINITY);
1852 }
1853
1854 #[test]
1856 fn f32_signed_zero_roundtrip() {
1857 let mut buf = Vec::new();
1858 0.0f32.encode_binary(&mut buf);
1859 let decoded = decode_f32(&buf).unwrap();
1860 assert_eq!(decoded.to_bits(), 0.0f32.to_bits(), "+0.0 bits must match");
1861
1862 buf.clear();
1863 (-0.0f32).encode_binary(&mut buf);
1864 let decoded = decode_f32(&buf).unwrap();
1865 assert_eq!(
1866 decoded.to_bits(),
1867 (-0.0f32).to_bits(),
1868 "-0.0 bits must match"
1869 );
1870 }
1871
1872 #[test]
1874 fn f64_signed_zero_roundtrip() {
1875 let mut buf = Vec::new();
1876 0.0f64.encode_binary(&mut buf);
1877 let decoded = decode_f64(&buf).unwrap();
1878 assert_eq!(decoded.to_bits(), 0.0f64.to_bits(), "+0.0 bits must match");
1879
1880 buf.clear();
1881 (-0.0f64).encode_binary(&mut buf);
1882 let decoded = decode_f64(&buf).unwrap();
1883 assert_eq!(
1884 decoded.to_bits(),
1885 (-0.0f64).to_bits(),
1886 "-0.0 bits must match"
1887 );
1888 }
1889
1890 #[test]
1892 fn i64_boundary_roundtrip() {
1893 let mut buf = Vec::new();
1894 i64::MIN.encode_binary(&mut buf);
1895 assert_eq!(decode_i64(&buf).unwrap(), i64::MIN);
1896
1897 buf.clear();
1898 i64::MAX.encode_binary(&mut buf);
1899 assert_eq!(decode_i64(&buf).unwrap(), i64::MAX);
1900 }
1901
1902 #[test]
1904 fn i16_boundary_standalone() {
1905 let mut buf = Vec::new();
1906 i16::MIN.encode_binary(&mut buf);
1907 assert_eq!(decode_i16(&buf).unwrap(), i16::MIN);
1908
1909 buf.clear();
1910 i16::MAX.encode_binary(&mut buf);
1911 assert_eq!(decode_i16(&buf).unwrap(), i16::MAX);
1912 }
1913
1914 #[cfg(feature = "chrono")]
1916 #[test]
1917 fn decode_date_chrono_negative_days() {
1918 let data = (-365i32).to_be_bytes();
1920 let date = decode_date_chrono(&data).unwrap();
1921 assert_eq!(date, chrono::NaiveDate::from_ymd_opt(1999, 1, 1).unwrap());
1922 }
1923
1924 #[cfg(feature = "chrono")]
1926 #[test]
1927 fn decode_date_chrono_day_zero() {
1928 let data = 0i32.to_be_bytes();
1929 let date = decode_date_chrono(&data).unwrap();
1930 assert_eq!(date, chrono::NaiveDate::from_ymd_opt(2000, 1, 1).unwrap());
1931 }
1932
1933 #[cfg(feature = "time")]
1935 #[test]
1936 fn decode_date_time_negative_days() {
1937 let data = (-1i32).to_be_bytes();
1938 let date = decode_date_time(&data).unwrap();
1939 let expected = time::Date::from_calendar_date(1999, time::Month::December, 31).unwrap();
1940 assert_eq!(date, expected);
1941 }
1942
1943 #[cfg(feature = "time")]
1945 #[test]
1946 fn decode_time_time_midnight() {
1947 let data = 0i64.to_be_bytes();
1948 let t = decode_time_time(&data).unwrap();
1949 assert_eq!(t, time::Time::MIDNIGHT);
1950 }
1951
1952 #[cfg(feature = "time")]
1954 #[test]
1955 fn decode_time_time_max_value() {
1956 let micros: i64 = 86_400_000_000 - 1; let data = micros.to_be_bytes();
1958 let t = decode_time_time(&data).unwrap();
1959 assert_eq!(t.hour(), 23);
1960 assert_eq!(t.minute(), 59);
1961 assert_eq!(t.second(), 59);
1962 assert_eq!(t.microsecond(), 999999);
1963 }
1964
1965 #[cfg(feature = "time")]
1967 #[test]
1968 fn decode_time_time_negative_micros_error() {
1969 let data = (-1i64).to_be_bytes();
1970 let result = decode_time_time(&data);
1971 assert!(result.is_err(), "negative microseconds should error");
1972 }
1973
1974 #[cfg(feature = "time")]
1976 #[test]
1977 fn decode_time_time_overflow_error() {
1978 let data = 86_400_000_000i64.to_be_bytes();
1979 let result = decode_time_time(&data);
1980 assert!(result.is_err(), ">= 24h microseconds should error");
1981 }
1982
1983 #[cfg(feature = "time")]
1985 #[test]
1986 fn decode_timestamptz_time_pg_epoch() {
1987 let data = 0i64.to_be_bytes();
1988 let dt = decode_timestamptz_time(&data).unwrap();
1989 assert_eq!(dt.year(), 2000);
1991 assert_eq!(dt.month(), time::Month::January);
1992 assert_eq!(dt.day(), 1);
1993 assert_eq!(dt.hour(), 0);
1994 assert_eq!(dt.minute(), 0);
1995 assert_eq!(dt.second(), 0);
1996 }
1997
1998 #[cfg(feature = "decimal")]
2000 #[test]
2001 fn decode_numeric_decimal_zero() {
2002 let mut data = Vec::new();
2004 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();
2009 assert!(dec.is_zero());
2010 }
2011
2012 #[cfg(feature = "decimal")]
2014 #[test]
2015 fn decode_numeric_decimal_negative() {
2016 let mut data = Vec::new();
2018 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();
2024 assert_eq!(dec, rust_decimal::Decimal::new(-42, 0));
2025 }
2026
2027 #[cfg(feature = "decimal")]
2029 #[test]
2030 fn decode_numeric_decimal_pure_fractional() {
2031 let mut data = Vec::new();
2036 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();
2042 let dec_normalized = dec.normalize();
2044 assert_eq!(dec_normalized.to_string(), "0.001");
2045 }
2046
2047 #[test]
2049 fn decode_array_empty() {
2050 let mut data = Vec::new();
2052 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();
2056 assert!(elems.is_empty());
2057 }
2058
2059 #[test]
2061 fn decode_array_multidim_error() {
2062 let mut data = Vec::new();
2063 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());
2068 data.extend_from_slice(&0i32.to_be_bytes());
2069 data.extend_from_slice(&0i32.to_be_bytes());
2070 data.extend_from_slice(&0i32.to_be_bytes());
2071 let result = decode_array_i32(&data);
2072 assert!(result.is_err(), "multi-dimensional should error");
2073 }
2074
2075 #[test]
2077 fn decode_array_truncated_error() {
2078 let mut data = Vec::new();
2080 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);
2087 assert!(result.is_err(), "truncated array should error");
2088 }
2089
2090 #[test]
2092 fn option_some_i32_produces_data() {
2093 let val: Option<i32> = Some(42);
2094 assert!(!val.is_null());
2095 let mut buf = Vec::new();
2096 val.encode_binary(&mut buf);
2097 assert_eq!(decode_i32(&buf).unwrap(), 42);
2098 }
2099
2100 #[test]
2102 fn option_none_i32_is_null() {
2103 let val: Option<i32> = None;
2104 assert!(val.is_null());
2105 let mut buf = Vec::new();
2106 val.encode_binary(&mut buf);
2107 assert!(buf.is_empty());
2108 }
2109
2110 #[test]
2112 fn empty_string_encode_decode() {
2113 let mut buf = Vec::new();
2114 "".encode_binary(&mut buf);
2115 assert!(buf.is_empty());
2116 assert_eq!(decode_str(&buf).unwrap(), "");
2117
2118 buf.clear();
2119 String::new().encode_binary(&mut buf);
2120 assert!(buf.is_empty());
2121 assert_eq!(decode_str(&buf).unwrap(), "");
2122 }
2123
2124 #[test]
2126 fn empty_bytes_encode_decode() {
2127 let mut buf = Vec::new();
2128 let empty: &[u8] = &[];
2129 empty.encode_binary(&mut buf);
2130 assert!(buf.is_empty());
2131 assert_eq!(decode_bytes(&buf).len(), 0);
2132
2133 buf.clear();
2134 Vec::<u8>::new().encode_binary(&mut buf);
2135 assert!(buf.is_empty());
2136 }
2137
2138 #[test]
2140 fn large_string_encode_decode() {
2141 let big = "x".repeat(1_000_000);
2142 let mut buf = Vec::new();
2143 big.as_str().encode_binary(&mut buf);
2144 assert_eq!(buf.len(), 1_000_000);
2145 assert_eq!(decode_str(&buf).unwrap(), big);
2146 }
2147
2148 #[test]
2150 fn uuid_nil() {
2151 let nil = [0u8; 16];
2152 let decoded = decode_uuid(&nil).unwrap();
2153 assert_eq!(decoded, [0u8; 16]);
2154 }
2155
2156 #[test]
2158 fn uuid_max() {
2159 let max = [0xFF; 16];
2160 let decoded = decode_uuid(&max).unwrap();
2161 assert_eq!(decoded, [0xFF; 16]);
2162 }
2163
2164 #[cfg(feature = "uuid")]
2166 #[test]
2167 fn uuid_type_nil_and_max() {
2168 let nil = [0u8; 16];
2169 let uuid = decode_uuid_type(&nil).unwrap();
2170 assert_eq!(uuid, uuid::Uuid::nil());
2171
2172 let max = [0xFF; 16];
2173 let uuid = decode_uuid_type(&max).unwrap();
2174 assert_eq!(uuid, uuid::Uuid::max());
2175 }
2176
2177 #[test]
2181 fn encode_array_bool_empty() {
2182 let arr: &[bool] = &[];
2183 let mut buf = Vec::new();
2184 arr.encode_binary(&mut buf);
2185 let decoded = decode_array_bool(&buf).unwrap();
2186 assert!(decoded.is_empty());
2187 }
2188
2189 #[test]
2190 fn encode_array_bool_single() {
2191 let arr: &[bool] = &[true];
2192 let mut buf = Vec::new();
2193 arr.encode_binary(&mut buf);
2194 let decoded = decode_array_bool(&buf).unwrap();
2195 assert_eq!(decoded, vec![true]);
2196 }
2197
2198 #[test]
2199 fn encode_array_bool_multi() {
2200 let arr: &[bool] = &[true, false, true, false];
2201 let mut buf = Vec::new();
2202 arr.encode_binary(&mut buf);
2203 let decoded = decode_array_bool(&buf).unwrap();
2204 assert_eq!(decoded, vec![true, false, true, false]);
2205 }
2206
2207 #[test]
2208 fn encode_array_bool_vec_delegate() {
2209 let v = vec![false, true];
2210 let mut buf = Vec::new();
2211 v.encode_binary(&mut buf);
2212 let decoded = decode_array_bool(&buf).unwrap();
2213 assert_eq!(decoded, vec![false, true]);
2214 assert_eq!(v.type_oid(), 1000);
2215 }
2216
2217 #[test]
2219 fn encode_array_i16_empty() {
2220 let arr: &[i16] = &[];
2221 let mut buf = Vec::new();
2222 arr.encode_binary(&mut buf);
2223 let decoded = decode_array_i16(&buf).unwrap();
2224 assert!(decoded.is_empty());
2225 }
2226
2227 #[test]
2228 fn encode_array_i16_single() {
2229 let arr: &[i16] = &[42];
2230 let mut buf = Vec::new();
2231 arr.encode_binary(&mut buf);
2232 let decoded = decode_array_i16(&buf).unwrap();
2233 assert_eq!(decoded, vec![42i16]);
2234 }
2235
2236 #[test]
2237 fn encode_array_i16_multi_boundary() {
2238 let arr: &[i16] = &[i16::MIN, -1, 0, 1, i16::MAX];
2239 let mut buf = Vec::new();
2240 arr.encode_binary(&mut buf);
2241 let decoded = decode_array_i16(&buf).unwrap();
2242 assert_eq!(decoded, vec![i16::MIN, -1, 0, 1, i16::MAX]);
2243 }
2244
2245 #[test]
2246 fn encode_array_i16_vec_delegate() {
2247 let v = vec![100i16, 200];
2248 let mut buf = Vec::new();
2249 v.encode_binary(&mut buf);
2250 let decoded = decode_array_i16(&buf).unwrap();
2251 assert_eq!(decoded, vec![100i16, 200]);
2252 assert_eq!(v.type_oid(), 1005);
2253 }
2254
2255 #[test]
2257 fn encode_array_i32_empty() {
2258 let arr: &[i32] = &[];
2259 let mut buf = Vec::new();
2260 arr.encode_binary(&mut buf);
2261 let decoded = decode_array_i32(&buf).unwrap();
2262 assert!(decoded.is_empty());
2263 }
2264
2265 #[test]
2266 fn encode_array_i32_single() {
2267 let arr: &[i32] = &[42];
2268 let mut buf = Vec::new();
2269 arr.encode_binary(&mut buf);
2270 let decoded = decode_array_i32(&buf).unwrap();
2271 assert_eq!(decoded, vec![42]);
2272 }
2273
2274 #[test]
2275 fn encode_array_i32_multi_boundary() {
2276 let arr: &[i32] = &[i32::MIN, -1, 0, 1, i32::MAX];
2277 let mut buf = Vec::new();
2278 arr.encode_binary(&mut buf);
2279 let decoded = decode_array_i32(&buf).unwrap();
2280 assert_eq!(decoded, vec![i32::MIN, -1, 0, 1, i32::MAX]);
2281 }
2282
2283 #[test]
2284 fn encode_array_i32_vec_delegate() {
2285 let v = vec![10, 20, 30];
2286 let mut buf = Vec::new();
2287 v.encode_binary(&mut buf);
2288 let decoded = decode_array_i32(&buf).unwrap();
2289 assert_eq!(decoded, vec![10, 20, 30]);
2290 assert_eq!(v.type_oid(), 1007);
2291 }
2292
2293 #[test]
2295 fn encode_array_i64_empty() {
2296 let arr: &[i64] = &[];
2297 let mut buf = Vec::new();
2298 arr.encode_binary(&mut buf);
2299 let decoded = decode_array_i64(&buf).unwrap();
2300 assert!(decoded.is_empty());
2301 }
2302
2303 #[test]
2304 fn encode_array_i64_single() {
2305 let arr: &[i64] = &[9999999999i64];
2306 let mut buf = Vec::new();
2307 arr.encode_binary(&mut buf);
2308 let decoded = decode_array_i64(&buf).unwrap();
2309 assert_eq!(decoded, vec![9999999999i64]);
2310 }
2311
2312 #[test]
2313 fn encode_array_i64_multi_boundary() {
2314 let arr: &[i64] = &[i64::MIN, -1, 0, 1, i64::MAX];
2315 let mut buf = Vec::new();
2316 arr.encode_binary(&mut buf);
2317 let decoded = decode_array_i64(&buf).unwrap();
2318 assert_eq!(decoded, vec![i64::MIN, -1, 0, 1, i64::MAX]);
2319 }
2320
2321 #[test]
2322 fn encode_array_i64_vec_delegate() {
2323 let v = vec![1i64, 2, 3];
2324 let mut buf = Vec::new();
2325 v.encode_binary(&mut buf);
2326 let decoded = decode_array_i64(&buf).unwrap();
2327 assert_eq!(decoded, vec![1i64, 2, 3]);
2328 assert_eq!(v.type_oid(), 1016);
2329 }
2330
2331 #[test]
2333 fn encode_array_f32_empty() {
2334 let arr: &[f32] = &[];
2335 let mut buf = Vec::new();
2336 arr.encode_binary(&mut buf);
2337 let decoded = decode_array_f32(&buf).unwrap();
2338 assert!(decoded.is_empty());
2339 }
2340
2341 #[test]
2342 fn encode_array_f32_single() {
2343 let arr: &[f32] = &[3.14];
2344 let mut buf = Vec::new();
2345 arr.encode_binary(&mut buf);
2346 let decoded = decode_array_f32(&buf).unwrap();
2347 assert!((decoded[0] - 3.14).abs() < f32::EPSILON);
2348 }
2349
2350 #[test]
2351 fn encode_array_f32_multi_boundary() {
2352 let arr: &[f32] = &[
2353 f32::MIN,
2354 -0.0,
2355 0.0,
2356 f32::MAX,
2357 f32::INFINITY,
2358 f32::NEG_INFINITY,
2359 ];
2360 let mut buf = Vec::new();
2361 arr.encode_binary(&mut buf);
2362 let decoded = decode_array_f32(&buf).unwrap();
2363 assert_eq!(decoded[0], f32::MIN);
2364 assert_eq!(decoded[1].to_bits(), (-0.0f32).to_bits());
2365 assert_eq!(decoded[2].to_bits(), 0.0f32.to_bits());
2366 assert_eq!(decoded[3], f32::MAX);
2367 assert_eq!(decoded[4], f32::INFINITY);
2368 assert_eq!(decoded[5], f32::NEG_INFINITY);
2369 }
2370
2371 #[test]
2372 fn encode_array_f32_vec_delegate() {
2373 let v = vec![1.0f32, 2.0];
2374 let mut buf = Vec::new();
2375 v.encode_binary(&mut buf);
2376 let decoded = decode_array_f32(&buf).unwrap();
2377 assert_eq!(decoded, vec![1.0f32, 2.0]);
2378 assert_eq!(v.type_oid(), 1021);
2379 }
2380
2381 #[test]
2383 fn encode_array_f64_empty() {
2384 let arr: &[f64] = &[];
2385 let mut buf = Vec::new();
2386 arr.encode_binary(&mut buf);
2387 let decoded = decode_array_f64(&buf).unwrap();
2388 assert!(decoded.is_empty());
2389 }
2390
2391 #[test]
2392 fn encode_array_f64_single() {
2393 let arr: &[f64] = &[std::f64::consts::PI];
2394 let mut buf = Vec::new();
2395 arr.encode_binary(&mut buf);
2396 let decoded = decode_array_f64(&buf).unwrap();
2397 assert!((decoded[0] - std::f64::consts::PI).abs() < f64::EPSILON);
2398 }
2399
2400 #[test]
2401 fn encode_array_f64_multi_boundary() {
2402 let arr: &[f64] = &[
2403 f64::MIN,
2404 -0.0,
2405 0.0,
2406 f64::MAX,
2407 f64::INFINITY,
2408 f64::NEG_INFINITY,
2409 ];
2410 let mut buf = Vec::new();
2411 arr.encode_binary(&mut buf);
2412 let decoded = decode_array_f64(&buf).unwrap();
2413 assert_eq!(decoded[0], f64::MIN);
2414 assert_eq!(decoded[1].to_bits(), (-0.0f64).to_bits());
2415 assert_eq!(decoded[2].to_bits(), 0.0f64.to_bits());
2416 assert_eq!(decoded[3], f64::MAX);
2417 assert_eq!(decoded[4], f64::INFINITY);
2418 assert_eq!(decoded[5], f64::NEG_INFINITY);
2419 }
2420
2421 #[test]
2422 fn encode_array_f64_vec_delegate() {
2423 let v = vec![1.0f64, 2.0];
2424 let mut buf = Vec::new();
2425 v.encode_binary(&mut buf);
2426 let decoded = decode_array_f64(&buf).unwrap();
2427 assert_eq!(decoded, vec![1.0f64, 2.0]);
2428 assert_eq!(v.type_oid(), 1022);
2429 }
2430
2431 #[test]
2433 fn encode_array_str_empty() {
2434 let arr: &[&str] = &[];
2435 let mut buf = Vec::new();
2436 arr.encode_binary(&mut buf);
2437 let decoded = decode_array_str(&buf).unwrap();
2438 assert!(decoded.is_empty());
2439 }
2440
2441 #[test]
2442 fn encode_array_str_single() {
2443 let arr: &[&str] = &["hello"];
2444 let mut buf = Vec::new();
2445 arr.encode_binary(&mut buf);
2446 let decoded = decode_array_str(&buf).unwrap();
2447 assert_eq!(decoded, vec!["hello".to_string()]);
2448 }
2449
2450 #[test]
2451 fn encode_array_str_multi() {
2452 let arr: &[&str] = &["hello", "", "world"];
2453 let mut buf = Vec::new();
2454 arr.encode_binary(&mut buf);
2455 let decoded = decode_array_str(&buf).unwrap();
2456 assert_eq!(
2457 decoded,
2458 vec!["hello".to_string(), "".to_string(), "world".to_string()]
2459 );
2460 }
2461
2462 #[test]
2463 fn encode_array_str_boundary_unicode() {
2464 let arr: &[&str] = &["\u{1F600}", "\u{00E9}"];
2465 let mut buf = Vec::new();
2466 arr.encode_binary(&mut buf);
2467 let decoded = decode_array_str(&buf).unwrap();
2468 assert_eq!(
2469 decoded,
2470 vec!["\u{1F600}".to_string(), "\u{00E9}".to_string()]
2471 );
2472 }
2473
2474 #[test]
2475 fn encode_array_vec_string() {
2476 let v = vec!["foo".to_string(), "bar".to_string()];
2477 let mut buf = Vec::new();
2478 v.encode_binary(&mut buf);
2479 let decoded = decode_array_str(&buf).unwrap();
2480 assert_eq!(decoded, vec!["foo".to_string(), "bar".to_string()]);
2481 assert_eq!(v.type_oid(), 1009);
2482 }
2483
2484 #[test]
2485 fn encode_array_vec_string_empty() {
2486 let v: Vec<String> = vec![];
2487 let mut buf = Vec::new();
2488 v.encode_binary(&mut buf);
2489 let decoded = decode_array_str(&buf).unwrap();
2490 assert!(decoded.is_empty());
2491 }
2492
2493 #[test]
2495 fn encode_array_bytea_empty() {
2496 let arr: &[&[u8]] = &[];
2497 let mut buf = Vec::new();
2498 arr.encode_binary(&mut buf);
2499 let decoded = decode_array_bytea(&buf).unwrap();
2500 assert!(decoded.is_empty());
2501 }
2502
2503 #[test]
2504 fn encode_array_bytea_single() {
2505 let data: &[u8] = &[0xDE, 0xAD];
2506 let arr: &[&[u8]] = &[data];
2507 let mut buf = Vec::new();
2508 arr.encode_binary(&mut buf);
2509 let decoded = decode_array_bytea(&buf).unwrap();
2510 assert_eq!(decoded, vec![vec![0xDE, 0xAD]]);
2511 }
2512
2513 #[test]
2514 fn encode_array_bytea_multi() {
2515 let a: &[u8] = &[1, 2, 3];
2516 let b: &[u8] = &[];
2517 let c: &[u8] = &[0xFF];
2518 let arr: &[&[u8]] = &[a, b, c];
2519 let mut buf = Vec::new();
2520 arr.encode_binary(&mut buf);
2521 let decoded = decode_array_bytea(&buf).unwrap();
2522 assert_eq!(decoded, vec![vec![1, 2, 3], vec![], vec![0xFF]]);
2523 }
2524
2525 #[test]
2526 fn encode_array_vec_vec_u8() {
2527 let v = vec![vec![10u8, 20], vec![30]];
2528 let mut buf = Vec::new();
2529 v.encode_binary(&mut buf);
2530 let decoded = decode_array_bytea(&buf).unwrap();
2531 assert_eq!(decoded, vec![vec![10u8, 20], vec![30]]);
2532 assert_eq!(v.type_oid(), 1001);
2533 }
2534
2535 #[test]
2536 fn encode_array_vec_vec_u8_empty() {
2537 let v: Vec<Vec<u8>> = vec![];
2538 let mut buf = Vec::new();
2539 v.encode_binary(&mut buf);
2540 let decoded = decode_array_bytea(&buf).unwrap();
2541 assert!(decoded.is_empty());
2542 }
2543
2544 #[test]
2546 fn array_type_oids_correct() {
2547 let b: &[bool] = &[];
2548 assert_eq!(b.type_oid(), 1000);
2549 let i2: &[i16] = &[];
2550 assert_eq!(i2.type_oid(), 1005);
2551 let i4: &[i32] = &[];
2552 assert_eq!(i4.type_oid(), 1007);
2553 let i8: &[i64] = &[];
2554 assert_eq!(i8.type_oid(), 1016);
2555 let f4: &[f32] = &[];
2556 assert_eq!(f4.type_oid(), 1021);
2557 let f8: &[f64] = &[];
2558 assert_eq!(f8.type_oid(), 1022);
2559 let t: &[&str] = &[];
2560 assert_eq!(t.type_oid(), 1009);
2561 let by: &[&[u8]] = &[];
2562 assert_eq!(by.type_oid(), 1001);
2563
2564 assert_eq!(Vec::<bool>::new().type_oid(), 1000);
2565 assert_eq!(Vec::<i16>::new().type_oid(), 1005);
2566 assert_eq!(Vec::<i32>::new().type_oid(), 1007);
2567 assert_eq!(Vec::<i64>::new().type_oid(), 1016);
2568 assert_eq!(Vec::<f32>::new().type_oid(), 1021);
2569 assert_eq!(Vec::<f64>::new().type_oid(), 1022);
2570 assert_eq!(Vec::<String>::new().type_oid(), 1009);
2571 assert_eq!(Vec::<Vec<u8>>::new().type_oid(), 1001);
2572 }
2573
2574 #[test]
2576 fn encode_array_empty_ndim_zero() {
2577 let arr: &[i32] = &[];
2578 let mut buf = Vec::new();
2579 arr.encode_binary(&mut buf);
2580 assert_eq!(buf.len(), 12);
2582 let ndim = i32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]);
2583 assert_eq!(ndim, 0, "empty array must have ndim=0");
2584 let elem_oid = i32::from_be_bytes([buf[8], buf[9], buf[10], buf[11]]);
2585 assert_eq!(
2586 elem_oid, 23,
2587 "element OID must be preserved for empty arrays"
2588 );
2589 }
2590
2591 #[test]
2594 fn encode_at_bool() {
2595 let mut dst = [0u8; 1];
2596 assert!(true.encode_at(&mut dst));
2597 assert_eq!(dst[0], 1);
2598 assert!(false.encode_at(&mut dst));
2599 assert_eq!(dst[0], 0);
2600 assert!(!true.encode_at(&mut [0u8; 2]));
2602 }
2603
2604 #[test]
2605 fn encode_at_i16() {
2606 let mut dst = [0u8; 2];
2607 assert!(0x1234i16.encode_at(&mut dst));
2608 assert_eq!(dst, [0x12, 0x34]);
2609 assert!(!42i16.encode_at(&mut [0u8; 4]));
2610 }
2611
2612 #[test]
2613 fn encode_at_i32() {
2614 let mut dst = [0u8; 4];
2615 assert!(42i32.encode_at(&mut dst));
2616 assert_eq!(dst, [0, 0, 0, 42]);
2617 assert!(!42i32.encode_at(&mut [0u8; 8]));
2618 }
2619
2620 #[test]
2621 fn encode_at_i64() {
2622 let mut dst = [0u8; 8];
2623 assert!(1234567890123i64.encode_at(&mut dst));
2624 assert_eq!(dst, 1234567890123i64.to_be_bytes());
2625 assert!(!42i64.encode_at(&mut [0u8; 4]));
2626 }
2627
2628 #[test]
2629 fn encode_at_f32() {
2630 let mut dst = [0u8; 4];
2631 assert!(3.14f32.encode_at(&mut dst));
2632 assert_eq!(dst, 3.14f32.to_be_bytes());
2633 assert!(!3.14f32.encode_at(&mut [0u8; 8]));
2634 }
2635
2636 #[test]
2637 fn encode_at_f64() {
2638 let mut dst = [0u8; 8];
2639 assert!(3.14f64.encode_at(&mut dst));
2640 assert_eq!(dst, 3.14f64.to_be_bytes());
2641 assert!(!3.14f64.encode_at(&mut [0u8; 4]));
2642 }
2643
2644 #[test]
2645 fn encode_at_u32() {
2646 let mut dst = [0u8; 4];
2647 assert!(42u32.encode_at(&mut dst));
2648 assert_eq!(dst, 42u32.to_be_bytes());
2649 }
2650
2651 #[test]
2652 fn encode_at_str_default_fallback() {
2653 let s: &str = "hello";
2655 let mut dst = [0u8; 5];
2656 assert!(s.encode_at(&mut dst));
2657 assert_eq!(&dst, b"hello");
2658 assert!(!s.encode_at(&mut [0u8; 3]));
2660 }
2661
2662 #[test]
2663 fn encode_at_matches_encode_binary() {
2664 fn check<T: Encode>(val: T, expected_len: usize) {
2667 let mut buf = Vec::new();
2668 val.encode_binary(&mut buf);
2669 assert_eq!(buf.len(), expected_len);
2670 let mut dst = vec![0u8; expected_len];
2671 assert!(val.encode_at(&mut dst));
2672 assert_eq!(
2673 buf, dst,
2674 "encode_at must produce same bytes as encode_binary"
2675 );
2676 }
2677 check(true, 1);
2678 check(false, 1);
2679 check(42i16, 2);
2680 check(i16::MAX, 2);
2681 check(42i32, 4);
2682 check(i32::MIN, 4);
2683 check(42i64, 8);
2684 check(3.14f32, 4);
2685 check(3.14f64, 8);
2686 check(42u32, 4);
2687 }
2688
2689 #[test]
2692 fn str_10kb_roundtrip() {
2693 let big = "A".repeat(10 * 1024);
2694 let mut buf = Vec::new();
2695 big.as_str().encode_binary(&mut buf);
2696 assert_eq!(buf.len(), 10 * 1024);
2697 assert_eq!(decode_str(&buf).unwrap(), big);
2698 }
2699
2700 #[test]
2703 fn empty_vec_u8_encode_roundtrip() {
2704 let mut buf = Vec::new();
2705 Vec::<u8>::new().encode_binary(&mut buf);
2706 assert!(buf.is_empty(), "empty Vec<u8> should produce no bytes");
2707 assert_eq!(decode_bytes(&buf).len(), 0);
2708 }
2709
2710 #[test]
2713 fn f32_min_max_roundtrip() {
2714 let mut buf = Vec::new();
2715 f32::MIN.encode_binary(&mut buf);
2716 assert_eq!(decode_f32(&buf).unwrap(), f32::MIN);
2717
2718 buf.clear();
2719 f32::MAX.encode_binary(&mut buf);
2720 assert_eq!(decode_f32(&buf).unwrap(), f32::MAX);
2721 }
2722
2723 #[test]
2726 fn f64_min_max_roundtrip() {
2727 let mut buf = Vec::new();
2728 f64::MIN.encode_binary(&mut buf);
2729 assert_eq!(decode_f64(&buf).unwrap(), f64::MIN);
2730
2731 buf.clear();
2732 f64::MAX.encode_binary(&mut buf);
2733 assert_eq!(decode_f64(&buf).unwrap(), f64::MAX);
2734 }
2735
2736 #[test]
2739 fn i32_zero_roundtrip() {
2740 let mut buf = Vec::new();
2741 0i32.encode_binary(&mut buf);
2742 assert_eq!(decode_i32(&buf).unwrap(), 0);
2743 }
2744
2745 #[test]
2748 fn i64_zero_roundtrip() {
2749 let mut buf = Vec::new();
2750 0i64.encode_binary(&mut buf);
2751 assert_eq!(decode_i64(&buf).unwrap(), 0);
2752 }
2753
2754 #[test]
2757 fn i16_zero_roundtrip() {
2758 let mut buf = Vec::new();
2759 0i16.encode_binary(&mut buf);
2760 assert_eq!(decode_i16(&buf).unwrap(), 0);
2761 }
2762
2763 #[test]
2766 fn f32_subnormal_roundtrip() {
2767 let mut buf = Vec::new();
2768 f32::MIN_POSITIVE.encode_binary(&mut buf);
2769 assert_eq!(decode_f32(&buf).unwrap(), f32::MIN_POSITIVE);
2770 }
2771
2772 #[test]
2775 fn f64_subnormal_roundtrip() {
2776 let mut buf = Vec::new();
2777 f64::MIN_POSITIVE.encode_binary(&mut buf);
2778 assert_eq!(decode_f64(&buf).unwrap(), f64::MIN_POSITIVE);
2779 }
2780
2781 #[test]
2784 fn f32_nan_bit_preservation() {
2785 let mut buf = Vec::new();
2786 f32::NAN.encode_binary(&mut buf);
2787 let decoded = decode_f32(&buf).unwrap();
2788 assert!(decoded.is_nan());
2789 assert_eq!(decoded.to_bits(), f32::NAN.to_bits());
2791 }
2792
2793 #[test]
2796 fn f64_nan_bit_preservation() {
2797 let mut buf = Vec::new();
2798 f64::NAN.encode_binary(&mut buf);
2799 let decoded = decode_f64(&buf).unwrap();
2800 assert!(decoded.is_nan());
2801 assert_eq!(decoded.to_bits(), f64::NAN.to_bits());
2802 }
2803
2804 mod proptest_fuzz {
2805 use super::*;
2806 use proptest::prelude::*;
2807
2808 proptest! {
2809 #[test]
2810 fn i32_roundtrip(val: i32) {
2811 let mut buf = Vec::new();
2812 val.encode_binary(&mut buf);
2813 let decoded = decode_i32(&buf).unwrap();
2814 prop_assert_eq!(decoded, val);
2815 }
2816
2817 #[test]
2818 fn i64_roundtrip(val: i64) {
2819 let mut buf = Vec::new();
2820 val.encode_binary(&mut buf);
2821 let decoded = decode_i64(&buf).unwrap();
2822 prop_assert_eq!(decoded, val);
2823 }
2824
2825 #[test]
2826 fn i16_roundtrip(val: i16) {
2827 let mut buf = Vec::new();
2828 val.encode_binary(&mut buf);
2829 let decoded = decode_i16(&buf).unwrap();
2830 prop_assert_eq!(decoded, val);
2831 }
2832
2833 #[test]
2834 fn f32_roundtrip(val: f32) {
2835 let mut buf = Vec::new();
2836 val.encode_binary(&mut buf);
2837 let decoded = decode_f32(&buf).unwrap();
2838 if val.is_nan() {
2839 prop_assert!(decoded.is_nan());
2840 } else {
2841 prop_assert_eq!(decoded, val);
2842 }
2843 }
2844
2845 #[test]
2846 fn f64_roundtrip(val: f64) {
2847 let mut buf = Vec::new();
2848 val.encode_binary(&mut buf);
2849 let decoded = decode_f64(&buf).unwrap();
2850 if val.is_nan() {
2851 prop_assert!(decoded.is_nan());
2852 } else {
2853 prop_assert_eq!(decoded, val);
2854 }
2855 }
2856
2857 #[test]
2858 fn bool_roundtrip(val: bool) {
2859 let mut buf = Vec::new();
2860 val.encode_binary(&mut buf);
2861 let decoded = decode_bool(&buf).unwrap();
2862 prop_assert_eq!(decoded, val);
2863 }
2864
2865 #[test]
2866 fn str_roundtrip(val in "\\PC*") {
2867 let mut buf = Vec::new();
2868 val.as_str().encode_binary(&mut buf);
2869 let decoded = decode_str(&buf).unwrap();
2870 prop_assert_eq!(decoded, val.as_str());
2871 }
2872
2873 #[test]
2874 fn decode_i32_arbitrary_never_panics(data in proptest::collection::vec(any::<u8>(), 0..16)) {
2875 let _ = decode_i32(&data);
2876 }
2877
2878 #[test]
2879 fn decode_str_arbitrary_never_panics(data in proptest::collection::vec(any::<u8>(), 0..1024)) {
2880 let _ = decode_str(&data);
2881 }
2882 }
2883 }
2884}