1use crate::error::{BindError, Result};
5use bytes::Bytes;
6
7#[derive(Debug, Clone)]
19pub struct TupleInput {
20 buf: Bytes,
21 off: usize,
22}
23
24impl TupleInput {
25 pub fn new(data: &[u8]) -> Self {
27 Self { buf: Bytes::copy_from_slice(data), off: 0 }
28 }
29
30 pub fn from_vec(data: Vec<u8>) -> Self {
32 Self { buf: Bytes::from(data), off: 0 }
33 }
34
35 pub fn from_bytes(data: Bytes) -> Self {
37 Self { buf: data, off: 0 }
38 }
39
40 pub fn available(&self) -> usize {
42 self.buf.len().saturating_sub(self.off)
43 }
44
45 pub fn get_offset(&self) -> usize {
47 self.off
48 }
49
50 pub fn set_offset(&mut self, offset: usize) {
52 self.off = offset;
53 }
54
55 pub fn get_buffer(&self) -> &[u8] {
57 &self.buf
58 }
59
60 fn read_fast(&mut self) -> Result<u8> {
62 if self.off >= self.buf.len() {
63 return Err(BindError::BufferUnderflow { needed: 1, available: 0 });
64 }
65 let b = self.buf[self.off];
66 self.off += 1;
67 Ok(b)
68 }
69
70 pub fn read_bool(&mut self) -> Result<bool> {
74 Ok(self.read_fast()? != 0)
75 }
76
77 pub fn read_u8(&mut self) -> Result<u8> {
81 self.read_fast()
82 }
83
84 pub fn read_i8(&mut self) -> Result<i8> {
88 let b = self.read_fast()?;
89 Ok((b ^ 0x80) as i8)
90 }
91
92 pub fn read_u16(&mut self) -> Result<u16> {
96 let c1 = self.read_fast()? as u16;
97 let c2 = self.read_fast()? as u16;
98 Ok((c1 << 8) | c2)
99 }
100
101 pub fn read_i16(&mut self) -> Result<i16> {
105 let v = self.read_u16()?;
106 Ok((v ^ 0x8000) as i16)
107 }
108
109 pub fn read_u32(&mut self) -> Result<u32> {
113 let c1 = self.read_fast()? as u32;
114 let c2 = self.read_fast()? as u32;
115 let c3 = self.read_fast()? as u32;
116 let c4 = self.read_fast()? as u32;
117 Ok((c1 << 24) | (c2 << 16) | (c3 << 8) | c4)
118 }
119
120 pub fn read_i32(&mut self) -> Result<i32> {
124 let v = self.read_u32()?;
125 Ok((v ^ 0x80000000) as i32)
126 }
127
128 pub fn read_u64(&mut self) -> Result<u64> {
132 let c1 = self.read_fast()? as u64;
133 let c2 = self.read_fast()? as u64;
134 let c3 = self.read_fast()? as u64;
135 let c4 = self.read_fast()? as u64;
136 let c5 = self.read_fast()? as u64;
137 let c6 = self.read_fast()? as u64;
138 let c7 = self.read_fast()? as u64;
139 let c8 = self.read_fast()? as u64;
140 Ok((c1 << 56)
141 | (c2 << 48)
142 | (c3 << 40)
143 | (c4 << 32)
144 | (c5 << 24)
145 | (c6 << 16)
146 | (c7 << 8)
147 | c8)
148 }
149
150 pub fn read_i64(&mut self) -> Result<i64> {
154 let v = self.read_u64()?;
155 Ok((v ^ 0x8000000000000000) as i64)
156 }
157
158 pub fn read_float(&mut self) -> Result<f32> {
165 let bits = self.read_u32()?;
166 Ok(f32::from_bits(bits))
167 }
168
169 pub fn read_double(&mut self) -> Result<f64> {
176 let bits = self.read_u64()?;
177 Ok(f64::from_bits(bits))
178 }
179
180 pub fn read_sorted_float(&mut self) -> Result<f32> {
188 let encoded = self.read_u32()?;
189 let bits = if encoded & 0x80000000 != 0 {
194 encoded ^ 0x80000000
195 } else {
196 encoded ^ 0xFFFFFFFF
197 };
198 Ok(f32::from_bits(bits))
199 }
200
201 pub fn read_sorted_double(&mut self) -> Result<f64> {
209 let encoded = self.read_u64()?;
210 let bits = if encoded & 0x8000000000000000 != 0 {
211 encoded ^ 0x8000000000000000
212 } else {
213 encoded ^ 0xFFFFFFFFFFFFFFFF
214 };
215 Ok(f64::from_bits(bits))
216 }
217
218 pub fn read_packed_int(&mut self) -> Result<i32> {
227 let b1 = self.read_fast()? as i8;
228
229 let (negative, byte_len) = if b1 < -119 {
230 (true, ((-b1) as usize) - 119)
231 } else if b1 > 119 {
232 (false, (b1 as usize) - 119)
233 } else {
234 return Ok(b1 as i32);
235 };
236
237 let mut value: u32 = self.read_fast()? as u32;
238 if byte_len > 1 {
239 value |= (self.read_fast()? as u32) << 8;
240 if byte_len > 2 {
241 value |= (self.read_fast()? as u32) << 16;
242 if byte_len > 3 {
243 value |= (self.read_fast()? as u32) << 24;
244 }
245 }
246 }
247
248 if negative {
249 Ok(-(value as i32) - 119)
250 } else {
251 Ok((value as i32) + 119)
252 }
253 }
254
255 pub fn read_packed_long(&mut self) -> Result<i64> {
264 let b1 = self.read_fast()? as i8;
265
266 let (negative, byte_len) = if b1 < -119 {
267 (true, ((-b1) as usize) - 119)
268 } else if b1 > 119 {
269 (false, (b1 as usize) - 119)
270 } else {
271 return Ok(b1 as i64);
272 };
273
274 let mut value: u64 = self.read_fast()? as u64;
275 if byte_len > 1 {
276 value |= (self.read_fast()? as u64) << 8;
277 if byte_len > 2 {
278 value |= (self.read_fast()? as u64) << 16;
279 if byte_len > 3 {
280 value |= (self.read_fast()? as u64) << 24;
281 if byte_len > 4 {
282 value |= (self.read_fast()? as u64) << 32;
283 if byte_len > 5 {
284 value |= (self.read_fast()? as u64) << 40;
285 if byte_len > 6 {
286 value |= (self.read_fast()? as u64) << 48;
287 if byte_len > 7 {
288 value |= (self.read_fast()? as u64) << 56;
289 }
290 }
291 }
292 }
293 }
294 }
295 }
296
297 if negative {
298 Ok(-(value as i64) - 119)
299 } else {
300 Ok((value as i64) + 119)
301 }
302 }
303
304 pub fn read_sorted_packed_int(&mut self) -> Result<i32> {
316 let b1 = self.read_fast()?;
317 if b1 < 0x08 {
318 let n = (0x08 - b1) as usize;
320 let mut raw: u32 = 0xFFFFFFFF;
321 for _ in 0..n {
322 raw = (raw << 8) | (self.read_fast()? as u32);
323 }
324 Ok(raw as i32 - 119)
325 } else if b1 > 0xF7 {
326 let n = (b1 - 0xF7) as usize;
328 let mut raw: u32 = 0;
329 for _ in 0..n {
330 raw = (raw << 8) | (self.read_fast()? as u32);
331 }
332 Ok(raw as i32 + 121)
333 } else {
334 Ok(b1 as i32 - 127)
335 }
336 }
337
338 pub fn read_sorted_packed_long(&mut self) -> Result<i64> {
346 let b1 = self.read_fast()?;
347 if b1 < 0x08 {
348 let n = (0x08 - b1) as usize;
349 let mut raw: u64 = 0xFFFFFFFFFFFFFFFF;
350 for _ in 0..n {
351 raw = (raw << 8) | (self.read_fast()? as u64);
352 }
353 Ok(raw as i64 - 119)
354 } else if b1 > 0xF7 {
355 let n = (b1 - 0xF7) as usize;
356 let mut raw: u64 = 0;
357 for _ in 0..n {
358 raw = (raw << 8) | (self.read_fast()? as u64);
359 }
360 Ok(raw as i64 + 121)
361 } else {
362 Ok(b1 as i64 - 127)
363 }
364 }
365
366 pub fn read_char(&mut self) -> Result<u16> {
370 self.read_u16()
371 }
372
373 pub fn read_string(&mut self) -> Result<String> {
379 let mut decoded: Vec<u8> = Vec::new();
380 loop {
381 if self.off >= self.buf.len() {
382 return Err(BindError::InvalidData(
383 "no null terminator found for string".to_string(),
384 ));
385 }
386 let b = self.buf[self.off];
387 self.off += 1;
388 if b == 0x00 {
389 if self.off >= self.buf.len() {
391 return Err(BindError::InvalidData(
392 "truncated null escape sequence in string".to_string(),
393 ));
394 }
395 let next = self.buf[self.off];
396 self.off += 1;
397 if next == 0x00 {
398 break;
400 } else if next == 0x01 {
401 decoded.push(0x00);
403 } else {
404 return Err(BindError::InvalidData(format!(
405 "invalid null escape byte 0x{:02x} in string",
406 next
407 )));
408 }
409 } else {
410 decoded.push(b);
411 }
412 }
413 String::from_utf8(decoded).map_err(|e| {
414 BindError::StringEncoding(format!("invalid UTF-8: {}", e))
415 })
416 }
417
418 pub fn read_bytes(&mut self, len: usize) -> Result<Vec<u8>> {
422 if self.available() < len {
423 return Err(BindError::BufferUnderflow {
424 needed: len,
425 available: self.available(),
426 });
427 }
428 let bytes = self.buf[self.off..self.off + len].to_vec();
429 self.off += len;
430 Ok(bytes)
431 }
432
433 pub fn skip(&mut self, count: usize) -> Result<()> {
435 if self.available() < count {
436 return Err(BindError::BufferUnderflow {
437 needed: count,
438 available: self.available(),
439 });
440 }
441 self.off += count;
442 Ok(())
443 }
444}
445
446#[cfg(test)]
447mod tests {
448 use super::*;
449 use crate::tuple::TupleOutput;
450
451 #[test]
452 fn test_bool_round_trip() {
453 let mut out = TupleOutput::new();
454 out.write_bool(true);
455 out.write_bool(false);
456 let mut input = TupleInput::new(&out.to_vec());
457 assert!(input.read_bool().unwrap());
458 assert!(!input.read_bool().unwrap());
459 }
460
461 #[test]
462 fn test_i8_round_trip() {
463 let mut out = TupleOutput::new();
464 out.write_i8(-128);
465 out.write_i8(0);
466 out.write_i8(127);
467 let mut input = TupleInput::new(&out.to_vec());
468 assert_eq!(input.read_i8().unwrap(), -128);
469 assert_eq!(input.read_i8().unwrap(), 0);
470 assert_eq!(input.read_i8().unwrap(), 127);
471 }
472
473 #[test]
474 fn test_i16_round_trip() {
475 let mut out = TupleOutput::new();
476 out.write_i16(i16::MIN);
477 out.write_i16(0);
478 out.write_i16(i16::MAX);
479 let mut input = TupleInput::new(&out.to_vec());
480 assert_eq!(input.read_i16().unwrap(), i16::MIN);
481 assert_eq!(input.read_i16().unwrap(), 0);
482 assert_eq!(input.read_i16().unwrap(), i16::MAX);
483 }
484
485 #[test]
486 fn test_i32_round_trip() {
487 let mut out = TupleOutput::new();
488 out.write_i32(i32::MIN);
489 out.write_i32(-1);
490 out.write_i32(0);
491 out.write_i32(1);
492 out.write_i32(i32::MAX);
493 let mut input = TupleInput::new(&out.to_vec());
494 assert_eq!(input.read_i32().unwrap(), i32::MIN);
495 assert_eq!(input.read_i32().unwrap(), -1);
496 assert_eq!(input.read_i32().unwrap(), 0);
497 assert_eq!(input.read_i32().unwrap(), 1);
498 assert_eq!(input.read_i32().unwrap(), i32::MAX);
499 }
500
501 #[test]
502 fn test_i64_round_trip() {
503 let mut out = TupleOutput::new();
504 out.write_i64(i64::MIN);
505 out.write_i64(-1);
506 out.write_i64(0);
507 out.write_i64(1);
508 out.write_i64(i64::MAX);
509 let mut input = TupleInput::new(&out.to_vec());
510 assert_eq!(input.read_i64().unwrap(), i64::MIN);
511 assert_eq!(input.read_i64().unwrap(), -1);
512 assert_eq!(input.read_i64().unwrap(), 0);
513 assert_eq!(input.read_i64().unwrap(), 1);
514 assert_eq!(input.read_i64().unwrap(), i64::MAX);
515 }
516
517 #[test]
518 fn test_u8_round_trip() {
519 let mut out = TupleOutput::new();
520 out.write_u8(0);
521 out.write_u8(128);
522 out.write_u8(255);
523 let mut input = TupleInput::new(&out.to_vec());
524 assert_eq!(input.read_u8().unwrap(), 0);
525 assert_eq!(input.read_u8().unwrap(), 128);
526 assert_eq!(input.read_u8().unwrap(), 255);
527 }
528
529 #[test]
530 fn test_float_round_trip() {
531 let mut out = TupleOutput::new();
532 out.write_float(0.0);
533 out.write_float(1.5);
534 out.write_float(-1.5);
535 out.write_float(f32::MAX);
536 out.write_float(f32::MIN);
537 let mut input = TupleInput::new(&out.to_vec());
538 assert_eq!(input.read_float().unwrap(), 0.0);
539 assert_eq!(input.read_float().unwrap(), 1.5);
540 assert_eq!(input.read_float().unwrap(), -1.5);
541 assert_eq!(input.read_float().unwrap(), f32::MAX);
542 assert_eq!(input.read_float().unwrap(), f32::MIN);
543 }
544
545 #[test]
546 fn test_double_round_trip() {
547 let mut out = TupleOutput::new();
548 out.write_double(0.0);
549 out.write_double(1.5);
550 out.write_double(-1.5);
551 out.write_double(f64::MAX);
552 out.write_double(f64::MIN);
553 let mut input = TupleInput::new(&out.to_vec());
554 assert_eq!(input.read_double().unwrap(), 0.0);
555 assert_eq!(input.read_double().unwrap(), 1.5);
556 assert_eq!(input.read_double().unwrap(), -1.5);
557 assert_eq!(input.read_double().unwrap(), f64::MAX);
558 assert_eq!(input.read_double().unwrap(), f64::MIN);
559 }
560
561 #[test]
562 fn test_sorted_float_round_trip() {
563 let mut out = TupleOutput::new();
564 out.write_sorted_float(-1.0);
565 out.write_sorted_float(0.0);
566 out.write_sorted_float(1.0);
567 out.write_sorted_float(f32::MAX);
568 out.write_sorted_float(f32::MIN);
569 let mut input = TupleInput::new(&out.to_vec());
570 assert_eq!(input.read_sorted_float().unwrap(), -1.0);
571 assert_eq!(input.read_sorted_float().unwrap(), 0.0);
572 assert_eq!(input.read_sorted_float().unwrap(), 1.0);
573 assert_eq!(input.read_sorted_float().unwrap(), f32::MAX);
574 assert_eq!(input.read_sorted_float().unwrap(), f32::MIN);
575 }
576
577 #[test]
578 fn test_sorted_double_round_trip() {
579 let mut out = TupleOutput::new();
580 out.write_sorted_double(-1.0);
581 out.write_sorted_double(0.0);
582 out.write_sorted_double(1.0);
583 out.write_sorted_double(f64::MAX);
584 out.write_sorted_double(f64::MIN);
585 let mut input = TupleInput::new(&out.to_vec());
586 assert_eq!(input.read_sorted_double().unwrap(), -1.0);
587 assert_eq!(input.read_sorted_double().unwrap(), 0.0);
588 assert_eq!(input.read_sorted_double().unwrap(), 1.0);
589 assert_eq!(input.read_sorted_double().unwrap(), f64::MAX);
590 assert_eq!(input.read_sorted_double().unwrap(), f64::MIN);
591 }
592
593 #[test]
594 fn test_packed_int_round_trip() {
595 let mut out = TupleOutput::new();
596 let values = [
597 0,
598 1,
599 -1,
600 119,
601 -119,
602 120,
603 -120,
604 255,
605 -256,
606 1000,
607 -1000,
608 i32::MAX,
609 i32::MIN,
610 65535,
611 -65536,
612 ];
613 for &v in &values {
614 out.write_packed_int(v);
615 }
616 let mut input = TupleInput::new(&out.to_vec());
617 for &v in &values {
618 assert_eq!(
619 input.read_packed_int().unwrap(),
620 v,
621 "failed for value {}",
622 v
623 );
624 }
625 }
626
627 #[test]
628 fn test_packed_long_round_trip() {
629 let mut out = TupleOutput::new();
630 let values: &[i64] = &[
631 0,
632 1,
633 -1,
634 119,
635 -119,
636 120,
637 -120,
638 1000,
639 -1000,
640 i32::MAX as i64,
641 i32::MIN as i64,
642 i64::MAX,
643 i64::MIN,
644 ];
645 for &v in values {
646 out.write_packed_long(v);
647 }
648 let mut input = TupleInput::new(&out.to_vec());
649 for &v in values {
650 assert_eq!(
651 input.read_packed_long().unwrap(),
652 v,
653 "failed for value {}",
654 v
655 );
656 }
657 }
658
659 #[test]
660 fn test_string_round_trip() {
661 let mut out = TupleOutput::new();
662 out.write_string("hello");
663 out.write_string("");
664 out.write_string("world");
665 let mut input = TupleInput::new(&out.to_vec());
666 assert_eq!(input.read_string().unwrap(), "hello");
667 assert_eq!(input.read_string().unwrap(), "");
668 assert_eq!(input.read_string().unwrap(), "world");
669 }
670
671 #[test]
672 fn test_bytes_round_trip() {
673 let mut out = TupleOutput::new();
674 out.write_bytes(&[1, 2, 3, 4, 5]);
675 let mut input = TupleInput::new(&out.to_vec());
676 assert_eq!(input.read_bytes(5).unwrap(), vec![1, 2, 3, 4, 5]);
677 }
678
679 #[test]
680 fn test_buffer_underflow() {
681 let mut input = TupleInput::new(&[]);
682 assert!(input.read_i32().is_err());
683 }
684
685 #[test]
686 fn test_available() {
687 let mut input = TupleInput::new(&[1, 2, 3, 4]);
688 assert_eq!(input.available(), 4);
689 input.read_u8().unwrap();
690 assert_eq!(input.available(), 3);
691 }
692
693 #[test]
699 fn test_available_tracks_reads() {
700 let mut out = TupleOutput::new();
701 out.write_bool(true);
702 out.write_i8(-1);
703 out.write_i16(1000);
704 out.write_i32(123);
705 out.write_i64(456);
706 let mut inp = TupleInput::new(&out.to_vec());
708 assert_eq!(inp.available(), 16);
709 inp.read_bool().unwrap();
710 assert_eq!(inp.available(), 15);
711 inp.read_i8().unwrap();
712 assert_eq!(inp.available(), 14);
713 inp.read_i16().unwrap();
714 assert_eq!(inp.available(), 12);
715 inp.read_i32().unwrap();
716 assert_eq!(inp.available(), 8);
717 inp.read_i64().unwrap();
718 assert_eq!(inp.available(), 0);
719 }
720
721 #[test]
723 fn test_multi_type_interleave_round_trip() {
724 let mut out = TupleOutput::new();
725 out.write_string("abc");
726 out.write_i32(42);
727 out.write_bool(true);
728 out.write_double(-1.5_f64);
729 out.write_string("xyz");
730
731 let mut inp = TupleInput::new(&out.to_vec());
732 assert_eq!(inp.read_string().unwrap(), "abc");
733 assert_eq!(inp.read_i32().unwrap(), 42);
734 assert!(inp.read_bool().unwrap());
735 assert_eq!(inp.read_double().unwrap(), -1.5_f64);
736 assert_eq!(inp.read_string().unwrap(), "xyz");
737 assert_eq!(inp.available(), 0);
738 }
739
740 #[test]
742 fn test_skip() {
743 let mut out = TupleOutput::new();
744 out.write_i32(111);
745 out.write_i32(222);
746 out.write_i32(333);
747 let mut inp = TupleInput::new(&out.to_vec());
748 inp.skip(4).unwrap(); assert_eq!(inp.read_i32().unwrap(), 222);
750 assert_eq!(inp.available(), 4);
751 assert_eq!(inp.read_i32().unwrap(), 333);
752 assert_eq!(inp.available(), 0);
753 }
754
755 #[test]
757 fn test_skip_past_end_error() {
758 let mut inp = TupleInput::new(&[1, 2, 3]);
759 assert!(inp.skip(4).is_err());
760 }
761
762 #[test]
764 fn test_set_get_offset_mark_reset() {
765 let mut out = TupleOutput::new();
766 out.write_i32(10);
767 out.write_i32(20);
768 let mut inp = TupleInput::new(&out.to_vec());
769 assert_eq!(inp.get_offset(), 0);
770 inp.read_i32().unwrap();
771 let mark = inp.get_offset(); assert_eq!(inp.read_i32().unwrap(), 20);
773 inp.set_offset(mark);
775 assert_eq!(inp.read_i32().unwrap(), 20);
776 assert_eq!(inp.available(), 0);
777 }
778
779 #[test]
781 fn test_get_buffer() {
782 let data = vec![1u8, 2, 3, 4];
783 let inp = TupleInput::new(&data);
784 assert_eq!(inp.get_buffer(), data.as_slice());
785 }
786
787 #[test]
789 fn test_bool_sequence_read() {
790 let mut out = TupleOutput::new();
791 out.write_bool(true);
792 out.write_bool(false);
793 out.write_bool(true);
794 assert_eq!(out.len(), 3);
795 let mut inp = TupleInput::new(&out.to_vec());
796 assert!(inp.read_bool().unwrap());
797 assert!(!inp.read_bool().unwrap());
798 assert!(inp.read_bool().unwrap());
799 assert_eq!(inp.available(), 0);
800 }
801
802 #[test]
804 fn test_short_sequence_read() {
805 let mut out = TupleOutput::new();
806 out.write_i16(0);
807 out.write_i16(1);
808 out.write_i16(-1);
809 assert_eq!(out.len(), 6);
810 let mut inp = TupleInput::new(&out.to_vec());
811 assert_eq!(inp.read_i16().unwrap(), 0);
812 assert_eq!(inp.read_i16().unwrap(), 1);
813 assert_eq!(inp.read_i16().unwrap(), -1);
814 assert_eq!(inp.available(), 0);
815 }
816
817 #[test]
819 fn test_int_sequence_read() {
820 let mut out = TupleOutput::new();
821 out.write_i32(0);
822 out.write_i32(1);
823 out.write_i32(-1);
824 assert_eq!(out.len(), 12);
825 let mut inp = TupleInput::new(&out.to_vec());
826 assert_eq!(inp.read_i32().unwrap(), 0);
827 assert_eq!(inp.read_i32().unwrap(), 1);
828 assert_eq!(inp.read_i32().unwrap(), -1);
829 assert_eq!(inp.available(), 0);
830 }
831
832 #[test]
834 fn test_long_sequence_read() {
835 let mut out = TupleOutput::new();
836 out.write_i64(0);
837 out.write_i64(1);
838 out.write_i64(-1);
839 assert_eq!(out.len(), 24);
840 let mut inp = TupleInput::new(&out.to_vec());
841 assert_eq!(inp.read_i64().unwrap(), 0);
842 assert_eq!(inp.read_i64().unwrap(), 1);
843 assert_eq!(inp.read_i64().unwrap(), -1);
844 assert_eq!(inp.available(), 0);
845 }
846
847 #[test]
849 fn test_float_sequence_read() {
850 let mut out = TupleOutput::new();
851 out.write_float(0.0);
852 out.write_float(1.0);
853 out.write_float(-1.0);
854 assert_eq!(out.len(), 12);
855 let mut inp = TupleInput::new(&out.to_vec());
856 assert_eq!(inp.read_float().unwrap(), 0.0f32);
857 assert_eq!(inp.read_float().unwrap(), 1.0f32);
858 assert_eq!(inp.read_float().unwrap(), -1.0f32);
859 assert_eq!(inp.available(), 0);
860 }
861
862 #[test]
864 fn test_double_sequence_read() {
865 let mut out = TupleOutput::new();
866 out.write_double(0.0);
867 out.write_double(1.0);
868 out.write_double(-1.0);
869 assert_eq!(out.len(), 24);
870 let mut inp = TupleInput::new(&out.to_vec());
871 assert_eq!(inp.read_double().unwrap(), 0.0f64);
872 assert_eq!(inp.read_double().unwrap(), 1.0f64);
873 assert_eq!(inp.read_double().unwrap(), -1.0f64);
874 assert_eq!(inp.available(), 0);
875 }
876
877 #[test]
879 fn test_sorted_float_sequence_read() {
880 let mut out = TupleOutput::new();
881 out.write_sorted_float(0.0);
882 out.write_sorted_float(1.0);
883 out.write_sorted_float(-1.0);
884 assert_eq!(out.len(), 12);
885 let mut inp = TupleInput::new(&out.to_vec());
886 assert_eq!(inp.read_sorted_float().unwrap(), 0.0f32);
887 assert_eq!(inp.read_sorted_float().unwrap(), 1.0f32);
888 assert_eq!(inp.read_sorted_float().unwrap(), -1.0f32);
889 assert_eq!(inp.available(), 0);
890 }
891
892 #[test]
894 fn test_sorted_double_sequence_read() {
895 let mut out = TupleOutput::new();
896 out.write_sorted_double(0.0);
897 out.write_sorted_double(1.0);
898 out.write_sorted_double(-1.0);
899 assert_eq!(out.len(), 24);
900 let mut inp = TupleInput::new(&out.to_vec());
901 assert_eq!(inp.read_sorted_double().unwrap(), 0.0f64);
902 assert_eq!(inp.read_sorted_double().unwrap(), 1.0f64);
903 assert_eq!(inp.read_sorted_double().unwrap(), -1.0f64);
904 assert_eq!(inp.available(), 0);
905 }
906
907 #[test]
909 fn test_float_nan_round_trip() {
910 let mut out = TupleOutput::new();
911 out.write_float(f32::NAN);
912 let mut inp = TupleInput::new(&out.to_vec());
913 assert!(inp.read_float().unwrap().is_nan());
914 }
915
916 #[test]
918 fn test_double_nan_round_trip() {
919 let mut out = TupleOutput::new();
920 out.write_double(f64::NAN);
921 let mut inp = TupleInput::new(&out.to_vec());
922 assert!(inp.read_double().unwrap().is_nan());
923 }
924
925 #[test]
927 fn test_sorted_float_nan_round_trip() {
928 let mut out = TupleOutput::new();
929 out.write_sorted_float(f32::NAN);
930 let mut inp = TupleInput::new(&out.to_vec());
931 assert!(inp.read_sorted_float().unwrap().is_nan());
932 }
933
934 #[test]
936 fn test_sorted_double_nan_round_trip() {
937 let mut out = TupleOutput::new();
938 out.write_sorted_double(f64::NAN);
939 let mut inp = TupleInput::new(&out.to_vec());
940 assert!(inp.read_sorted_double().unwrap().is_nan());
941 }
942
943 #[test]
945 fn test_sorted_float_infinity_round_trip() {
946 let mut out = TupleOutput::new();
947 out.write_sorted_float(f32::INFINITY);
948 out.write_sorted_float(f32::NEG_INFINITY);
949 let mut inp = TupleInput::new(&out.to_vec());
950 assert_eq!(inp.read_sorted_float().unwrap(), f32::INFINITY);
951 assert_eq!(inp.read_sorted_float().unwrap(), f32::NEG_INFINITY);
952 assert_eq!(inp.available(), 0);
953 }
954
955 #[test]
957 fn test_sorted_double_infinity_round_trip() {
958 let mut out = TupleOutput::new();
959 out.write_sorted_double(f64::INFINITY);
960 out.write_sorted_double(f64::NEG_INFINITY);
961 let mut inp = TupleInput::new(&out.to_vec());
962 assert_eq!(inp.read_sorted_double().unwrap(), f64::INFINITY);
963 assert_eq!(inp.read_sorted_double().unwrap(), f64::NEG_INFINITY);
964 assert_eq!(inp.available(), 0);
965 }
966
967 #[test]
969 fn test_packed_int_specific_sizes_round_trip() {
970 let cases: &[(i32, usize)] =
971 &[(119, 1), (0xFFFF + 119, 3), (i32::MAX, 5)];
972 for &(val, expected_size) in cases {
973 let mut out = TupleOutput::new();
974 out.write_packed_int(val);
975 assert_eq!(out.len(), expected_size, "packed_int {} size", val);
976 let mut inp = TupleInput::new(&out.to_vec());
977 assert_eq!(inp.read_packed_int().unwrap(), val);
978 }
979 }
980
981 #[test]
983 fn test_packed_long_specific_sizes_round_trip() {
984 let cases: &[(i64, usize)] =
985 &[(119, 1), (0xFFFF_FFFF_i64 + 119, 5), (i64::MAX, 9)];
986 for &(val, expected_size) in cases {
987 let mut out = TupleOutput::new();
988 out.write_packed_long(val);
989 assert_eq!(out.len(), expected_size, "packed_long {} size", val);
990 let mut inp = TupleInput::new(&out.to_vec());
991 assert_eq!(inp.read_packed_long().unwrap(), val);
992 }
993 }
994
995 #[test]
997 fn test_sorted_packed_int_specific_sizes_round_trip() {
998 let cases: &[(i32, usize)] = &[
999 (-1, 1),
1000 (0, 1),
1001 (1, 1),
1002 (-119, 1),
1003 (120, 1),
1004 (121, 2),
1005 (-120, 2),
1006 (i32::MAX, 5),
1007 (i32::MIN, 5),
1008 ];
1009 for &(val, expected_size) in cases {
1010 let mut out = TupleOutput::new();
1011 out.write_sorted_packed_int(val);
1012 assert_eq!(
1013 out.len(),
1014 expected_size,
1015 "sorted_packed_int {} size",
1016 val
1017 );
1018 let mut inp = TupleInput::new(&out.to_vec());
1019 assert_eq!(inp.read_sorted_packed_int().unwrap(), val);
1020 }
1021 }
1022
1023 #[test]
1025 fn test_sorted_packed_long_specific_sizes_round_trip() {
1026 let cases: &[(i64, usize)] = &[
1027 (-1, 1),
1028 (0, 1),
1029 (1, 1),
1030 (-119, 1),
1031 (120, 1),
1032 (121, 2),
1033 (-120, 2),
1034 (i64::MAX, 9),
1035 (i64::MIN, 9),
1036 ];
1037 for &(val, expected_size) in cases {
1038 let mut out = TupleOutput::new();
1039 out.write_sorted_packed_long(val);
1040 assert_eq!(
1041 out.len(),
1042 expected_size,
1043 "sorted_packed_long {} size",
1044 val
1045 );
1046 let mut inp = TupleInput::new(&out.to_vec());
1047 assert_eq!(inp.read_sorted_packed_long().unwrap(), val);
1048 }
1049 }
1050
1051 #[test]
1053 fn test_unsigned_byte_sequence_read() {
1054 let mut out = TupleOutput::new();
1055 out.write_u8(0);
1056 out.write_u8(1);
1057 out.write_u8(255);
1058 assert_eq!(out.len(), 3);
1059 let mut inp = TupleInput::new(&out.to_vec());
1060 assert_eq!(inp.read_u8().unwrap(), 0);
1061 assert_eq!(inp.read_u8().unwrap(), 1);
1062 assert_eq!(inp.read_u8().unwrap(), 255);
1063 assert_eq!(inp.available(), 0);
1064 }
1065
1066 #[test]
1068 fn test_unsigned_short_sequence_read() {
1069 let mut out = TupleOutput::new();
1070 out.write_u16(0);
1071 out.write_u16(1);
1072 out.write_u16(0xFFFF);
1073 assert_eq!(out.len(), 6);
1074 let mut inp = TupleInput::new(&out.to_vec());
1075 assert_eq!(inp.read_u16().unwrap(), 0);
1076 assert_eq!(inp.read_u16().unwrap(), 1);
1077 assert_eq!(inp.read_u16().unwrap(), 0xFFFF);
1078 assert_eq!(inp.available(), 0);
1079 }
1080
1081 #[test]
1083 fn test_unsigned_int_sequence_read() {
1084 let mut out = TupleOutput::new();
1085 out.write_u32(0);
1086 out.write_u32(1);
1087 out.write_u32(0xFFFF_FFFF);
1088 assert_eq!(out.len(), 12);
1089 let mut inp = TupleInput::new(&out.to_vec());
1090 assert_eq!(inp.read_u32().unwrap(), 0);
1091 assert_eq!(inp.read_u32().unwrap(), 1);
1092 assert_eq!(inp.read_u32().unwrap(), 0xFFFF_FFFF);
1093 assert_eq!(inp.available(), 0);
1094 }
1095
1096 #[test]
1102 fn test_string_then_int_interleaved() {
1103 let mut out = TupleOutput::new();
1104 out.write_string("abc");
1105 out.write_i32(123);
1106 assert_eq!(out.len(), 9);
1108 let mut inp = TupleInput::new(&out.to_vec());
1109 assert_eq!(inp.read_string().unwrap(), "abc");
1110 assert_eq!(inp.available(), 4);
1111 assert_eq!(inp.read_i32().unwrap(), 123);
1112 assert_eq!(inp.available(), 0);
1113 }
1114
1115 #[test]
1117 fn test_char_size_and_round_trip() {
1118 let mut out = TupleOutput::new();
1119 out.write_char(b'a' as u16);
1120 assert_eq!(out.len(), 2);
1121 let mut inp = TupleInput::new(&out.to_vec());
1122 assert_eq!(inp.read_char().unwrap(), b'a' as u16);
1123 assert_eq!(inp.available(), 0);
1124 }
1125
1126 #[test]
1128 fn test_from_vec_constructor() {
1129 let data = vec![0x80u8, 0x00, 0x00, 0x2B]; let mut inp1 = TupleInput::from_vec(data.clone());
1131 let mut inp2 = TupleInput::new(&data);
1132 assert_eq!(inp1.read_i32().unwrap(), inp2.read_i32().unwrap());
1133 }
1134
1135 #[test]
1141 fn test_i8_edge_values() {
1142 for &v in &[i8::MIN, -1i8, 0, 1, i8::MAX] {
1143 let mut out = TupleOutput::new();
1144 out.write_i8(v);
1145 assert_eq!(out.len(), 1, "i8 {} should be 1 byte", v);
1146 let mut inp = TupleInput::new(&out.to_vec());
1147 assert_eq!(inp.read_i8().unwrap(), v);
1148 }
1149 }
1150
1151 #[test]
1153 fn test_i16_edge_values() {
1154 for &v in &[i16::MIN, -1i16, 0, 1, i16::MAX] {
1155 let mut out = TupleOutput::new();
1156 out.write_i16(v);
1157 assert_eq!(out.len(), 2, "i16 {} should be 2 bytes", v);
1158 let mut inp = TupleInput::new(&out.to_vec());
1159 assert_eq!(inp.read_i16().unwrap(), v);
1160 }
1161 }
1162
1163 #[test]
1165 fn test_i32_wrapping_values() {
1166 let cases: &[(i32, i32)] = &[
1169 (i32::MAX.wrapping_add(1), i32::MIN), (i32::MIN.wrapping_sub(1), i32::MAX), ];
1172 for &(input_val, expected) in cases {
1173 let mut out = TupleOutput::new();
1174 out.write_i32(input_val);
1175 let mut inp = TupleInput::new(&out.to_vec());
1176 assert_eq!(inp.read_i32().unwrap(), expected);
1177 }
1178 }
1179
1180 #[test]
1182 fn test_i64_wrapping_values() {
1183 let cases: &[(i64, i64)] = &[
1184 (i64::MAX.wrapping_add(1), i64::MIN),
1185 (i64::MIN.wrapping_sub(1), i64::MAX),
1186 ];
1187 for &(input_val, expected) in cases {
1188 let mut out = TupleOutput::new();
1189 out.write_i64(input_val);
1190 let mut inp = TupleInput::new(&out.to_vec());
1191 assert_eq!(inp.read_i64().unwrap(), expected);
1192 }
1193 }
1194
1195 #[test]
1197 fn test_float_special_values_round_trip() {
1198 let special: &[f32] = &[
1199 f32::NAN,
1200 f32::INFINITY,
1201 f32::NEG_INFINITY,
1202 f32::MAX,
1203 f32::MIN,
1204 f32::MIN_POSITIVE,
1205 0.0,
1206 -0.0,
1207 1.0,
1208 -1.0,
1209 ];
1210 for &v in special {
1211 let mut out = TupleOutput::new();
1212 out.write_float(v);
1213 assert_eq!(out.len(), 4);
1214 let mut inp = TupleInput::new(&out.to_vec());
1215 let got = inp.read_float().unwrap();
1216 if v.is_nan() {
1217 assert!(got.is_nan(), "NaN should round-trip as NaN");
1218 } else {
1219 assert_eq!(
1220 got.to_bits(),
1221 v.to_bits(),
1222 "float {} should round-trip",
1223 v
1224 );
1225 }
1226 }
1227 }
1228
1229 #[test]
1231 fn test_double_special_values_round_trip() {
1232 let special: &[f64] = &[
1233 f64::NAN,
1234 f64::INFINITY,
1235 f64::NEG_INFINITY,
1236 f64::MAX,
1237 f64::MIN,
1238 f64::MIN_POSITIVE,
1239 0.0,
1240 -0.0,
1241 1.0,
1242 -1.0,
1243 ];
1244 for &v in special {
1245 let mut out = TupleOutput::new();
1246 out.write_double(v);
1247 assert_eq!(out.len(), 8);
1248 let mut inp = TupleInput::new(&out.to_vec());
1249 let got = inp.read_double().unwrap();
1250 if v.is_nan() {
1251 assert!(got.is_nan(), "NaN should round-trip as NaN");
1252 } else {
1253 assert_eq!(
1254 got.to_bits(),
1255 v.to_bits(),
1256 "double {} should round-trip",
1257 v
1258 );
1259 }
1260 }
1261 }
1262
1263 #[test]
1265 fn test_sorted_float_special_values_round_trip() {
1266 let special: &[f32] = &[
1267 f32::NAN,
1268 f32::INFINITY,
1269 f32::NEG_INFINITY,
1270 f32::MAX,
1271 f32::MIN,
1272 f32::MIN_POSITIVE,
1273 0.0,
1274 -0.0,
1275 1.0,
1276 -1.0,
1277 123.123,
1278 ];
1279 for &v in special {
1280 let mut out = TupleOutput::new();
1281 out.write_sorted_float(v);
1282 assert_eq!(out.len(), 4);
1283 let mut inp = TupleInput::new(&out.to_vec());
1284 let got = inp.read_sorted_float().unwrap();
1285 if v.is_nan() {
1286 assert!(got.is_nan(), "NaN should round-trip");
1287 } else {
1288 assert_eq!(
1289 got.to_bits(),
1290 v.to_bits(),
1291 "sorted float {} should round-trip",
1292 v
1293 );
1294 }
1295 }
1296 }
1297
1298 #[test]
1300 fn test_sorted_double_special_values_round_trip() {
1301 let special: &[f64] = &[
1302 f64::NAN,
1303 f64::INFINITY,
1304 f64::NEG_INFINITY,
1305 f64::MAX,
1306 f64::MIN,
1307 f64::MIN_POSITIVE,
1308 0.0,
1309 -0.0,
1310 1.0,
1311 -1.0,
1312 123.123,
1313 ];
1314 for &v in special {
1315 let mut out = TupleOutput::new();
1316 out.write_sorted_double(v);
1317 assert_eq!(out.len(), 8);
1318 let mut inp = TupleInput::new(&out.to_vec());
1319 let got = inp.read_sorted_double().unwrap();
1320 if v.is_nan() {
1321 assert!(got.is_nan(), "NaN should round-trip");
1322 } else {
1323 assert_eq!(
1324 got.to_bits(),
1325 v.to_bits(),
1326 "sorted double {} should round-trip",
1327 v
1328 );
1329 }
1330 }
1331 }
1332}