1mod impl_core;
4mod impl_tuples;
5mod impls;
6
7pub use bincode::de::{BorrowDecoder, Decoder};
8pub use bincode::error::DecodeError;
9pub use bincode::{BorrowDecode, Decode};
10use platform_version::version::PlatformVersion;
11
12pub trait DefaultDecode: bincode::Decode<crate::BincodeContext> {
14 fn decode<D: Decoder<Context = crate::BincodeContext>>(
15 decoder: &mut D,
16 ) -> Result<Self, DecodeError>
17 where
18 Self: Sized,
19 {
20 <Self as bincode::Decode<crate::BincodeContext>>::decode(decoder)
21 }
22}
23impl<T> DefaultDecode for T where T: bincode::Decode<crate::BincodeContext> {}
24
25pub trait DefaultBorrowDecode<'de>: bincode::BorrowDecode<'de, crate::BincodeContext> {
27 fn borrow_decode<D: BorrowDecoder<'de, Context = crate::BincodeContext>>(
28 decoder: &mut D,
29 ) -> Result<Self, DecodeError>
30 where
31 Self: Sized,
32 {
33 <Self as bincode::BorrowDecode<'de, crate::BincodeContext>>::borrow_decode(decoder)
34 }
35}
36impl<'de, T> DefaultBorrowDecode<'de> for T where
37 T: bincode::BorrowDecode<'de, crate::BincodeContext>
38{
39}
40
41pub trait PlatformVersionedDecode: Sized {
108 fn platform_versioned_decode<D: Decoder<Context = crate::BincodeContext>>(
110 decoder: &mut D,
111 platform_version: &PlatformVersion,
112 ) -> Result<Self, DecodeError>;
113}
114
115pub trait PlatformVersionedBorrowDecode<'de>: Sized {
121 fn platform_versioned_borrow_decode<D: BorrowDecoder<'de, Context = crate::BincodeContext>>(
123 decoder: &mut D,
124 platform_version: &PlatformVersion,
125 ) -> Result<Self, DecodeError>;
126}
127
128#[macro_export]
130macro_rules! impl_platform_versioned_borrow_decode {
131 ($ty:ty) => {
132 impl<'de> $crate::PlatformVersionedBorrowDecode<'de> for $ty {
133 fn platform_versioned_borrow_decode<
134 D: bincode::de::BorrowDecoder<'de, Context = $crate::BincodeContext>,
135 >(
136 decoder: &mut D,
137 platform_version: &PlatformVersion,
138 ) -> core::result::Result<Self, bincode::error::DecodeError> {
139 <$ty as $crate::PlatformVersionedDecode>::platform_versioned_decode(
143 decoder,
144 platform_version,
145 )
146 }
147 }
148 };
149}
150
151#[inline]
153pub(crate) fn decode_option_variant<D: Decoder<Context = crate::BincodeContext>>(
154 decoder: &mut D,
155 type_name: &'static str,
156) -> Result<Option<()>, DecodeError> {
157 let is_some = <u8 as DefaultDecode>::decode(decoder)?;
158 match is_some {
159 0 => Ok(None),
160 1 => Ok(Some(())),
161 x => Err(DecodeError::UnexpectedVariant {
162 found: x as u32,
163 allowed: &bincode::error::AllowedEnumVariants::Range { max: 1, min: 0 },
164 type_name,
165 }),
166 }
167}
168
169const MAX_COLLECTION_LEN: u64 = 1024 * 1024;
185
186#[inline]
188pub(crate) fn decode_slice_len<D: Decoder<Context = crate::BincodeContext>>(
189 decoder: &mut D,
190) -> Result<usize, DecodeError> {
191 let v = <u64 as DefaultDecode>::decode(decoder)?;
192
193 if v > MAX_COLLECTION_LEN {
194 return Err(DecodeError::LimitExceeded);
195 }
196
197 v.try_into().map_err(|_| DecodeError::OutsideUsizeRange(v))
198}
199
200#[cfg(test)]
201mod tests {
202 use super::*;
203 use bincode::config;
204 use platform_version::version::PlatformVersion;
205
206 fn cfg() -> impl bincode::config::Config {
207 config::standard().with_big_endian().with_no_limit()
208 }
209
210 fn pv() -> &'static PlatformVersion {
211 PlatformVersion::first()
212 }
213
214 fn try_decode_len(value: u64) -> Result<usize, DecodeError> {
217 let config = config::standard().with_big_endian().with_no_limit();
218 let encoded = bincode::encode_to_vec(value, config).unwrap();
219 let reader = bincode::de::read::SliceReader::new(&encoded);
220 let mut decoder = bincode::de::DecoderImpl::new(reader, config, ());
221 decode_slice_len(&mut decoder)
222 }
223
224 #[test]
225 fn decode_slice_len_accepts_small_values() {
226 assert_eq!(try_decode_len(0).unwrap(), 0);
227 assert_eq!(try_decode_len(1).unwrap(), 1);
228 assert_eq!(try_decode_len(1024).unwrap(), 1024);
229 }
230
231 #[test]
232 fn decode_slice_len_accepts_at_limit() {
233 let limit = MAX_COLLECTION_LEN;
234 assert_eq!(try_decode_len(limit).unwrap(), limit as usize);
235 }
236
237 #[test]
238 fn decode_slice_len_rejects_above_limit() {
239 let above = MAX_COLLECTION_LEN + 1;
240 match try_decode_len(above) {
241 Err(DecodeError::LimitExceeded) => {} other => panic!("expected LimitExceeded, got {:?}", other),
243 }
244 }
245
246 #[test]
247 fn decode_slice_len_rejects_huge_value() {
248 match try_decode_len(u64::MAX) {
250 Err(DecodeError::LimitExceeded) => {} other => panic!("expected LimitExceeded, got {:?}", other),
252 }
253 }
254
255 fn try_decode_option_variant(byte: u8) -> Result<Option<()>, DecodeError> {
260 let data = bincode::encode_to_vec(byte, cfg()).unwrap();
261 let reader = bincode::de::read::SliceReader::new(&data);
262 let mut decoder = bincode::de::DecoderImpl::new(reader, cfg(), ());
263 decode_option_variant(&mut decoder, "test::Option")
264 }
265
266 #[test]
267 fn decode_option_variant_none() {
268 assert_eq!(try_decode_option_variant(0).unwrap(), None);
269 }
270
271 #[test]
272 fn decode_option_variant_some() {
273 assert_eq!(try_decode_option_variant(1).unwrap(), Some(()));
274 }
275
276 #[test]
277 fn decode_option_variant_invalid() {
278 match try_decode_option_variant(2) {
279 Err(DecodeError::UnexpectedVariant { found: 2, .. }) => {}
280 other => panic!("expected UnexpectedVariant, got {:?}", other),
281 }
282 match try_decode_option_variant(255) {
283 Err(DecodeError::UnexpectedVariant { found: 255, .. }) => {}
284 other => panic!("expected UnexpectedVariant, got {:?}", other),
285 }
286 }
287
288 #[test]
293 fn option_some_round_trip() {
294 let value: Option<u32> = Some(42);
295 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
296 let decoded: Option<u32> =
297 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
298 assert_eq!(decoded, Some(42));
299 }
300
301 #[test]
302 fn option_none_round_trip() {
303 let value: Option<u32> = None;
304 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
305 let decoded: Option<u32> =
306 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
307 assert_eq!(decoded, None);
308 }
309
310 #[test]
315 fn result_ok_round_trip() {
316 let value: Result<u32, u8> = Ok(123);
317 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
318 let decoded: Result<u32, u8> =
319 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
320 assert_eq!(decoded, Ok(123));
321 }
322
323 #[test]
324 fn result_err_round_trip() {
325 let value: Result<u32, u8> = Err(99);
326 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
327 let decoded: Result<u32, u8> =
328 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
329 assert_eq!(decoded, Err(99));
330 }
331
332 #[test]
333 fn result_invalid_variant() {
334 let mut data = bincode::encode_to_vec(2u32, cfg()).unwrap();
336 data.extend_from_slice(&[0u8; 8]);
338 let result =
339 crate::platform_versioned_decode_from_slice::<Result<u32, u8>, _>(&data, cfg(), pv());
340 match result {
341 Err(DecodeError::UnexpectedVariant { found: 2, .. }) => {}
342 other => panic!("expected UnexpectedVariant, got {:?}", other),
343 }
344 }
345
346 #[test]
351 fn bound_unbounded_round_trip() {
352 use core::ops::Bound;
353 let value: Bound<u32> = Bound::Unbounded;
354 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
355 let decoded: Bound<u32> =
356 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
357 assert_eq!(decoded, Bound::Unbounded);
358 }
359
360 #[test]
361 fn bound_included_round_trip() {
362 use core::ops::Bound;
363 let value: Bound<u32> = Bound::Included(10);
364 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
365 let decoded: Bound<u32> =
366 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
367 assert_eq!(decoded, Bound::Included(10));
368 }
369
370 #[test]
371 fn bound_excluded_round_trip() {
372 use core::ops::Bound;
373 let value: Bound<u32> = Bound::Excluded(20);
374 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
375 let decoded: Bound<u32> =
376 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
377 assert_eq!(decoded, Bound::Excluded(20));
378 }
379
380 #[test]
381 fn bound_invalid_variant() {
382 use core::ops::Bound;
383 let mut data = bincode::encode_to_vec(3u32, cfg()).unwrap();
385 data.extend_from_slice(&[0u8; 8]);
386 let result =
387 crate::platform_versioned_decode_from_slice::<Bound<u32>, _>(&data, cfg(), pv());
388 match result {
389 Err(DecodeError::UnexpectedVariant { found: 3, .. }) => {}
390 other => panic!("expected UnexpectedVariant, got {:?}", other),
391 }
392 }
393
394 #[test]
399 fn array_u8_decode_round_trip() {
400 let value: [u8; 4] = [0xDE, 0xAD, 0xBE, 0xEF];
402 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
403 let decoded: [u8; 4] =
404 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
405 assert_eq!(decoded, value);
406 }
407
408 #[test]
409 fn array_non_u8_decode_round_trip() {
410 let value: [u32; 3] = [100, 200, 300];
412 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
413 let decoded: [u32; 3] =
414 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
415 assert_eq!(decoded, value);
416 }
417
418 #[test]
419 fn array_borrow_decode_u8_path() {
420 let value: [u8; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
421 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
422 let decoded: [u8; 8] =
423 crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
424 assert_eq!(decoded, value);
425 }
426
427 #[test]
428 fn array_borrow_decode_non_u8_path() {
429 let value: [i16; 4] = [-1, 0, 1, 32767];
430 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
431 let decoded: [i16; 4] =
432 crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
433 assert_eq!(decoded, value);
434 }
435
436 #[test]
441 fn cell_round_trip() {
442 use core::cell::Cell;
443 let value = Cell::new(42u32);
444 let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
445 let decoded: Cell<u32> =
446 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
447 assert_eq!(decoded.get(), 42);
448 }
449
450 #[test]
451 fn refcell_round_trip() {
452 use core::cell::RefCell;
453 let value = RefCell::new(99u16);
454 let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
455 let decoded: RefCell<u16> =
456 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
457 assert_eq!(*decoded.borrow(), 99);
458 }
459
460 #[test]
465 fn range_round_trip() {
466 let value: core::ops::Range<u32> = 10..20;
467 let encoded = crate::platform_encode_to_vec(value.clone(), cfg(), pv()).unwrap();
468 let decoded: core::ops::Range<u32> =
469 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
470 assert_eq!(decoded, value);
471 }
472
473 #[test]
474 fn range_inclusive_round_trip() {
475 let value: core::ops::RangeInclusive<i32> = -5..=5;
476 let encoded = crate::platform_encode_to_vec(value.clone(), cfg(), pv()).unwrap();
477 let decoded: core::ops::RangeInclusive<i32> =
478 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
479 assert_eq!(decoded, value);
480 }
481
482 #[test]
487 fn unit_round_trip() {
488 let value = ();
489 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
490 let decoded: () =
491 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
492 assert_eq!(decoded, ());
493 }
494
495 #[test]
496 fn phantom_data_round_trip() {
497 use core::marker::PhantomData;
498 let value: PhantomData<u32> = PhantomData;
499 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
500 let decoded: PhantomData<u32> =
501 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
502 assert_eq!(decoded, PhantomData);
503 }
504
505 #[test]
510 fn bool_round_trip() {
511 for value in [true, false] {
512 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
513 let decoded: bool =
514 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
515 assert_eq!(decoded, value);
516 }
517 }
518
519 #[test]
520 fn char_round_trip() {
521 for value in ['a', '\u{1F600}', '\0'] {
522 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
523 let decoded: char =
524 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
525 assert_eq!(decoded, value);
526 }
527 }
528
529 #[test]
530 fn f64_round_trip() {
531 let value: f64 = core::f64::consts::PI;
532 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
533 let decoded: f64 =
534 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
535 assert_eq!(decoded, value);
536 }
537
538 #[test]
539 fn duration_round_trip() {
540 let value = core::time::Duration::new(123, 456_789);
541 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
542 let decoded: core::time::Duration =
543 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
544 assert_eq!(decoded, value);
545 }
546
547 #[test]
548 fn borrow_decode_byte_slice() {
549 let data: &[u8] = b"hello bytes";
551 let encoded = bincode::encode_to_vec(data, cfg()).unwrap();
552 let decoded: &[u8] =
553 crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
554 assert_eq!(decoded, data);
555 }
556
557 #[test]
558 fn borrow_decode_str() {
559 let data = "borrow me";
560 let encoded = crate::platform_encode_to_vec(data, cfg(), pv()).unwrap();
561 let decoded: &str =
562 crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
563 assert_eq!(decoded, data);
564 }
565
566 macro_rules! nonzero_round_trip_test {
571 ($name:ident, $ty:ty, $val:expr) => {
572 #[test]
573 fn $name() {
574 let value: $ty = <$ty>::new($val).unwrap();
575 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
576 let decoded: $ty =
577 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
578 assert_eq!(decoded, value);
579 }
580 };
581 }
582
583 nonzero_round_trip_test!(nonzero_u8_round_trip, core::num::NonZeroU8, 1);
584 nonzero_round_trip_test!(nonzero_u16_round_trip, core::num::NonZeroU16, 100);
585 nonzero_round_trip_test!(nonzero_u32_round_trip, core::num::NonZeroU32, 1000);
586 nonzero_round_trip_test!(nonzero_u64_round_trip, core::num::NonZeroU64, 10000);
587 nonzero_round_trip_test!(nonzero_u128_round_trip, core::num::NonZeroU128, 100000);
588 nonzero_round_trip_test!(nonzero_usize_round_trip, core::num::NonZeroUsize, 42);
589 nonzero_round_trip_test!(nonzero_i8_round_trip, core::num::NonZeroI8, -1);
590 nonzero_round_trip_test!(nonzero_i16_round_trip, core::num::NonZeroI16, -100);
591 nonzero_round_trip_test!(nonzero_i32_round_trip, core::num::NonZeroI32, -1000);
592 nonzero_round_trip_test!(nonzero_i64_round_trip, core::num::NonZeroI64, -10000);
593 nonzero_round_trip_test!(nonzero_i128_round_trip, core::num::NonZeroI128, -100000);
594 nonzero_round_trip_test!(nonzero_isize_round_trip, core::num::NonZeroIsize, -42);
595
596 #[test]
601 fn i8_round_trip() {
602 let value: i8 = -128;
603 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
604 let decoded: i8 =
605 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
606 assert_eq!(decoded, value);
607 }
608
609 #[test]
610 fn i16_round_trip() {
611 let value: i16 = -32768;
612 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
613 let decoded: i16 =
614 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
615 assert_eq!(decoded, value);
616 }
617
618 #[test]
619 fn i32_round_trip() {
620 let value: i32 = -2_000_000;
621 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
622 let decoded: i32 =
623 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
624 assert_eq!(decoded, value);
625 }
626
627 #[test]
628 fn i128_round_trip() {
629 let value: i128 = i128::MIN;
630 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
631 let decoded: i128 =
632 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
633 assert_eq!(decoded, value);
634 }
635
636 #[test]
637 fn isize_round_trip() {
638 let value: isize = -999;
639 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
640 let decoded: isize =
641 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
642 assert_eq!(decoded, value);
643 }
644
645 #[test]
646 fn u128_round_trip() {
647 let value: u128 = u128::MAX;
648 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
649 let decoded: u128 =
650 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
651 assert_eq!(decoded, value);
652 }
653
654 #[test]
655 fn usize_round_trip() {
656 let value: usize = 12345;
657 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
658 let decoded: usize =
659 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
660 assert_eq!(decoded, value);
661 }
662
663 #[test]
664 fn f32_round_trip() {
665 let value: f32 = core::f32::consts::E;
666 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
667 let decoded: f32 =
668 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
669 assert_eq!(decoded, value);
670 }
671
672 #[test]
677 fn cell_borrow_decode_round_trip() {
678 use core::cell::Cell;
679 let value = Cell::new(77u32);
680 let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
681 let decoded: Cell<u32> =
682 crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
683 assert_eq!(decoded.get(), 77);
684 }
685
686 #[test]
687 fn refcell_borrow_decode_round_trip() {
688 use core::cell::RefCell;
689 let value = RefCell::new(88u16);
690 let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
691 let decoded: RefCell<u16> =
692 crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
693 assert_eq!(*decoded.borrow(), 88);
694 }
695
696 #[test]
697 fn option_borrow_decode_some() {
698 let value: Option<u32> = Some(42);
699 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
700 let decoded: Option<u32> =
701 crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
702 assert_eq!(decoded, Some(42));
703 }
704
705 #[test]
706 fn option_borrow_decode_none() {
707 let value: Option<u32> = None;
708 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
709 let decoded: Option<u32> =
710 crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
711 assert_eq!(decoded, None);
712 }
713
714 #[test]
715 fn result_borrow_decode_ok() {
716 let value: Result<u32, u8> = Ok(123);
717 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
718 let decoded: Result<u32, u8> =
719 crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
720 assert_eq!(decoded, Ok(123));
721 }
722
723 #[test]
724 fn result_borrow_decode_err() {
725 let value: Result<u32, u8> = Err(99);
726 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
727 let decoded: Result<u32, u8> =
728 crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
729 assert_eq!(decoded, Err(99));
730 }
731
732 #[test]
733 fn result_borrow_decode_invalid_variant() {
734 let mut data = bincode::encode_to_vec(2u32, cfg()).unwrap();
735 data.extend_from_slice(&[0u8; 8]);
736 let result = crate::platform_versioned_borrow_decode_from_slice::<Result<u32, u8>, _>(
737 &data,
738 cfg(),
739 pv(),
740 );
741 match result {
742 Err(DecodeError::UnexpectedVariant { found: 2, .. }) => {}
743 other => panic!("expected UnexpectedVariant, got {:?}", other),
744 }
745 }
746
747 #[test]
748 fn range_borrow_decode_round_trip() {
749 let value: core::ops::Range<u32> = 5..15;
750 let encoded = crate::platform_encode_to_vec(value.clone(), cfg(), pv()).unwrap();
751 let decoded: core::ops::Range<u32> =
752 crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
753 assert_eq!(decoded, value);
754 }
755
756 #[test]
757 fn range_inclusive_borrow_decode_round_trip() {
758 let value: core::ops::RangeInclusive<i32> = -10..=10;
759 let encoded = crate::platform_encode_to_vec(value.clone(), cfg(), pv()).unwrap();
760 let decoded: core::ops::RangeInclusive<i32> =
761 crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
762 assert_eq!(decoded, value);
763 }
764
765 #[test]
766 fn bound_borrow_decode_all_variants() {
767 use core::ops::Bound;
768 for value in [
769 Bound::Unbounded,
770 Bound::Included(10u32),
771 Bound::Excluded(20u32),
772 ] {
773 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
774 let decoded: Bound<u32> =
775 crate::platform_versioned_borrow_decode_from_slice(&encoded, cfg(), pv()).unwrap();
776 assert_eq!(decoded, value);
777 }
778 }
779
780 #[test]
781 fn bound_borrow_decode_invalid_variant() {
782 use core::ops::Bound;
783 let mut data = bincode::encode_to_vec(3u32, cfg()).unwrap();
784 data.extend_from_slice(&[0u8; 8]);
785 let result =
786 crate::platform_versioned_borrow_decode_from_slice::<Bound<u32>, _>(&data, cfg(), pv());
787 match result {
788 Err(DecodeError::UnexpectedVariant { found: 3, .. }) => {}
789 other => panic!("expected UnexpectedVariant, got {:?}", other),
790 }
791 }
792}