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