1use crate::PlatformVersionEncode;
2
3use bincode::enc::Encoder;
4use bincode::error::EncodeError;
5use bincode::Encode;
6use core::{
7 cell::{Cell, RefCell},
8 marker::PhantomData,
9 num::{
10 NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
11 NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,
12 },
13 ops::{Bound, Range, RangeInclusive},
14 time::Duration,
15};
16use platform_version::version::PlatformVersion;
17
18impl PlatformVersionEncode for () {
19 fn platform_encode<E: Encoder>(
20 &self,
21 _: &mut E,
22 _: &PlatformVersion,
23 ) -> Result<(), EncodeError> {
24 Ok(())
25 }
26}
27
28impl<T> PlatformVersionEncode for PhantomData<T> {
29 fn platform_encode<E: Encoder>(
30 &self,
31 _: &mut E,
32 _: &PlatformVersion,
33 ) -> Result<(), EncodeError> {
34 Ok(())
35 }
36}
37
38impl PlatformVersionEncode for bool {
39 fn platform_encode<E: Encoder>(
40 &self,
41 encoder: &mut E,
42 _: &PlatformVersion,
43 ) -> Result<(), EncodeError> {
44 Encode::encode(self, encoder)
45 }
46}
47
48impl PlatformVersionEncode for u8 {
49 fn platform_encode<E: Encoder>(
50 &self,
51 encoder: &mut E,
52 _: &PlatformVersion,
53 ) -> Result<(), EncodeError> {
54 Encode::encode(self, encoder)
55 }
56}
57
58impl PlatformVersionEncode for NonZeroU8 {
59 fn platform_encode<E: Encoder>(
60 &self,
61 encoder: &mut E,
62 _: &PlatformVersion,
63 ) -> Result<(), EncodeError> {
64 Encode::encode(self, encoder)
65 }
66}
67
68impl PlatformVersionEncode for u16 {
69 fn platform_encode<E: Encoder>(
70 &self,
71 encoder: &mut E,
72 _: &PlatformVersion,
73 ) -> Result<(), EncodeError> {
74 Encode::encode(self, encoder)
75 }
76}
77
78impl PlatformVersionEncode for NonZeroU16 {
79 fn platform_encode<E: Encoder>(
80 &self,
81 encoder: &mut E,
82 _: &PlatformVersion,
83 ) -> Result<(), EncodeError> {
84 Encode::encode(self, encoder)
85 }
86}
87
88impl PlatformVersionEncode for u32 {
89 fn platform_encode<E: Encoder>(
90 &self,
91 encoder: &mut E,
92 _: &PlatformVersion,
93 ) -> Result<(), EncodeError> {
94 Encode::encode(self, encoder)
95 }
96}
97
98impl PlatformVersionEncode for NonZeroU32 {
99 fn platform_encode<E: Encoder>(
100 &self,
101 encoder: &mut E,
102 _: &PlatformVersion,
103 ) -> Result<(), EncodeError> {
104 Encode::encode(self, encoder)
105 }
106}
107
108impl PlatformVersionEncode for u64 {
109 fn platform_encode<E: Encoder>(
110 &self,
111 encoder: &mut E,
112 _: &PlatformVersion,
113 ) -> Result<(), EncodeError> {
114 Encode::encode(self, encoder)
115 }
116}
117
118impl PlatformVersionEncode for NonZeroU64 {
119 fn platform_encode<E: Encoder>(
120 &self,
121 encoder: &mut E,
122 _: &PlatformVersion,
123 ) -> Result<(), EncodeError> {
124 Encode::encode(self, encoder)
125 }
126}
127
128impl PlatformVersionEncode for u128 {
129 fn platform_encode<E: Encoder>(
130 &self,
131 encoder: &mut E,
132 _: &PlatformVersion,
133 ) -> Result<(), EncodeError> {
134 Encode::encode(self, encoder)
135 }
136}
137
138impl PlatformVersionEncode for NonZeroU128 {
139 fn platform_encode<E: Encoder>(
140 &self,
141 encoder: &mut E,
142 _: &PlatformVersion,
143 ) -> Result<(), EncodeError> {
144 Encode::encode(self, encoder)
145 }
146}
147
148impl PlatformVersionEncode for usize {
149 fn platform_encode<E: Encoder>(
150 &self,
151 encoder: &mut E,
152 _: &PlatformVersion,
153 ) -> Result<(), EncodeError> {
154 Encode::encode(self, encoder)
155 }
156}
157
158impl PlatformVersionEncode for NonZeroUsize {
159 fn platform_encode<E: Encoder>(
160 &self,
161 encoder: &mut E,
162 _: &PlatformVersion,
163 ) -> Result<(), EncodeError> {
164 Encode::encode(self, encoder)
165 }
166}
167
168impl PlatformVersionEncode for i8 {
169 fn platform_encode<E: Encoder>(
170 &self,
171 encoder: &mut E,
172 _: &PlatformVersion,
173 ) -> Result<(), EncodeError> {
174 Encode::encode(self, encoder)
175 }
176}
177
178impl PlatformVersionEncode for NonZeroI8 {
179 fn platform_encode<E: Encoder>(
180 &self,
181 encoder: &mut E,
182 _: &PlatformVersion,
183 ) -> Result<(), EncodeError> {
184 Encode::encode(self, encoder)
185 }
186}
187
188impl PlatformVersionEncode for i16 {
189 fn platform_encode<E: Encoder>(
190 &self,
191 encoder: &mut E,
192 _: &PlatformVersion,
193 ) -> Result<(), EncodeError> {
194 Encode::encode(self, encoder)
195 }
196}
197
198impl PlatformVersionEncode for NonZeroI16 {
199 fn platform_encode<E: Encoder>(
200 &self,
201 encoder: &mut E,
202 _: &PlatformVersion,
203 ) -> Result<(), EncodeError> {
204 Encode::encode(self, encoder)
205 }
206}
207
208impl PlatformVersionEncode for i32 {
209 fn platform_encode<E: Encoder>(
210 &self,
211 encoder: &mut E,
212 _: &PlatformVersion,
213 ) -> Result<(), EncodeError> {
214 Encode::encode(self, encoder)
215 }
216}
217
218impl PlatformVersionEncode for NonZeroI32 {
219 fn platform_encode<E: Encoder>(
220 &self,
221 encoder: &mut E,
222 _: &PlatformVersion,
223 ) -> Result<(), EncodeError> {
224 Encode::encode(self, encoder)
225 }
226}
227
228impl PlatformVersionEncode for i64 {
229 fn platform_encode<E: Encoder>(
230 &self,
231 encoder: &mut E,
232 _: &PlatformVersion,
233 ) -> Result<(), EncodeError> {
234 Encode::encode(self, encoder)
235 }
236}
237
238impl PlatformVersionEncode for NonZeroI64 {
239 fn platform_encode<E: Encoder>(
240 &self,
241 encoder: &mut E,
242 _: &PlatformVersion,
243 ) -> Result<(), EncodeError> {
244 Encode::encode(self, encoder)
245 }
246}
247
248impl PlatformVersionEncode for i128 {
249 fn platform_encode<E: Encoder>(
250 &self,
251 encoder: &mut E,
252 _: &PlatformVersion,
253 ) -> Result<(), EncodeError> {
254 Encode::encode(self, encoder)
255 }
256}
257
258impl PlatformVersionEncode for NonZeroI128 {
259 fn platform_encode<E: Encoder>(
260 &self,
261 encoder: &mut E,
262 _: &PlatformVersion,
263 ) -> Result<(), EncodeError> {
264 Encode::encode(self, encoder)
265 }
266}
267
268impl PlatformVersionEncode for isize {
269 fn platform_encode<E: Encoder>(
270 &self,
271 encoder: &mut E,
272 _: &PlatformVersion,
273 ) -> Result<(), EncodeError> {
274 Encode::encode(self, encoder)
275 }
276}
277
278impl PlatformVersionEncode for NonZeroIsize {
279 fn platform_encode<E: Encoder>(
280 &self,
281 encoder: &mut E,
282 _: &PlatformVersion,
283 ) -> Result<(), EncodeError> {
284 Encode::encode(self, encoder)
285 }
286}
287
288impl PlatformVersionEncode for f32 {
289 fn platform_encode<E: Encoder>(
290 &self,
291 encoder: &mut E,
292 _: &PlatformVersion,
293 ) -> Result<(), EncodeError> {
294 Encode::encode(self, encoder)
295 }
296}
297
298impl PlatformVersionEncode for f64 {
299 fn platform_encode<E: Encoder>(
300 &self,
301 encoder: &mut E,
302 _: &PlatformVersion,
303 ) -> Result<(), EncodeError> {
304 Encode::encode(self, encoder)
305 }
306}
307
308impl PlatformVersionEncode for char {
309 fn platform_encode<E: Encoder>(
310 &self,
311 encoder: &mut E,
312 _: &PlatformVersion,
313 ) -> Result<(), EncodeError> {
314 Encode::encode(self, encoder)
315 }
316}
317
318impl<T> PlatformVersionEncode for [T]
329where
330 T: PlatformVersionEncode + Encode + 'static,
331{
332 fn platform_encode<E: Encoder>(
333 &self,
334 encoder: &mut E,
335 platform_version: &PlatformVersion,
336 ) -> Result<(), EncodeError> {
337 super::encode_slice_len(encoder, self.len())?;
338
339 if core::any::TypeId::of::<T>() == core::any::TypeId::of::<u8>() {
340 return Encode::encode(self, encoder);
341 }
342
343 for item in self {
344 item.platform_encode(encoder, platform_version)?;
345 }
346 Ok(())
347 }
348}
349
350impl PlatformVersionEncode for str {
351 fn platform_encode<E: Encoder>(
352 &self,
353 encoder: &mut E,
354 _: &PlatformVersion,
355 ) -> Result<(), EncodeError> {
356 Encode::encode(self, encoder)
357 }
358}
359
360impl<T, const N: usize> PlatformVersionEncode for [T; N]
361where
362 T: PlatformVersionEncode,
363{
364 fn platform_encode<E: Encoder>(
365 &self,
366 encoder: &mut E,
367 platform_version: &PlatformVersion,
368 ) -> Result<(), EncodeError> {
369 for item in self.iter() {
370 item.platform_encode(encoder, platform_version)?;
371 }
372 Ok(())
373 }
374}
375
376impl<T> PlatformVersionEncode for Option<T>
377where
378 T: PlatformVersionEncode,
379{
380 fn platform_encode<E: Encoder>(
381 &self,
382 encoder: &mut E,
383 platform_version: &PlatformVersion,
384 ) -> Result<(), EncodeError> {
385 super::encode_option_variant(encoder, self)?;
386 if let Some(val) = self {
387 val.platform_encode(encoder, platform_version)?;
388 }
389 Ok(())
390 }
391}
392
393impl<T, U> PlatformVersionEncode for Result<T, U>
394where
395 T: PlatformVersionEncode,
396 U: PlatformVersionEncode,
397{
398 fn platform_encode<E: Encoder>(
399 &self,
400 encoder: &mut E,
401 platform_version: &PlatformVersion,
402 ) -> Result<(), EncodeError> {
403 match self {
404 Ok(val) => {
405 0u32.platform_encode(encoder, platform_version)?;
406 val.platform_encode(encoder, platform_version)
407 }
408 Err(err) => {
409 1u32.platform_encode(encoder, platform_version)?;
410 err.platform_encode(encoder, platform_version)
411 }
412 }
413 }
414}
415
416impl<T> PlatformVersionEncode for Cell<T>
417where
418 T: PlatformVersionEncode + Copy,
419{
420 fn platform_encode<E: Encoder>(
421 &self,
422 encoder: &mut E,
423 platform_version: &PlatformVersion,
424 ) -> Result<(), EncodeError> {
425 T::platform_encode(&self.get(), encoder, platform_version)
426 }
427}
428
429impl<T> PlatformVersionEncode for RefCell<T>
430where
431 T: PlatformVersionEncode + ?Sized,
432{
433 fn platform_encode<E: Encoder>(
434 &self,
435 encoder: &mut E,
436 platform_version: &PlatformVersion,
437 ) -> Result<(), EncodeError> {
438 let borrow_guard = self
439 .try_borrow()
440 .map_err(|e| EncodeError::RefCellAlreadyBorrowed {
441 inner: e,
442 type_name: core::any::type_name::<RefCell<T>>(),
443 })?;
444 T::platform_encode(&borrow_guard, encoder, platform_version)
445 }
446}
447
448impl PlatformVersionEncode for Duration {
449 fn platform_encode<E: Encoder>(
450 &self,
451 encoder: &mut E,
452 _: &PlatformVersion,
453 ) -> Result<(), EncodeError> {
454 Encode::encode(self, encoder)
455 }
456}
457
458impl<T> PlatformVersionEncode for Range<T>
459where
460 T: Encode,
461{
462 fn platform_encode<E: Encoder>(
463 &self,
464 encoder: &mut E,
465 _: &PlatformVersion,
466 ) -> Result<(), EncodeError> {
467 Encode::encode(self, encoder)
468 }
469}
470
471impl<T> PlatformVersionEncode for RangeInclusive<T>
472where
473 T: Encode,
474{
475 fn platform_encode<E: Encoder>(
476 &self,
477 encoder: &mut E,
478 _: &PlatformVersion,
479 ) -> Result<(), EncodeError> {
480 Encode::encode(self, encoder)
481 }
482}
483
484impl<T> PlatformVersionEncode for Bound<T>
485where
486 T: Encode,
487{
488 fn platform_encode<E: Encoder>(
489 &self,
490 encoder: &mut E,
491 _: &PlatformVersion,
492 ) -> Result<(), EncodeError> {
493 Encode::encode(self, encoder)
494 }
495}
496
497impl<T> PlatformVersionEncode for &T
498where
499 T: PlatformVersionEncode + ?Sized,
500{
501 fn platform_encode<E: Encoder>(
502 &self,
503 encoder: &mut E,
504 platform_version: &PlatformVersion,
505 ) -> Result<(), EncodeError> {
506 T::platform_encode(self, encoder, platform_version)
507 }
508}
509
510impl<A> PlatformVersionEncode for (A,)
511where
512 A: PlatformVersionEncode,
513{
514 fn platform_encode<_E: Encoder>(
515 &self,
516 encoder: &mut _E,
517 platform_version: &PlatformVersion,
518 ) -> Result<(), EncodeError> {
519 self.0.platform_encode(encoder, platform_version)?;
520 Ok(())
521 }
522}
523
524impl<A, B> PlatformVersionEncode for (A, B)
525where
526 A: PlatformVersionEncode,
527 B: PlatformVersionEncode,
528{
529 fn platform_encode<_E: Encoder>(
530 &self,
531 encoder: &mut _E,
532 platform_version: &PlatformVersion,
533 ) -> Result<(), EncodeError> {
534 self.0.platform_encode(encoder, platform_version)?;
535 self.1.platform_encode(encoder, platform_version)?;
536 Ok(())
537 }
538}
539
540impl<A, B, C> PlatformVersionEncode for (A, B, C)
541where
542 A: PlatformVersionEncode,
543 B: PlatformVersionEncode,
544 C: PlatformVersionEncode,
545{
546 fn platform_encode<_E: Encoder>(
547 &self,
548 encoder: &mut _E,
549 platform_version: &PlatformVersion,
550 ) -> Result<(), EncodeError> {
551 self.0.platform_encode(encoder, platform_version)?;
552 self.1.platform_encode(encoder, platform_version)?;
553 self.2.platform_encode(encoder, platform_version)?;
554 Ok(())
555 }
556}
557
558impl<A, B, C, D> PlatformVersionEncode for (A, B, C, D)
559where
560 A: PlatformVersionEncode,
561 B: PlatformVersionEncode,
562 C: PlatformVersionEncode,
563 D: PlatformVersionEncode,
564{
565 fn platform_encode<_E: Encoder>(
566 &self,
567 encoder: &mut _E,
568 platform_version: &PlatformVersion,
569 ) -> Result<(), EncodeError> {
570 self.0.platform_encode(encoder, platform_version)?;
571 self.1.platform_encode(encoder, platform_version)?;
572 self.2.platform_encode(encoder, platform_version)?;
573 self.3.platform_encode(encoder, platform_version)?;
574 Ok(())
575 }
576}
577
578impl<A, B, C, D, E> PlatformVersionEncode for (A, B, C, D, E)
579where
580 A: PlatformVersionEncode,
581 B: PlatformVersionEncode,
582 C: PlatformVersionEncode,
583 D: PlatformVersionEncode,
584 E: PlatformVersionEncode,
585{
586 fn platform_encode<_E: Encoder>(
587 &self,
588 encoder: &mut _E,
589 platform_version: &PlatformVersion,
590 ) -> Result<(), EncodeError> {
591 self.0.platform_encode(encoder, platform_version)?;
592 self.1.platform_encode(encoder, platform_version)?;
593 self.2.platform_encode(encoder, platform_version)?;
594 self.3.platform_encode(encoder, platform_version)?;
595 self.4.platform_encode(encoder, platform_version)?;
596 Ok(())
597 }
598}
599
600#[cfg(test)]
601mod tests {
602 use super::*;
603 use bincode::config;
604 use platform_version::version::PlatformVersion;
605
606 fn cfg() -> impl bincode::config::Config {
607 config::standard().with_big_endian().with_no_limit()
608 }
609
610 fn pv() -> &'static PlatformVersion {
611 PlatformVersion::first()
612 }
613
614 fn round_trip<T>(value: T) -> T
616 where
617 T: PlatformVersionEncode + crate::PlatformVersionedDecode,
618 {
619 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
620 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap()
621 }
622
623 #[test]
628 fn encode_u8_slice_optimization() {
629 let data: Vec<u8> = vec![1, 2, 3, 4, 5];
631 let encoded = crate::platform_encode_to_vec(&data, cfg(), pv()).unwrap();
632 let decoded: Vec<u8> =
633 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
634 assert_eq!(decoded, data);
635 }
636
637 #[test]
638 fn encode_non_u8_slice() {
639 let data: Vec<u32> = vec![100, 200, 300];
641 let encoded = crate::platform_encode_to_vec(&data, cfg(), pv()).unwrap();
642 let decoded: Vec<u32> =
643 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
644 assert_eq!(decoded, data);
645 }
646
647 #[test]
648 fn encode_empty_slice() {
649 let data: &[u8] = &[];
650 let encoded = crate::platform_encode_to_vec(data, cfg(), pv()).unwrap();
651 let decoded: Vec<u8> =
652 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
653 assert!(decoded.is_empty());
654 }
655
656 #[test]
661 fn encode_array_u32() {
662 let value: [u32; 3] = [10, 20, 30];
663 assert_eq!(round_trip(value), value);
664 }
665
666 #[test]
667 fn encode_array_single_element() {
668 let value: [u64; 1] = [42];
669 assert_eq!(round_trip(value), value);
670 }
671
672 #[test]
677 fn encode_option_some() {
678 let value: Option<i32> = Some(-42);
679 assert_eq!(round_trip(value), value);
680 }
681
682 #[test]
683 fn encode_option_none() {
684 let value: Option<i32> = None;
685 assert_eq!(round_trip(value), value);
686 }
687
688 #[test]
693 fn encode_result_ok() {
694 let value: Result<u32, u8> = Ok(42);
695 assert_eq!(round_trip(value), value);
696 }
697
698 #[test]
699 fn encode_result_err() {
700 let value: Result<u32, u8> = Err(1);
701 assert_eq!(round_trip(value), value);
702 }
703
704 #[test]
709 fn encode_cell() {
710 let value = Cell::new(77u32);
711 let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
712 let decoded: u32 =
713 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
714 assert_eq!(decoded, 77);
715 }
716
717 #[test]
718 fn encode_refcell() {
719 let value = RefCell::new(88u16);
720 let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
721 let decoded: u16 =
722 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
723 assert_eq!(decoded, 88);
724 }
725
726 #[test]
727 fn encode_refcell_already_borrowed_returns_error() {
728 let value = RefCell::new(42u32);
729 let _borrow = value.borrow_mut(); let result = crate::platform_encode_to_vec(&value, cfg(), pv());
731 assert!(result.is_err());
732 }
733
734 #[test]
739 fn encode_str() {
740 let value = "hello platform";
741 let encoded = crate::platform_encode_to_vec(value, cfg(), pv()).unwrap();
742 let decoded: String =
743 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
744 assert_eq!(decoded, value);
745 }
746
747 #[test]
752 fn encode_ref() {
753 let value: u32 = 42;
754 let encoded = crate::platform_encode_to_vec(&value, cfg(), pv()).unwrap();
755 let decoded: u32 =
756 crate::platform_versioned_decode_from_slice(&encoded, cfg(), pv()).unwrap();
757 assert_eq!(decoded, value);
758 }
759
760 #[test]
765 fn encode_tuple_1() {
766 let value: (u32,) = (42,);
767 assert_eq!(round_trip(value), value);
768 }
769
770 #[test]
771 fn encode_tuple_2() {
772 let value: (u32, i8) = (42, -1);
773 assert_eq!(round_trip(value), value);
774 }
775
776 #[test]
777 fn encode_tuple_3() {
778 let value: (u8, u16, u32) = (1, 2, 3);
779 assert_eq!(round_trip(value), value);
780 }
781
782 #[test]
783 fn encode_tuple_4() {
784 let value: (u8, u16, u32, u64) = (1, 2, 3, 4);
785 assert_eq!(round_trip(value), value);
786 }
787
788 #[test]
789 fn encode_tuple_5() {
790 let value: (u8, u16, u32, u64, bool) = (1, 2, 3, 4, true);
791 assert_eq!(round_trip(value), value);
792 }
793
794 #[test]
799 fn encode_duration() {
800 let value = Duration::new(60, 500_000_000);
801 assert_eq!(round_trip(value), value);
802 }
803
804 #[test]
805 fn encode_range() {
806 let value = 10u32..20u32;
807 assert_eq!(round_trip(value.clone()), value);
808 }
809
810 #[test]
811 fn encode_range_inclusive() {
812 let value = 10u32..=20u32;
813 assert_eq!(round_trip(value.clone()), value);
814 }
815
816 #[test]
817 fn encode_bound_unbounded() {
818 use core::ops::Bound;
819 let value: Bound<u32> = Bound::Unbounded;
820 assert_eq!(round_trip(value), value);
821 }
822
823 #[test]
824 fn encode_bound_included() {
825 use core::ops::Bound;
826 let value: Bound<u32> = Bound::Included(5);
827 assert_eq!(round_trip(value), value);
828 }
829
830 #[test]
831 fn encode_bound_excluded() {
832 use core::ops::Bound;
833 let value: Bound<u32> = Bound::Excluded(5);
834 assert_eq!(round_trip(value), value);
835 }
836}