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