1#![cfg_attr(not(feature = "std"), no_std)]
2#![deny(unsafe_code)]
3
4#[cfg(feature = "alloc")]
5extern crate alloc;
6
7#[cfg(feature = "alloc")]
8#[doc(hidden)]
9pub use alloc::vec::Vec as __Vec;
10
11pub mod buffer;
12#[cfg(feature = "bytes")]
13pub mod bytes_impl;
14#[cfg(feature = "crc32")]
15pub mod checksum;
16pub mod error;
17pub mod limits;
18pub mod pool;
19#[cfg(feature = "simd")]
20pub mod simd;
21pub mod varint;
22pub mod version;
23
24pub use error::{DecodeError, EncodeError, ValidateError};
25
26pub trait Encode {
27 fn encode<W: BufferWriter>(&self, writer: &mut W) -> Result<(), EncodeError>;
28
29 #[cfg(feature = "alloc")]
30 fn encode_to_vec(&self) -> Result<alloc::vec::Vec<u8>, EncodeError> {
31 let mut writer = buffer::VecWriter::new();
32 self.encode(&mut writer)?;
33 Ok(writer.into_vec())
34 }
35}
36
37pub trait View<'a>: Sized {
38 fn view<R: BufferReader<'a>>(reader: &mut R) -> Result<Self, DecodeError>;
39}
40
41pub trait Decode: Sized {
42 fn decode<'a, R: BufferReader<'a>>(reader: &mut R) -> Result<Self, DecodeError>;
43}
44
45pub trait Validate<'a>: Sized {
46 fn validate<R: BufferReader<'a>>(reader: &mut R) -> Result<(), ValidateError>;
47}
48
49impl<'a, T: View<'a>> Validate<'a> for T {
50 #[inline]
51 fn validate<R: BufferReader<'a>>(reader: &mut R) -> Result<(), ValidateError> {
52 T::view(reader)?;
53 Ok(())
54 }
55}
56
57pub trait FixedSize {
58 const SIZE: usize;
59}
60
61macro_rules! impl_primitive {
62 ($ty:ty, $size:expr) => {
63 impl Encode for $ty {
64 #[inline]
65 fn encode<W: BufferWriter>(&self, writer: &mut W) -> Result<(), EncodeError> {
66 writer.write_all(&self.to_le_bytes())
67 }
68 }
69
70 impl Decode for $ty {
71 #[inline]
72 fn decode<'a, R: BufferReader<'a>>(reader: &mut R) -> Result<Self, DecodeError> {
73 let mut buf = [0u8; $size];
74 reader.read_exact(&mut buf)?;
75 Ok(Self::from_le_bytes(buf))
76 }
77 }
78
79 impl<'a> View<'a> for $ty {
80 #[inline]
81 fn view<R: BufferReader<'a>>(reader: &mut R) -> Result<Self, DecodeError> {
82 <Self as Decode>::decode(reader)
83 }
84 }
85
86 impl FixedSize for $ty {
87 const SIZE: usize = $size;
88 }
89 };
90}
91
92impl_primitive!(u8, 1);
93impl_primitive!(u16, 2);
94impl_primitive!(u32, 4);
95impl_primitive!(u64, 8);
96impl_primitive!(u128, 16);
97impl_primitive!(i8, 1);
98impl_primitive!(i16, 2);
99impl_primitive!(i32, 4);
100impl_primitive!(i64, 8);
101impl_primitive!(i128, 16);
102
103impl_primitive!(f32, 4);
104impl_primitive!(f64, 8);
105
106impl Encode for bool {
107 #[inline]
108 fn encode<W: BufferWriter>(&self, writer: &mut W) -> Result<(), EncodeError> {
109 writer.write_all(&[*self as u8])
110 }
111}
112
113impl Decode for bool {
114 #[inline]
115 fn decode<'a, R: BufferReader<'a>>(reader: &mut R) -> Result<Self, DecodeError> {
116 let mut buf = [0u8; 1];
117 reader.read_exact(&mut buf)?;
118 match buf[0] {
119 0 => Ok(false),
120 1 => Ok(true),
121 _ => Err(DecodeError::InvalidBool),
122 }
123 }
124}
125
126impl<'a> View<'a> for bool {
127 #[inline]
128 fn view<R: BufferReader<'a>>(reader: &mut R) -> Result<Self, DecodeError> {
129 <Self as Decode>::decode(reader)
130 }
131}
132
133impl FixedSize for bool {
134 const SIZE: usize = 1;
135}
136
137impl<T: Encode> Encode for Option<T> {
138 #[inline]
139 fn encode<W: BufferWriter>(&self, writer: &mut W) -> Result<(), EncodeError> {
140 match self {
141 None => 0u8.encode(writer),
142 Some(v) => {
143 1u8.encode(writer)?;
144 v.encode(writer)
145 }
146 }
147 }
148}
149
150impl<T: Decode> Decode for Option<T> {
151 #[inline]
152 fn decode<'a, R: BufferReader<'a>>(reader: &mut R) -> Result<Self, DecodeError> {
153 let tag = u8::decode(reader)?;
154 match tag {
155 0 => Ok(None),
156 1 => Ok(Some(T::decode(reader)?)),
157 _ => Err(DecodeError::InvalidOptionTag),
158 }
159 }
160}
161
162impl<'a, T: View<'a>> View<'a> for Option<T> {
163 #[inline]
164 fn view<R: BufferReader<'a>>(reader: &mut R) -> Result<Self, DecodeError> {
165 let tag = u8::decode(reader)?;
166 match tag {
167 0 => Ok(None),
168 1 => Ok(Some(T::view(reader)?)),
169 _ => Err(DecodeError::InvalidOptionTag),
170 }
171 }
172}
173
174pub trait BufferWriter {
175 fn write_all(&mut self, buf: &[u8]) -> Result<(), EncodeError>;
176}
177
178pub trait BufferReader<'a> {
179 fn peek(&self) -> Option<u8>;
180 fn next(&mut self) -> Option<u8>;
181 fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), DecodeError>;
182 fn remaining(&self) -> &'a [u8];
183 fn advance(&mut self, n: usize) -> Result<(), DecodeError>;
184
185 #[inline]
186 fn check_alloc(&mut self, _n: usize) -> Result<(), DecodeError> {
187 Ok(())
188 }
189
190 #[inline]
191 fn depth_enter(&mut self) -> Result<(), DecodeError> {
192 Ok(())
193 }
194
195 #[inline]
196 fn depth_exit(&mut self) {}
197}
198
199#[cfg(feature = "alloc")]
200impl Encode for alloc::string::String {
201 #[inline]
202 fn encode<W: BufferWriter>(&self, writer: &mut W) -> Result<(), EncodeError> {
203 varint::encode_uvarint(self.len() as u64, writer)?;
204 writer.write_all(self.as_bytes())
205 }
206}
207
208#[cfg(feature = "alloc")]
209impl Decode for alloc::string::String {
210 #[inline]
211 fn decode<'a, R: BufferReader<'a>>(reader: &mut R) -> Result<Self, DecodeError> {
212 let len = varint::decode_uvarint(reader)? as usize;
213 if len > 16 * 1024 * 1024 {
214 return Err(DecodeError::AllocationLimitExceeded);
215 }
216 reader.check_alloc(len)?;
217 let bytes = reader.remaining();
218 if bytes.len() < len {
219 return Err(DecodeError::UnexpectedEOF);
220 }
221 let s = core::str::from_utf8(&bytes[..len]).map_err(|_| DecodeError::InvalidUtf8)?;
222 let owned = alloc::string::String::from(s);
223 reader.advance(len)?;
224 Ok(owned)
225 }
226}
227
228#[cfg(feature = "alloc")]
229impl<'a> Validate<'a> for alloc::string::String {
230 #[inline]
231 fn validate<R: BufferReader<'a>>(reader: &mut R) -> Result<(), ValidateError> {
232 let len =
233 varint::decode_uvarint(reader).map_err(|_| ValidateError::InvalidVarint)? as usize;
234 if len > 16 * 1024 * 1024 {
235 return Err(ValidateError::AllocationLimitExceeded);
236 }
237 let bytes = reader.remaining();
238 if bytes.len() < len {
239 return Err(ValidateError::UnexpectedEOF);
240 }
241 core::str::from_utf8(&bytes[..len]).map_err(|_| ValidateError::InvalidUtf8)?;
242 reader
243 .advance(len)
244 .map_err(|_| ValidateError::UnexpectedEOF)?;
245 Ok(())
246 }
247}
248
249impl Encode for &str {
250 #[inline]
251 fn encode<W: BufferWriter>(&self, writer: &mut W) -> Result<(), EncodeError> {
252 varint::encode_uvarint(self.len() as u64, writer)?;
253 writer.write_all(self.as_bytes())
254 }
255}
256
257impl<T: FixedSize + Encode> Encode for &[T] {
258 #[inline]
259 fn encode<W: BufferWriter>(&self, writer: &mut W) -> Result<(), EncodeError> {
260 let count = self.len() as u64;
261 count.encode(writer)?;
262 for item in *self {
263 item.encode(writer)?;
264 }
265 Ok(())
266 }
267}
268
269impl<'a> View<'a> for &'a str {
270 #[inline]
271 fn view<R: BufferReader<'a>>(reader: &mut R) -> Result<Self, DecodeError> {
272 let len = varint::decode_uvarint(reader)? as usize;
273 let bytes = reader.remaining();
274 if bytes.len() < len {
275 return Err(DecodeError::UnexpectedEOF);
276 }
277 let s = core::str::from_utf8(&bytes[..len]).map_err(|_| DecodeError::InvalidUtf8)?;
278 reader.advance(len)?;
279 Ok(s)
280 }
281}
282
283#[allow(unsafe_code)]
284impl<'a, T: FixedSize + Decode> View<'a> for &'a [T] {
285 #[inline]
286 fn view<R: BufferReader<'a>>(reader: &mut R) -> Result<Self, DecodeError> {
287 let len = u64::decode(reader)? as usize;
288 if len > 1024 * 1024 {
289 return Err(DecodeError::AllocationLimitExceeded);
290 }
291 reader.check_alloc(len * T::SIZE)?;
292
293 let bytes = reader.remaining();
294 let byte_len = len
295 .checked_mul(T::SIZE)
296 .ok_or(DecodeError::AllocationLimitExceeded)?;
297 if bytes.len() < byte_len {
298 return Err(DecodeError::UnexpectedEOF);
299 }
300
301 if (bytes.as_ptr() as usize) % core::mem::align_of::<T>() != 0 {
303 return Err(DecodeError::UnexpectedEOF);
304 }
305
306 let mut temp_reader = crate::buffer::SliceReader::new(&bytes[..byte_len]);
308 for _ in 0..len {
309 T::decode(&mut temp_reader)?;
310 }
311
312 reader.advance(byte_len)?;
313
314 unsafe { Ok(core::slice::from_raw_parts(bytes.as_ptr() as *const T, len)) }
320 }
321}
322
323#[cfg(feature = "alloc")]
324impl<T: Decode> Decode for alloc::vec::Vec<T> {
325 #[inline]
326 fn decode<'a, R: BufferReader<'a>>(reader: &mut R) -> Result<Self, DecodeError> {
327 let len = varint::decode_uvarint(reader)? as usize;
328 if len > 1024 * 1024 {
329 return Err(DecodeError::AllocationLimitExceeded);
330 }
331 reader.check_alloc(len)?;
332 let mut vec = alloc::vec::Vec::with_capacity(len);
333 for _ in 0..len {
334 vec.push(T::decode(reader)?);
335 }
336 Ok(vec)
337 }
338}
339
340#[cfg(feature = "alloc")]
341#[inline]
342pub fn decode_vec_u8<'a, R: BufferReader<'a>>(
343 reader: &mut R,
344) -> Result<alloc::vec::Vec<u8>, DecodeError> {
345 let len = varint::decode_uvarint(reader)? as usize;
346 if len > 1024 * 1024 {
347 return Err(DecodeError::AllocationLimitExceeded);
348 }
349 reader.check_alloc(len)?;
350
351 let bytes = reader.remaining();
352 if bytes.len() < len {
353 return Err(DecodeError::UnexpectedEOF);
354 }
355
356 let mut vec = alloc::vec::Vec::with_capacity(len);
357 vec.extend_from_slice(&bytes[..len]);
358 reader.advance(len)?;
359 Ok(vec)
360}
361
362#[cfg(feature = "alloc")]
363impl<'a, T: Validate<'a>> Validate<'a> for alloc::vec::Vec<T> {
364 #[inline]
365 fn validate<R: BufferReader<'a>>(reader: &mut R) -> Result<(), ValidateError> {
366 let len =
367 varint::decode_uvarint(reader).map_err(|_| ValidateError::InvalidVarint)? as usize;
368 if len > 1024 * 1024 {
369 return Err(ValidateError::AllocationLimitExceeded);
370 }
371 for _ in 0..len {
372 T::validate(reader)?;
373 }
374 Ok(())
375 }
376}
377
378#[cfg(feature = "alloc")]
379impl<T: Encode> Encode for alloc::vec::Vec<T> {
380 #[inline]
381 fn encode<W: BufferWriter>(&self, writer: &mut W) -> Result<(), EncodeError> {
382 varint::encode_uvarint(self.len() as u64, writer)?;
383 for item in self {
384 item.encode(writer)?;
385 }
386 Ok(())
387 }
388}
389
390#[cfg(feature = "alloc")]
391impl<T: Encode> Encode for alloc::boxed::Box<T> {
392 #[inline]
393 fn encode<W: BufferWriter>(&self, writer: &mut W) -> Result<(), EncodeError> {
394 (**self).encode(writer)
395 }
396}
397
398#[cfg(feature = "alloc")]
399impl<T: Decode> Decode for alloc::boxed::Box<T> {
400 #[inline]
401 fn decode<'a, R: BufferReader<'a>>(reader: &mut R) -> Result<Self, DecodeError> {
402 Ok(alloc::boxed::Box::new(T::decode(reader)?))
403 }
404}
405
406#[cfg(feature = "alloc")]
407impl<'a> View<'a> for alloc::borrow::Cow<'a, str> {
408 #[inline]
409 fn view<R: BufferReader<'a>>(reader: &mut R) -> Result<Self, DecodeError> {
410 let len = varint::decode_uvarint(reader)? as usize;
411 let bytes = reader.remaining();
412 if bytes.len() < len {
413 return Err(DecodeError::UnexpectedEOF);
414 }
415 match core::str::from_utf8(&bytes[..len]) {
416 Ok(s) => {
417 reader.advance(len)?;
418 Ok(alloc::borrow::Cow::Borrowed(s))
419 }
420 Err(_) => Err(DecodeError::InvalidUtf8),
421 }
422 }
423}
424
425#[cfg(feature = "alloc")]
426impl<'a> View<'a> for alloc::borrow::Cow<'a, [u8]> {
427 #[inline]
428 fn view<R: BufferReader<'a>>(reader: &mut R) -> Result<Self, DecodeError> {
429 let len = varint::decode_uvarint(reader)? as usize;
430 let bytes = reader.remaining();
431 if bytes.len() < len {
432 return Err(DecodeError::UnexpectedEOF);
433 }
434 let slice = &bytes[..len];
435 reader.advance(len)?;
436 Ok(alloc::borrow::Cow::Borrowed(slice))
437 }
438}
439
440#[cfg(feature = "alloc")]
441impl<'a> Decode for alloc::borrow::Cow<'a, str> {
442 #[inline]
443 fn decode<'__b, R: BufferReader<'__b>>(reader: &mut R) -> Result<Self, DecodeError> {
444 let s = alloc::string::String::decode(reader)?;
445 Ok(alloc::borrow::Cow::Owned(s))
446 }
447}
448
449#[cfg(feature = "alloc")]
450impl<'a> Decode for alloc::borrow::Cow<'a, [u8]> {
451 #[inline]
452 fn decode<'__b, R: BufferReader<'__b>>(reader: &mut R) -> Result<Self, DecodeError> {
453 let v = alloc::vec::Vec::<u8>::decode(reader)?;
454 Ok(alloc::borrow::Cow::Owned(v))
455 }
456}
457
458#[cfg(feature = "alloc")]
459impl<'a> Encode for alloc::borrow::Cow<'a, [u8]> {
460 #[inline]
461 fn encode<W: BufferWriter>(&self, writer: &mut W) -> Result<(), EncodeError> {
462 varint::encode_uvarint(self.len() as u64, writer)?;
463 writer.write_all(self.as_ref())
464 }
465}
466
467#[cfg(feature = "alloc")]
468impl Encode for alloc::borrow::Cow<'_, str> {
469 #[inline]
470 fn encode<W: BufferWriter>(&self, writer: &mut W) -> Result<(), EncodeError> {
471 varint::encode_uvarint(self.len() as u64, writer)?;
472 writer.write_all(self.as_bytes())
473 }
474}
475
476#[cfg(feature = "axhash")]
477impl<K: Encode, V: Encode> Encode for axhash_map::HashMap<K, V> {
478 #[inline]
479 fn encode<W: BufferWriter>(&self, writer: &mut W) -> Result<(), EncodeError> {
480 varint::encode_uvarint(self.len() as u64, writer)?;
481 for (k, v) in self.iter() {
482 k.encode(writer)?;
483 v.encode(writer)?;
484 }
485 Ok(())
486 }
487}
488
489#[cfg(feature = "axhash")]
490impl<K: Decode + Eq + core::hash::Hash, V: Decode> Decode for axhash_map::HashMap<K, V> {
491 #[inline]
492 fn decode<'__b, R: BufferReader<'__b>>(reader: &mut R) -> Result<Self, DecodeError> {
493 let len = varint::decode_uvarint(reader)? as usize;
494 if len > 1024 * 1024 {
495 return Err(DecodeError::AllocationLimitExceeded);
496 }
497 let mut map = axhash_map::HashMap::default();
498 map.reserve(len);
499 for _ in 0..len {
500 let k = K::decode(reader)?;
501 let v = V::decode(reader)?;
502 map.insert(k, v);
503 }
504 Ok(map)
505 }
506}
507
508#[cfg(feature = "axhash")]
509impl<'a, K: Validate<'a>, V: Validate<'a>> Validate<'a> for axhash_map::HashMap<K, V> {
510 #[inline]
511 fn validate<R: BufferReader<'a>>(reader: &mut R) -> Result<(), ValidateError> {
512 let len =
513 varint::decode_uvarint(reader).map_err(|_| ValidateError::InvalidVarint)? as usize;
514 if len > 1024 * 1024 {
515 return Err(ValidateError::AllocationLimitExceeded);
516 }
517 for _ in 0..len {
518 K::validate(reader)?;
519 V::validate(reader)?;
520 }
521 Ok(())
522 }
523}
524
525#[cfg(feature = "axhash")]
526impl<T: Encode> Encode for axhash_map::HashSet<T> {
527 #[inline]
528 fn encode<W: BufferWriter>(&self, writer: &mut W) -> Result<(), EncodeError> {
529 varint::encode_uvarint(self.len() as u64, writer)?;
530 for item in self.iter() {
531 item.encode(writer)?;
532 }
533 Ok(())
534 }
535}
536
537#[cfg(feature = "axhash")]
538impl<T: Decode + Eq + core::hash::Hash> Decode for axhash_map::HashSet<T> {
539 #[inline]
540 fn decode<'__b, R: BufferReader<'__b>>(reader: &mut R) -> Result<Self, DecodeError> {
541 let len = varint::decode_uvarint(reader)? as usize;
542 if len > 1024 * 1024 {
543 return Err(DecodeError::AllocationLimitExceeded);
544 }
545 let mut set = axhash_map::HashSet::default();
546 set.reserve(len);
547 for _ in 0..len {
548 set.insert(T::decode(reader)?);
549 }
550 Ok(set)
551 }
552}
553
554#[cfg(feature = "axhash")]
555impl<'a, T: Validate<'a>> Validate<'a> for axhash_map::HashSet<T> {
556 #[inline]
557 fn validate<R: BufferReader<'a>>(reader: &mut R) -> Result<(), ValidateError> {
558 let len =
559 varint::decode_uvarint(reader).map_err(|_| ValidateError::InvalidVarint)? as usize;
560 if len > 1024 * 1024 {
561 return Err(ValidateError::AllocationLimitExceeded);
562 }
563 for _ in 0..len {
564 T::validate(reader)?;
565 }
566 Ok(())
567 }
568}
569
570#[cfg(test)]
571mod tests {
572 use super::*;
573 use crate::Validate;
574
575 #[test]
576 fn roundtrip_u16() {
577 let mut w = buffer::VecWriter::new();
578 let val: u16 = 0x1234;
579 val.encode(&mut w).unwrap();
580 let mut r = buffer::SliceReader::new(w.as_slice());
581 let decoded = u16::decode(&mut r).unwrap();
582 assert_eq!(val, decoded);
583 }
584
585 #[test]
586 fn roundtrip_option_some() {
587 let mut w = buffer::VecWriter::new();
588 let val: Option<u16> = Some(0x1234);
589 val.encode(&mut w).unwrap();
590 let mut r = buffer::SliceReader::new(w.as_slice());
591 let decoded = Option::<u16>::decode(&mut r).unwrap();
592 assert_eq!(val, decoded);
593 }
594
595 #[test]
596 fn roundtrip_option_none() {
597 let mut w = buffer::VecWriter::new();
598 let val: Option<u16> = None;
599 val.encode(&mut w).unwrap();
600 let mut r = buffer::SliceReader::new(w.as_slice());
601 let decoded = Option::<u16>::decode(&mut r).unwrap();
602 assert_eq!(val, decoded);
603 }
604
605 #[test]
606 fn validate_u16_ok() {
607 let mut w = buffer::VecWriter::new();
608 let val: u16 = 0x1234;
609 val.encode(&mut w).unwrap();
610 let mut r = buffer::SliceReader::new(w.as_slice());
611 u16::validate(&mut r).unwrap();
612 }
613
614 #[test]
615 fn validate_u16_eof_fails() {
616 let buf = [0x12u8]; let mut r = buffer::SliceReader::new(&buf);
618 assert!(u16::validate(&mut r).is_err());
619 }
620
621 #[test]
622 fn validate_bool_ok() {
623 let mut w = buffer::VecWriter::new();
624 true.encode(&mut w).unwrap();
625 let mut r = buffer::SliceReader::new(w.as_slice());
626 bool::validate(&mut r).unwrap();
627 }
628
629 #[test]
630 fn validate_bool_invalid_fails() {
631 let buf = [0x02u8];
632 let mut r = buffer::SliceReader::new(&buf);
633 assert!(bool::validate(&mut r).is_err());
634 }
635
636 #[test]
637 #[cfg(feature = "axhash")]
638 fn hashmap_roundtrip() {
639 use axhash_map::HashMap;
640 let mut map: HashMap<String, u32> = HashMap::default();
641 map.insert("alice".into(), 42u32);
642 map.insert("bob".into(), 17u32);
643
644 let mut w = buffer::VecWriter::new();
645 map.encode(&mut w).unwrap();
646
647 let mut r = buffer::SliceReader::new(w.as_slice());
648 let decoded = HashMap::<String, u32>::decode(&mut r).unwrap();
649
650 assert_eq!(decoded.len(), 2);
651 assert_eq!(decoded["alice"], 42);
652 assert_eq!(decoded["bob"], 17);
653 }
654
655 #[test]
656 #[cfg(feature = "axhash")]
657 fn hashset_roundtrip() {
658 use axhash_map::HashSet;
659 let mut set: HashSet<u32> = HashSet::default();
660 set.insert(1u32);
661 set.insert(2u32);
662 set.insert(3u32);
663
664 let mut w = buffer::VecWriter::new();
665 set.encode(&mut w).unwrap();
666
667 let mut r = buffer::SliceReader::new(w.as_slice());
668 let decoded = HashSet::<u32>::decode(&mut r).unwrap();
669
670 assert_eq!(decoded.len(), 3);
671 assert!(decoded.contains(&1));
672 assert!(decoded.contains(&2));
673 assert!(decoded.contains(&3));
674 }
675
676 #[test]
677 #[cfg(feature = "axhash")]
678 fn hashmap_validate_ok() {
679 use axhash_map::HashMap;
680 let mut map: HashMap<String, u32> = HashMap::default();
681 map.insert("alice".into(), 42u32);
682
683 let mut w = buffer::VecWriter::new();
684 map.encode(&mut w).unwrap();
685
686 let mut r = buffer::SliceReader::new(w.as_slice());
687 HashMap::<String, u32>::validate(&mut r).unwrap();
688 }
689
690 #[test]
691 #[cfg(feature = "axhash")]
692 fn hashset_validate_ok() {
693 use axhash_map::HashSet;
694 let mut set: HashSet<u32> = HashSet::default();
695 set.insert(1u32);
696
697 let mut w = buffer::VecWriter::new();
698 set.encode(&mut w).unwrap();
699
700 let mut r = buffer::SliceReader::new(w.as_slice());
701 HashSet::<u32>::validate(&mut r).unwrap();
702 }
703
704 #[test]
705 #[cfg(feature = "crc32")]
706 fn checksum_roundtrip_u16() {
707 let val: u16 = 0x1234;
708 let mut w = buffer::VecWriter::new();
709 checksum::encode_with_checksum(&val, &mut w).unwrap();
710
711 let mut r = buffer::SliceReader::new(w.as_slice());
712 let decoded = checksum::decode_with_checksum::<u16, _>(&mut r).unwrap();
713 assert_eq!(val, decoded);
714 }
715
716 #[test]
717 #[cfg(feature = "crc32")]
718 fn checksum_corrupted_fails() {
719 let val: u16 = 0x1234;
720 let mut w = buffer::VecWriter::new();
721 checksum::encode_with_checksum(&val, &mut w).unwrap();
722
723 let mut bytes = w.into_vec();
724 bytes[0] ^= 0xFF; let mut r = buffer::SliceReader::new(&bytes);
727 assert!(checksum::decode_with_checksum::<u16, _>(&mut r).is_err());
728 }
729
730 #[test]
731 #[cfg(feature = "crc32")]
732 fn checksum_validate_ok() {
733 let val: u16 = 0x1234;
734 let mut w = buffer::VecWriter::new();
735 checksum::encode_with_checksum(&val, &mut w).unwrap();
736
737 let mut r = buffer::SliceReader::new(w.as_slice());
738 checksum::validate_with_checksum::<u16, _>(&mut r).unwrap();
739 }
740
741 #[test]
742 fn versioned_roundtrip() {
743 let val: u16 = 0x1234;
744 let mut w = buffer::VecWriter::new();
745 version::encode_versioned(1, &val, &mut w).unwrap();
746
747 let mut r = buffer::SliceReader::new(w.as_slice());
748 let (ver, decoded) = version::decode_versioned::<u16, _>(0, 2, &mut r).unwrap();
749 assert_eq!(ver, 1);
750 assert_eq!(decoded, val);
751 }
752
753 #[test]
754 fn versioned_out_of_range_fails() {
755 let val: u16 = 0x1234;
756 let mut w = buffer::VecWriter::new();
757 version::encode_versioned(5, &val, &mut w).unwrap();
758
759 let mut r = buffer::SliceReader::new(w.as_slice());
760 assert!(version::decode_versioned::<u16, _>(0, 2, &mut r).is_err());
761 }
762
763 #[test]
764 fn zero_copy_slice_u32() {
765 let vals = [0x01020304u32, 0x05060708, 0x090a0b0c];
766 let mut w = buffer::VecWriter::new();
767 (vals.len() as u64).encode(&mut w).unwrap();
768 for v in &vals {
769 v.encode(&mut w).unwrap();
770 }
771
772 let mut r = buffer::SliceReader::new(w.as_slice());
773 let slice: &[u32] = View::view(&mut r).unwrap();
774 assert_eq!(slice, &vals);
775 }
776
777 #[test]
778 fn zero_copy_slice_u16() {
779 let vals = [0x1234u16, 0x5678];
780 let mut w = buffer::VecWriter::new();
781 (vals.len() as u64).encode(&mut w).unwrap();
782 for v in &vals {
783 v.encode(&mut w).unwrap();
784 }
785
786 let mut r = buffer::SliceReader::new(w.as_slice());
787 let slice: &[u16] = View::view(&mut r).unwrap();
788 assert_eq!(slice, &vals);
789 }
790
791 #[test]
792 #[cfg(feature = "bytes")]
793 fn bytes_decode_u16_roundtrip() {
794 let val: u16 = 0x1234;
795 let mut w = buffer::VecWriter::new();
796 val.encode(&mut w).unwrap();
797
798 let mut buf = bytes::Bytes::copy_from_slice(w.as_slice());
799 let decoded = bytes_impl::decode_from_bytes::<u16>(&mut buf).unwrap();
800 assert_eq!(val, decoded);
801 }
802
803 #[test]
804 fn decode_vec_u8_bulk_copy() {
805 let data = alloc::vec![1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10];
806 let mut w = buffer::VecWriter::new();
807 data.encode(&mut w).unwrap();
808
809 let mut r = buffer::SliceReader::new(w.as_slice());
810 let decoded = decode_vec_u8(&mut r).unwrap();
811 assert_eq!(decoded, data);
812 }
813
814 #[test]
815 #[cfg(feature = "bytes")]
816 fn bytes_decode_multiple_values() {
817 let mut w = buffer::VecWriter::new();
818 0x0102u16.encode(&mut w).unwrap();
819 0x0304u16.encode(&mut w).unwrap();
820 0x0506u16.encode(&mut w).unwrap();
821
822 let mut buf = bytes::Bytes::copy_from_slice(w.as_slice());
823 assert_eq!(
824 bytes_impl::decode_from_bytes::<u16>(&mut buf).unwrap(),
825 0x0102
826 );
827 assert_eq!(
828 bytes_impl::decode_from_bytes::<u16>(&mut buf).unwrap(),
829 0x0304
830 );
831 assert_eq!(
832 bytes_impl::decode_from_bytes::<u16>(&mut buf).unwrap(),
833 0x0506
834 );
835 }
836}