1use crate::{InvalidIntegerLength, TryPutIntegerError};
7
8use super::{Buffer, InlineSize, TryGetError, TryPutError, panic_advance, panic_does_not_fit};
9
10#[inline]
15pub(crate) fn assert_uint_width(nbytes: usize) {
16 if nbytes > 8 {
17 panic_does_not_fit(8, nbytes);
18 }
19}
20
21pub(crate) const fn sign_extend(val: u64, nbytes: usize) -> i64 {
23 if nbytes == 0 {
24 return 0;
25 }
26
27 let shift = (8 - nbytes) * 8;
28 (val << shift) as i64 >> shift
29}
30
31macro_rules! impl_try_get {
32 ($this:ident, $typ:tt::$conv:tt) => {{
33 const SIZE: usize = core::mem::size_of::<$typ>();
34
35 let remaining = $this.remaining();
36
37 if remaining < SIZE {
38 return Err(TryGetError {
39 requested: SIZE,
40 available: remaining,
41 });
42 }
43
44 unsafe {
45 let ptr = $this.buf.as_ptr().add($this.cur.to_usize());
46 let val = $typ::$conv(*(ptr as *const _ as *const [_; SIZE]));
47
48 $this.cur = InlineSize::from_u8($this.cur.to_u8() + SIZE as u8);
49 Ok(val)
50 }
51 }};
52 (le($this:ident, $typ:tt, $len_to_read:expr)) => {{
53 const SIZE: usize = core::mem::size_of::<$typ>();
54
55 assert_uint_width($len_to_read);
56
57 let remaining = $this.remaining();
58 if remaining < $len_to_read {
59 return Err(TryGetError {
60 requested: $len_to_read,
61 available: remaining,
62 });
63 }
64
65 let mut buf = [0u8; SIZE];
66
67 unsafe {
68 core::ptr::copy_nonoverlapping(
71 $this.buf.as_ptr().add($this.cur.to_usize()).cast::<u8>(),
72 buf.as_mut_ptr(),
73 $len_to_read,
74 );
75 let val = $typ::from_le_bytes(buf);
76
77 $this.cur = InlineSize::from_u8($this.cur.to_u8() + $len_to_read as u8);
78 Ok(val)
79 }
80 }};
81 (be($this:ident, $typ:tt, $len_to_read:expr)) => {{
82 const SIZE: usize = core::mem::size_of::<$typ>();
83
84 assert_uint_width($len_to_read);
85
86 let remaining = $this.remaining();
87 if remaining < $len_to_read {
88 return Err(TryGetError {
89 requested: $len_to_read,
90 available: remaining,
91 });
92 }
93
94 let slice_at = SIZE - $len_to_read;
95 let mut buf = [0u8; SIZE];
96
97 unsafe {
98 core::ptr::copy_nonoverlapping(
101 $this.buf.as_ptr().add($this.cur.to_usize()).cast::<u8>(),
102 buf.as_mut_ptr().add(slice_at),
103 $len_to_read,
104 );
105 let val = $typ::from_be_bytes(buf);
106
107 $this.cur = InlineSize::from_u8($this.cur.to_u8() + $len_to_read as u8);
108 Ok(val)
109 }
110 }};
111}
112
113macro_rules! try_get_and_get {
114 ($long:literal: { $($typ:ident::$conv:ident$(::$order:ident)?),+$(,)? }) => {
115 paste::paste! {
116 $(
117 #[doc = "Gets a `" $typ "` from `self` in " $long " byte order."]
118 #[inline]
125 pub fn [<get_ $typ:lower $(_ $order)?>](&mut self) -> $typ {
126 self.[<try_get_ $typ:lower $(_ $order)?>]().unwrap_or_else(|e| panic_advance(e.available, e.requested))
127 }
128
129 #[doc = "Tries to get a `" $typ "` from `self` in " $long " byte order."]
130 #[inline]
137 pub const fn [<try_get_ $typ:lower $(_ $order)?>](&mut self) -> Result<$typ, TryGetError> {
138 impl_try_get!(self, $typ::$conv)
139 }
140 )*
141 }
142 };
143}
144
145macro_rules! try_put_and_put {
146 ($long:literal: { $($typ:ident::$conv:ident$(::$order:ident)?),+$(,)? }) => {
147 paste::paste! {
148 $(
149 #[doc = "Puts a `" $typ "` to `self` in " $long " byte order."]
150 #[inline]
157 pub fn [<put_ $typ:lower $(_ $order)?>](&mut self, val: $typ) {
158 self.[<try_put_ $typ:lower $(_ $order)?>](val)
159 .unwrap_or_else(|e| panic_advance(e.available, e.requested))
160 }
161
162 #[doc = "Tries to put a `" $typ "` to `self` in " $long " byte order."]
163 #[inline]
170 pub const fn [<try_put_ $typ:lower $(_ $order)?>](&mut self, val: $typ) -> Result<(), TryPutError> {
171 self.try_put_slice(val.$conv().as_slice())
172 }
173 )*
174 }
175 };
176}
177
178impl Buffer {
179 try_get_and_get!(
180 "little-endian": {
181 u16::from_le_bytes::le,
182 i16::from_le_bytes::le,
183 u32::from_le_bytes::le,
184 i32::from_le_bytes::le,
185 u64::from_le_bytes::le,
186 i64::from_le_bytes::le,
187 u128::from_le_bytes::le,
188 i128::from_le_bytes::le,
189 }
190 );
191
192 try_get_and_get!(
193 "big-endian": {
194 u16::from_be_bytes,
195 i16::from_be_bytes,
196 u32::from_be_bytes,
197 i32::from_be_bytes,
198 u64::from_be_bytes,
199 i64::from_be_bytes,
200 u128::from_be_bytes,
201 i128::from_be_bytes,
202 }
203 );
204
205 try_get_and_get!(
206 "native-endian": {
207 u16::from_ne_bytes::ne,
208 i16::from_ne_bytes::ne,
209 u32::from_ne_bytes::ne,
210 i32::from_ne_bytes::ne,
211 u64::from_ne_bytes::ne,
212 i64::from_ne_bytes::ne,
213 u128::from_ne_bytes::ne,
214 i128::from_ne_bytes::ne,
215 }
216 );
217
218 #[inline]
236 pub fn get_u8(&mut self) -> u8 {
237 match self.try_get_u8() {
238 Ok(v) => v,
239 Err(e) => panic_advance(e.available, e.requested),
240 }
241 }
242
243 #[inline]
261 pub const fn try_get_u8(&mut self) -> Result<u8, TryGetError> {
262 if self.remaining() < 1 {
263 return Err(TryGetError {
264 requested: 1,
265 available: self.remaining(),
266 });
267 }
268
269 let ret = unsafe { self.buf[self.cur.to_usize()].assume_init_read() };
271 self.cur = unsafe { InlineSize::from_u8(self.cur.to_u8() + 1) };
272 Ok(ret)
273 }
274
275 #[inline]
283 pub fn get_i8(&mut self) -> i8 {
284 Self::get_u8(self) as i8
285 }
286
287 #[inline]
295 pub const fn try_get_i8(&mut self) -> Result<i8, TryGetError> {
296 match Self::try_get_u8(self) {
297 Ok(v) => Ok(v as i8),
298 Err(e) => Err(e),
299 }
300 }
301
302 #[inline]
320 pub fn get_f32(&mut self) -> f32 {
321 f32::from_bits(self.get_u32())
322 }
323
324 #[inline]
333 pub const fn try_get_f32(&mut self) -> Result<f32, TryGetError> {
334 match self.try_get_u32() {
335 Ok(bits) => Ok(f32::from_bits(bits)),
336 Err(e) => Err(e),
337 }
338 }
339
340 #[inline]
349 pub fn get_f32_le(&mut self) -> f32 {
350 f32::from_bits(self.get_u32_le())
351 }
352
353 #[inline]
362 pub const fn try_get_f32_le(&mut self) -> Result<f32, TryGetError> {
363 match self.try_get_u32_le() {
364 Ok(bits) => Ok(f32::from_bits(bits)),
365 Err(e) => Err(e),
366 }
367 }
368
369 #[inline]
378 pub fn get_f32_ne(&mut self) -> f32 {
379 f32::from_bits(self.get_u32_ne())
380 }
381
382 #[inline]
391 pub const fn try_get_f32_ne(&mut self) -> Result<f32, TryGetError> {
392 match self.try_get_u32_ne() {
393 Ok(bits) => Ok(f32::from_bits(bits)),
394 Err(e) => Err(e),
395 }
396 }
397
398 #[inline]
407 pub fn get_f64(&mut self) -> f64 {
408 f64::from_bits(self.get_u64())
409 }
410
411 #[inline]
420 pub const fn try_get_f64(&mut self) -> Result<f64, TryGetError> {
421 match self.try_get_u64() {
422 Ok(bits) => Ok(f64::from_bits(bits)),
423 Err(e) => Err(e),
424 }
425 }
426
427 #[inline]
436 pub fn get_f64_le(&mut self) -> f64 {
437 f64::from_bits(self.get_u64_le())
438 }
439
440 #[inline]
449 pub const fn try_get_f64_le(&mut self) -> Result<f64, TryGetError> {
450 match self.try_get_u64_le() {
451 Ok(bits) => Ok(f64::from_bits(bits)),
452 Err(e) => Err(e),
453 }
454 }
455
456 #[inline]
465 pub fn get_f64_ne(&mut self) -> f64 {
466 f64::from_bits(self.get_u64_ne())
467 }
468
469 #[inline]
478 pub const fn try_get_f64_ne(&mut self) -> Result<f64, TryGetError> {
479 match self.try_get_u64_ne() {
480 Ok(bits) => Ok(f64::from_bits(bits)),
481 Err(e) => Err(e),
482 }
483 }
484
485 #[inline]
503 pub fn get_uint(&mut self, nbytes: usize) -> u64 {
504 self
505 .try_get_uint(nbytes)
506 .unwrap_or_else(|e| panic_advance(e.available, e.requested))
507 }
508
509 #[inline]
521 pub fn try_get_uint(&mut self, nbytes: usize) -> Result<u64, TryGetError> {
522 impl_try_get!(be(self, u64, nbytes))
523 }
524
525 #[inline]
534 pub fn get_uint_le(&mut self, nbytes: usize) -> u64 {
535 self
536 .try_get_uint_le(nbytes)
537 .unwrap_or_else(|e| panic_advance(e.available, e.requested))
538 }
539
540 #[inline]
552 pub fn try_get_uint_le(&mut self, nbytes: usize) -> Result<u64, TryGetError> {
553 impl_try_get!(le(self, u64, nbytes))
554 }
555
556 #[inline]
565 pub fn get_uint_ne(&mut self, nbytes: usize) -> u64 {
566 self
567 .try_get_uint_ne(nbytes)
568 .unwrap_or_else(|e| panic_advance(e.available, e.requested))
569 }
570
571 #[inline]
583 pub fn try_get_uint_ne(&mut self, nbytes: usize) -> Result<u64, TryGetError> {
584 if cfg!(target_endian = "big") {
585 self.try_get_uint(nbytes)
586 } else {
587 self.try_get_uint_le(nbytes)
588 }
589 }
590
591 #[inline]
600 pub fn get_int(&mut self, nbytes: usize) -> i64 {
601 sign_extend(self.get_uint(nbytes), nbytes)
602 }
603
604 #[inline]
616 pub fn try_get_int(&mut self, nbytes: usize) -> Result<i64, TryGetError> {
617 self
618 .try_get_uint(nbytes)
619 .map(|value| sign_extend(value, nbytes))
620 }
621
622 #[inline]
631 pub fn get_int_le(&mut self, nbytes: usize) -> i64 {
632 sign_extend(self.get_uint_le(nbytes), nbytes)
633 }
634
635 #[inline]
647 pub fn try_get_int_le(&mut self, nbytes: usize) -> Result<i64, TryGetError> {
648 self
649 .try_get_uint_le(nbytes)
650 .map(|value| sign_extend(value, nbytes))
651 }
652
653 #[inline]
662 pub fn get_int_ne(&mut self, nbytes: usize) -> i64 {
663 if cfg!(target_endian = "big") {
664 self.get_int(nbytes)
665 } else {
666 self.get_int_le(nbytes)
667 }
668 }
669
670 #[inline]
682 pub fn try_get_int_ne(&mut self, nbytes: usize) -> Result<i64, TryGetError> {
683 if cfg!(target_endian = "big") {
684 self.try_get_int(nbytes)
685 } else {
686 self.try_get_int_le(nbytes)
687 }
688 }
689}
690
691impl Buffer {
692 try_put_and_put!(
693 "little-endian": {
694 u16::to_le_bytes::le,
695 i16::to_le_bytes::le,
696 u32::to_le_bytes::le,
697 i32::to_le_bytes::le,
698 u64::to_le_bytes::le,
699 i64::to_le_bytes::le,
700 u128::to_le_bytes::le,
701 i128::to_le_bytes::le,
702 }
703 );
704
705 try_put_and_put!(
706 "big-endian": {
707 u16::to_be_bytes,
708 i16::to_be_bytes,
709 u32::to_be_bytes,
710 i32::to_be_bytes,
711 u64::to_be_bytes,
712 i64::to_be_bytes,
713 u128::to_be_bytes,
714 i128::to_be_bytes,
715 }
716 );
717
718 try_put_and_put!(
719 "native-endian": {
720 u16::to_ne_bytes::ne,
721 i16::to_ne_bytes::ne,
722 u32::to_ne_bytes::ne,
723 i32::to_ne_bytes::ne,
724 u64::to_ne_bytes::ne,
725 i64::to_ne_bytes::ne,
726 u128::to_ne_bytes::ne,
727 i128::to_ne_bytes::ne,
728 }
729 );
730
731 #[inline]
749 pub fn put_i8(&mut self, n: i8) {
750 self
751 .try_put_i8(n)
752 .unwrap_or_else(|e| panic_advance(e.available, e.requested))
753 }
754
755 #[inline]
763 pub const fn try_put_i8(&mut self, n: i8) -> Result<(), TryPutError> {
764 self.try_put_u8(n as u8)
765 }
766
767 #[inline]
776 pub fn put_uint(&mut self, n: u64, nbytes: usize) {
777 self
778 .try_put_uint(n, nbytes)
779 .unwrap_or_else(|e| panic!("{e}"));
780 }
781
782 #[inline]
790 pub const fn try_put_uint(&mut self, n: u64, nbytes: usize) -> Result<(), TryPutIntegerError> {
791 if nbytes > 8 {
792 return Err(TryPutIntegerError::InvalidLength(InvalidIntegerLength(
793 nbytes,
794 )));
795 }
796
797 let available = self.remaining_mut();
798 if available < nbytes {
799 return Err(TryPutIntegerError::NotEnoughSpace(TryPutError {
800 requested: nbytes,
801 available,
802 }));
803 }
804
805 let bytes = n.to_be_bytes();
806 let mut i = 0;
807 while i < nbytes {
808 unsafe {
811 *self
812 .buf
813 .as_mut_ptr()
814 .add(self.end.to_usize() + i)
815 .cast::<u8>() = bytes[8 - nbytes + i];
816 }
817 i += 1;
818 }
819 self.end = unsafe { InlineSize::from_u8(self.end.to_u8() + nbytes as u8) };
822 Ok(())
823 }
824
825 #[inline]
834 pub fn put_uint_le(&mut self, n: u64, nbytes: usize) {
835 self
836 .try_put_uint_le(n, nbytes)
837 .unwrap_or_else(|e| panic!("{e}"))
838 }
839
840 #[inline]
848 pub const fn try_put_uint_le(&mut self, n: u64, nbytes: usize) -> Result<(), TryPutIntegerError> {
849 if nbytes > 8 {
850 return Err(TryPutIntegerError::InvalidLength(InvalidIntegerLength(
851 nbytes,
852 )));
853 }
854
855 let available = self.remaining_mut();
856 if available < nbytes {
857 return Err(TryPutIntegerError::NotEnoughSpace(TryPutError {
858 requested: nbytes,
859 available,
860 }));
861 }
862
863 let bytes = n.to_le_bytes();
864 let mut i = 0;
865 while i < nbytes {
866 unsafe {
869 *self
870 .buf
871 .as_mut_ptr()
872 .add(self.end.to_usize() + i)
873 .cast::<u8>() = bytes[i];
874 }
875 i += 1;
876 }
877 self.end = unsafe { InlineSize::from_u8(self.end.to_u8() + nbytes as u8) };
880 Ok(())
881 }
882
883 #[inline]
892 pub fn put_uint_ne(&mut self, n: u64, nbytes: usize) {
893 self
894 .try_put_uint_ne(n, nbytes)
895 .unwrap_or_else(|e| panic!("{e}"))
896 }
897
898 #[inline]
910 pub const fn try_put_uint_ne(&mut self, n: u64, nbytes: usize) -> Result<(), TryPutIntegerError> {
911 if cfg!(target_endian = "big") {
912 self.try_put_uint(n, nbytes)
913 } else {
914 self.try_put_uint_le(n, nbytes)
915 }
916 }
917
918 #[inline]
927 pub fn put_int(&mut self, n: i64, nbytes: usize) {
928 self
929 .try_put_int(n, nbytes)
930 .unwrap_or_else(|e| panic!("{e}"));
931 }
932
933 #[inline]
945 pub const fn try_put_int(&mut self, n: i64, nbytes: usize) -> Result<(), TryPutIntegerError> {
946 self.try_put_uint(n as u64, nbytes)
947 }
948
949 #[inline]
958 pub fn put_int_le(&mut self, n: i64, nbytes: usize) {
959 self
960 .try_put_int_le(n, nbytes)
961 .unwrap_or_else(|e| panic!("{e}"));
962 }
963
964 #[inline]
976 pub const fn try_put_int_le(&mut self, n: i64, nbytes: usize) -> Result<(), TryPutIntegerError> {
977 self.try_put_uint_le(n as u64, nbytes)
978 }
979
980 #[inline]
989 pub fn put_int_ne(&mut self, n: i64, nbytes: usize) {
990 self
991 .try_put_int_ne(n, nbytes)
992 .unwrap_or_else(|e| panic!("{e}"));
993 }
994
995 #[inline]
1007 pub const fn try_put_int_ne(&mut self, n: i64, nbytes: usize) -> Result<(), TryPutIntegerError> {
1008 if cfg!(target_endian = "big") {
1009 self.try_put_int(n, nbytes)
1010 } else {
1011 self.try_put_int_le(n, nbytes)
1012 }
1013 }
1014
1015 #[inline]
1024 pub fn put_f32(&mut self, n: f32) {
1025 self.put_u32(n.to_bits())
1026 }
1027
1028 #[inline]
1037 pub const fn try_put_f32(&mut self, n: f32) -> Result<(), TryPutError> {
1038 self.try_put_u32(n.to_bits())
1039 }
1040
1041 #[inline]
1050 pub fn put_f32_le(&mut self, n: f32) {
1051 self.put_u32_le(n.to_bits())
1052 }
1053
1054 #[inline]
1063 pub const fn try_put_f32_le(&mut self, n: f32) -> Result<(), TryPutError> {
1064 self.try_put_u32_le(n.to_bits())
1065 }
1066
1067 #[inline]
1076 pub fn put_f32_ne(&mut self, n: f32) {
1077 self.put_u32_ne(n.to_bits())
1078 }
1079
1080 #[inline]
1089 pub const fn try_put_f32_ne(&mut self, n: f32) -> Result<(), TryPutError> {
1090 self.try_put_u32_ne(n.to_bits())
1091 }
1092
1093 #[inline]
1102 pub fn put_f64(&mut self, n: f64) {
1103 self.put_u64(n.to_bits())
1104 }
1105
1106 #[inline]
1115 pub const fn try_put_f64(&mut self, n: f64) -> Result<(), TryPutError> {
1116 self.try_put_u64(n.to_bits())
1117 }
1118
1119 #[inline]
1128 pub fn put_f64_le(&mut self, n: f64) {
1129 self.put_u64_le(n.to_bits())
1130 }
1131
1132 #[inline]
1141 pub const fn try_put_f64_le(&mut self, n: f64) -> Result<(), TryPutError> {
1142 self.try_put_u64_le(n.to_bits())
1143 }
1144
1145 #[inline]
1154 pub fn put_f64_ne(&mut self, n: f64) {
1155 self.put_u64_ne(n.to_bits())
1156 }
1157
1158 #[inline]
1167 pub const fn try_put_f64_ne(&mut self, n: f64) -> Result<(), TryPutError> {
1168 self.try_put_u64_ne(n.to_bits())
1169 }
1170}
1171
1172#[cfg(test)]
1173mod tests {
1174 #[cfg(not(feature = "std"))]
1175 extern crate std;
1176
1177 use super::*;
1178
1179 #[test]
1180 fn test_get_u8() {
1181 let mut buf = Buffer::try_from(&[0x01, 0x02, 0x03][..]).unwrap();
1182 assert_eq!(buf.get_u8(), 0x01);
1183 assert_eq!(buf.get_u8(), 0x02);
1184 assert_eq!(buf.get_u8(), 0x03);
1185 assert_eq!(buf.remaining(), 0);
1186 }
1187
1188 #[test]
1189 fn test_try_get_u8_error() {
1190 let mut buf = Buffer::new();
1191 assert!(buf.try_get_u8().is_err());
1192 }
1193
1194 #[test]
1195 fn test_get_i8() {
1196 let mut buf = Buffer::try_from(&[0xFF, 0x7F, 0x80][..]).unwrap();
1197 assert_eq!(buf.get_i8(), -1);
1198 assert_eq!(buf.get_i8(), 127);
1199 assert_eq!(buf.get_i8(), -128);
1200 }
1201
1202 #[test]
1203 fn test_get_u16() {
1204 let mut buf = Buffer::try_from(&[0x01, 0x02, 0x03, 0x04][..]).unwrap();
1205 assert_eq!(buf.get_u16(), 0x0102);
1206 assert_eq!(buf.get_u16(), 0x0304);
1207 }
1208
1209 #[test]
1210 fn test_get_u16_le() {
1211 let mut buf = Buffer::try_from(&[0x01, 0x02, 0x03, 0x04][..]).unwrap();
1212 assert_eq!(buf.get_u16_le(), 0x0201);
1213 assert_eq!(buf.get_u16_le(), 0x0403);
1214 }
1215
1216 #[test]
1217 fn test_get_i16() {
1218 let mut buf = Buffer::try_from(&[0xFF, 0xFF, 0x7F, 0xFF][..]).unwrap();
1219 assert_eq!(buf.get_i16(), -1);
1220 assert_eq!(buf.get_i16(), 32767);
1221 }
1222
1223 #[test]
1224 fn test_get_u32() {
1225 let mut buf = Buffer::try_from(&[0x01, 0x02, 0x03, 0x04][..]).unwrap();
1226 assert_eq!(buf.get_u32(), 0x01020304);
1227 }
1228
1229 #[test]
1230 fn test_get_u32_le() {
1231 let mut buf = Buffer::try_from(&[0x01, 0x02, 0x03, 0x04][..]).unwrap();
1232 assert_eq!(buf.get_u32_le(), 0x04030201);
1233 }
1234
1235 #[test]
1236 fn test_get_i32() {
1237 let mut buf = Buffer::try_from(&[0xFF, 0xFF, 0xFF, 0xFF][..]).unwrap();
1238 assert_eq!(buf.get_i32(), -1);
1239 }
1240
1241 #[test]
1242 fn test_get_u64() {
1243 let mut buf = Buffer::try_from(&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08][..]).unwrap();
1244 assert_eq!(buf.get_u64(), 0x0102030405060708);
1245 }
1246
1247 #[test]
1248 fn test_get_u64_le() {
1249 let mut buf = Buffer::try_from(&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08][..]).unwrap();
1250 assert_eq!(buf.get_u64_le(), 0x0807060504030201);
1251 }
1252
1253 #[test]
1254 fn test_get_i64() {
1255 let mut buf = Buffer::try_from(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF][..]).unwrap();
1256 assert_eq!(buf.get_i64(), -1);
1257 }
1258
1259 #[test]
1260 fn test_get_u128() {
1261 let mut buf = Buffer::try_from(
1262 &[
1263 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1264 0x10,
1265 ][..],
1266 )
1267 .unwrap();
1268 assert_eq!(buf.get_u128(), 0x0102030405060708090A0B0C0D0E0F10);
1269 }
1270
1271 #[test]
1272 fn test_get_u128_le() {
1273 let mut buf = Buffer::try_from(
1274 &[
1275 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1276 0x10,
1277 ][..],
1278 )
1279 .unwrap();
1280 assert_eq!(buf.get_u128_le(), 0x100F0E0D0C0B0A090807060504030201);
1281 }
1282
1283 #[test]
1284 fn test_get_i128() {
1285 let mut buf = Buffer::try_from(
1286 &[
1287 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1288 0xFF,
1289 ][..],
1290 )
1291 .unwrap();
1292 assert_eq!(buf.get_i128(), -1);
1293 }
1294
1295 #[test]
1296 fn test_get_f32() {
1297 let mut buf = Buffer::try_from(&[0x41, 0x48, 0x00, 0x00][..]).unwrap();
1298 assert_eq!(buf.get_f32(), 12.5);
1299 }
1300
1301 #[test]
1302 fn test_get_f32_le() {
1303 let mut buf = Buffer::try_from(&[0x00, 0x00, 0x48, 0x41][..]).unwrap();
1304 assert_eq!(buf.get_f32_le(), 12.5);
1305 }
1306
1307 #[test]
1308 fn test_get_f64() {
1309 let mut buf = Buffer::try_from(&[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]).unwrap();
1310 assert_eq!(buf.get_f64(), 12.5);
1311 }
1312
1313 #[test]
1314 fn test_get_f64_le() {
1315 let mut buf = Buffer::try_from(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40][..]).unwrap();
1316 assert_eq!(buf.get_f64_le(), 12.5);
1317 }
1318
1319 #[test]
1320 fn test_get_uint() {
1321 let mut buf = Buffer::try_from(&[0x01, 0x02, 0x03][..]).unwrap();
1322 assert_eq!(buf.get_uint(3), 0x010203);
1323 assert_eq!(buf.remaining(), 0);
1324 }
1325
1326 #[test]
1327 fn test_get_uint_le() {
1328 let mut buf = Buffer::try_from(&[0x01, 0x02, 0x03][..]).unwrap();
1329 assert_eq!(buf.get_uint_le(3), 0x030201);
1330 assert_eq!(buf.remaining(), 0);
1331 }
1332
1333 #[test]
1334 fn test_get_int() {
1335 let mut buf = Buffer::try_from(&[0xFF, 0xFF, 0xFF][..]).unwrap();
1336 assert_eq!(buf.get_int(3), -1);
1337 }
1338
1339 #[test]
1340 fn test_get_int_le() {
1341 let mut buf = Buffer::try_from(&[0xFF, 0xFF, 0xFF][..]).unwrap();
1342 assert_eq!(buf.get_int_le(3), -1);
1343 }
1344
1345 #[test]
1347 fn test_put_u8() {
1348 let mut buf = Buffer::new();
1349 buf.put_u8(0x01);
1350 buf.put_u8(0x02);
1351 assert_eq!(&buf[..], &[0x01, 0x02]);
1352 }
1353
1354 #[test]
1355 fn test_try_put_u8_error() {
1356 let mut buf = Buffer::try_from(&[0u8; 62][..]).unwrap();
1357 assert!(buf.try_put_u8(0xFF).is_err());
1358 }
1359
1360 #[test]
1361 fn test_put_i8() {
1362 let mut buf = Buffer::new();
1363 buf.put_i8(-1);
1364 buf.put_i8(127);
1365 assert_eq!(&buf[..], &[0xFF, 0x7F]);
1366 }
1367
1368 #[test]
1369 fn test_put_u16() {
1370 let mut buf = Buffer::new();
1371 buf.put_u16(0x0102);
1372 assert_eq!(&buf[..], &[0x01, 0x02]);
1373 }
1374
1375 #[test]
1376 fn test_put_u16_le() {
1377 let mut buf = Buffer::new();
1378 buf.put_u16_le(0x0102);
1379 assert_eq!(&buf[..], &[0x02, 0x01]);
1380 }
1381
1382 #[test]
1383 fn test_put_i16() {
1384 let mut buf = Buffer::new();
1385 buf.put_i16(-1);
1386 assert_eq!(&buf[..], &[0xFF, 0xFF]);
1387 }
1388
1389 #[test]
1390 fn test_put_u32() {
1391 let mut buf = Buffer::new();
1392 buf.put_u32(0x01020304);
1393 assert_eq!(&buf[..], &[0x01, 0x02, 0x03, 0x04]);
1394 }
1395
1396 #[test]
1397 fn test_put_u32_le() {
1398 let mut buf = Buffer::new();
1399 buf.put_u32_le(0x01020304);
1400 assert_eq!(&buf[..], &[0x04, 0x03, 0x02, 0x01]);
1401 }
1402
1403 #[test]
1404 fn test_put_i32() {
1405 let mut buf = Buffer::new();
1406 buf.put_i32(-1);
1407 assert_eq!(&buf[..], &[0xFF, 0xFF, 0xFF, 0xFF]);
1408 }
1409
1410 #[test]
1411 fn test_put_u64() {
1412 let mut buf = Buffer::new();
1413 buf.put_u64(0x0102030405060708);
1414 assert_eq!(&buf[..], &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]);
1415 }
1416
1417 #[test]
1418 fn test_put_u64_le() {
1419 let mut buf = Buffer::new();
1420 buf.put_u64_le(0x0102030405060708);
1421 assert_eq!(&buf[..], &[0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01]);
1422 }
1423
1424 #[test]
1425 fn test_put_i64() {
1426 let mut buf = Buffer::new();
1427 buf.put_i64(-1);
1428 assert_eq!(&buf[..], &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]);
1429 }
1430
1431 #[test]
1432 fn test_put_u128() {
1433 let mut buf = Buffer::new();
1434 buf.put_u128(0x0102030405060708090A0B0C0D0E0F10);
1435 assert_eq!(
1436 &buf[..],
1437 &[
1438 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1439 0x10
1440 ]
1441 );
1442 }
1443
1444 #[test]
1445 fn test_put_u128_le() {
1446 let mut buf = Buffer::new();
1447 buf.put_u128_le(0x0102030405060708090A0B0C0D0E0F10);
1448 assert_eq!(
1449 &buf[..],
1450 &[
1451 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02,
1452 0x01
1453 ]
1454 );
1455 }
1456
1457 #[test]
1458 fn test_put_i128() {
1459 let mut buf = Buffer::new();
1460 buf.put_i128(-1);
1461 assert_eq!(
1462 &buf[..],
1463 &[
1464 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1465 0xFF
1466 ]
1467 );
1468 }
1469
1470 #[test]
1471 fn test_put_f32() {
1472 let mut buf = Buffer::new();
1473 buf.put_f32(12.5);
1474 assert_eq!(&buf[..], &[0x41, 0x48, 0x00, 0x00]);
1475 }
1476
1477 #[test]
1478 fn test_put_f32_le() {
1479 let mut buf = Buffer::new();
1480 buf.put_f32_le(12.5);
1481 assert_eq!(&buf[..], &[0x00, 0x00, 0x48, 0x41]);
1482 }
1483
1484 #[test]
1485 fn test_put_f64() {
1486 let mut buf = Buffer::new();
1487 buf.put_f64(12.5);
1488 assert_eq!(&buf[..], &[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
1489 }
1490
1491 #[test]
1492 fn test_put_f64_le() {
1493 let mut buf = Buffer::new();
1494 buf.put_f64_le(12.5);
1495 assert_eq!(&buf[..], &[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]);
1496 }
1497
1498 #[test]
1499 fn test_put_uint() {
1500 let mut buf = Buffer::new();
1501 buf.put_uint(0x010203, 3);
1502 assert_eq!(&buf[..], &[0x01, 0x02, 0x03]);
1503 }
1504
1505 #[test]
1506 fn test_put_uint_le() {
1507 let mut buf = Buffer::new();
1508 buf.put_uint_le(0x010203, 3);
1509 assert_eq!(&buf[..], &[0x03, 0x02, 0x01]);
1510 }
1511
1512 #[test]
1513 fn test_put_int() {
1514 let mut buf = Buffer::new();
1515 buf.put_int(-1, 3);
1516 assert_eq!(&buf[..], &[0xFF, 0xFF, 0xFF]);
1517 }
1518
1519 #[test]
1520 fn test_put_int_le() {
1521 let mut buf = Buffer::new();
1522 buf.put_int_le(-1, 3);
1523 assert_eq!(&buf[..], &[0xFF, 0xFF, 0xFF]);
1524 }
1525
1526 #[test]
1527 fn test_roundtrip_u16() {
1528 let mut buf = Buffer::new();
1529 let value: u16 = 0x1234;
1530 buf.put_u16(value);
1531 buf.advance(0);
1532 assert_eq!(buf.get_u16(), value);
1533 }
1534
1535 #[test]
1536 fn test_roundtrip_u32() {
1537 let mut buf = Buffer::new();
1538 let value: u32 = 0x12345678;
1539 buf.put_u32(value);
1540 buf.advance(0);
1541 assert_eq!(buf.get_u32(), value);
1542 }
1543
1544 #[test]
1545 fn test_roundtrip_u64() {
1546 let mut buf = Buffer::new();
1547 let value: u64 = 0x123456789ABCDEF0;
1548 buf.put_u64(value);
1549 buf.advance(0);
1550 assert_eq!(buf.get_u64(), value);
1551 }
1552
1553 #[test]
1554 fn test_roundtrip_u128() {
1555 let mut buf = Buffer::new();
1556 let value: u128 = 0x123456789ABCDEF0FEDCBA9876543210;
1557 buf.put_u128(value);
1558 buf.advance(0);
1559 assert_eq!(buf.get_u128(), value);
1560 }
1561
1562 #[test]
1563 fn test_roundtrip_f32() {
1564 let mut buf = Buffer::new();
1565 let value: f32 = core::f32::consts::PI;
1566 buf.put_f32(value);
1567 buf.advance(0);
1568 assert_eq!(buf.get_f32(), value);
1569 }
1570
1571 #[test]
1572 fn test_roundtrip_f64() {
1573 let mut buf = Buffer::new();
1574 let value: f64 = core::f64::consts::PI;
1575 buf.put_f64(value);
1576 buf.advance(0);
1577 assert_eq!(buf.get_f64(), value);
1578 }
1579
1580 #[test]
1581 fn test_mixed_operations() {
1582 let mut buf = Buffer::new();
1583 buf.put_u8(0x01);
1584 buf.put_u16(0x0203);
1585 buf.put_u32(0x04050607);
1586 buf.advance(0);
1587
1588 assert_eq!(buf.get_u8(), 0x01);
1589 assert_eq!(buf.get_u16(), 0x0203);
1590 assert_eq!(buf.get_u32(), 0x04050607);
1591 assert_eq!(buf.remaining(), 0);
1592 }
1593
1594 #[test]
1595 fn test_native_endian_consistency() {
1596 let mut buf = Buffer::new();
1597 let value: u32 = 0x12345678;
1598 buf.put_u32_ne(value);
1599 buf.advance(0);
1600 assert_eq!(buf.get_u32_ne(), value);
1601 }
1602
1603 #[test]
1604 #[should_panic]
1605 fn test_get_u8_panic() {
1606 let mut buf = Buffer::new();
1607 buf.get_u8(); }
1609
1610 #[test]
1611 #[should_panic]
1612 fn test_put_u8_panic() {
1613 let mut buf = Buffer::try_from(&[0u8; 62][..]).unwrap();
1614 buf.put_u8(0xFF); }
1616
1617 #[test]
1618 fn test_try_methods_errors() {
1619 let mut empty_buf = Buffer::new();
1620 assert!(empty_buf.try_get_u8().is_err());
1621 assert!(empty_buf.try_get_i8().is_err());
1622 assert!(empty_buf.try_get_u16().is_err());
1623 assert!(empty_buf.try_get_i16().is_err());
1624 assert!(empty_buf.try_get_u32().is_err());
1625 assert!(empty_buf.try_get_i32().is_err());
1626 assert!(empty_buf.try_get_u64().is_err());
1627 assert!(empty_buf.try_get_i64().is_err());
1628 assert!(empty_buf.try_get_u128().is_err());
1629 assert!(empty_buf.try_get_i128().is_err());
1630 assert!(empty_buf.try_get_f32().is_err());
1631 assert!(empty_buf.try_get_f64().is_err());
1632 assert!(empty_buf.try_get_uint(3).is_err());
1633 assert!(empty_buf.try_get_int(3).is_err());
1634
1635 let mut full_buf = Buffer::try_from(&[0u8; 62][..]).unwrap();
1636 assert!(full_buf.try_put_u8(0).is_err());
1637 assert!(full_buf.try_put_i8(0).is_err());
1638 }
1639
1640 #[test]
1641 fn variable_width_panics_before_availability_checks_and_preserves_cursor() {
1642 for operation in [
1643 |buffer: &mut Buffer| buffer.get_uint(9),
1644 |buffer: &mut Buffer| buffer.get_uint_le(9),
1645 |buffer: &mut Buffer| buffer.get_uint_ne(9),
1646 ] {
1647 let mut buffer = Buffer::try_from(&b"abc"[..]).unwrap();
1648 let panic = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| operation(&mut buffer)));
1649 assert!(panic.is_err());
1650 assert_eq!(buffer.as_slice(), b"abc");
1651 }
1652
1653 for operation in [
1654 |buffer: &mut Buffer| buffer.get_int(9),
1655 |buffer: &mut Buffer| buffer.get_int_le(9),
1656 |buffer: &mut Buffer| buffer.get_int_ne(9),
1657 ] {
1658 let mut buffer = Buffer::try_from(&b"abc"[..]).unwrap();
1659 let panic = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| operation(&mut buffer)));
1660 assert!(panic.is_err());
1661 assert_eq!(buffer.as_slice(), b"abc");
1662 }
1663 }
1664}