djin_protocol/types/
array.rs1use crate::{hint, util, Parcel, Error, Settings};
2use std::io::prelude::*;
3
4macro_rules! impl_parcel_for_array {
5 ($n:expr) => {
6 impl<T: Parcel> Parcel for [T; $n] where T: Copy {
7 const TYPE_NAME: &'static str = stringify!([T; $n]);
8
9 fn read_field(read: &mut dyn Read,
10 settings: &Settings,
11 _: &mut hint::Hints) -> Result<Self, Error> {
12 use std::mem;
13
14 let elements: Vec<_> = util::read_items($n, read, settings)?.collect();
15 assert_eq!(elements.len(), $n, "fixed size array did not read the expected number of elements");
16
17 let mut uninit_array: [mem::MaybeUninit<T>; $n] = unsafe { mem::MaybeUninit::uninit().assume_init() };
20 for (i, element) in elements.into_iter().enumerate() {
21 uninit_array[i] = mem::MaybeUninit::new(element);
22 }
23
24 let array: &[T; $n] = unsafe { mem::transmute(&uninit_array) };
25 mem::forget(uninit_array);
26 Ok(*array)
27 }
28
29 fn write_field(&self, write: &mut dyn Write,
30 settings: &Settings,
31 _: &mut hint::Hints) -> Result<(), Error> {
32 util::write_items(self.iter(), write, settings)
33 }
34 }
35 }
36}
37
38impl_parcel_for_array!(1);
39impl_parcel_for_array!(2);
40impl_parcel_for_array!(3);
41impl_parcel_for_array!(4);
42impl_parcel_for_array!(5);
43impl_parcel_for_array!(6);
44impl_parcel_for_array!(7);
45impl_parcel_for_array!(8);
46impl_parcel_for_array!(9);
47impl_parcel_for_array!(10);
48impl_parcel_for_array!(11);
49impl_parcel_for_array!(12);
50impl_parcel_for_array!(13);
51impl_parcel_for_array!(14);
52impl_parcel_for_array!(15);
53impl_parcel_for_array!(16);
54impl_parcel_for_array!(17);
55impl_parcel_for_array!(18);
56impl_parcel_for_array!(19);
57impl_parcel_for_array!(20);
58impl_parcel_for_array!(21);
59impl_parcel_for_array!(22);
60impl_parcel_for_array!(23);
61impl_parcel_for_array!(24);
62impl_parcel_for_array!(25);
63impl_parcel_for_array!(26);
64impl_parcel_for_array!(27);
65impl_parcel_for_array!(28);
66impl_parcel_for_array!(29);
67impl_parcel_for_array!(30);
68impl_parcel_for_array!(31);
69impl_parcel_for_array!(32);
70impl_parcel_for_array!(40);
71impl_parcel_for_array!(42);
72impl_parcel_for_array!(48);
73impl_parcel_for_array!(64);
74impl_parcel_for_array!(80);
75impl_parcel_for_array!(120);
76impl_parcel_for_array!(128);
77impl_parcel_for_array!(256);
78impl_parcel_for_array!(500);
79impl_parcel_for_array!(512);
80impl_parcel_for_array!(1000);
81impl_parcel_for_array!(1024);
82impl_parcel_for_array!(4096);
83impl_parcel_for_array!(0xffff);
84
85#[cfg(test)]
86mod test {
87 use crate::{Parcel, Settings};
88 use std::io::Cursor;
89
90 #[test]
91 fn can_read_array() {
92 let mut data = Cursor::new([0u8, 1, 2, 3]);
93 let read_back: [u8; 4] = Parcel::read(&mut data, &Settings::default()).unwrap();
94 assert_eq!(read_back, [0, 1, 2, 3]);
95 }
96
97 #[test]
98 fn can_write_array() {
99 let mut buffer = Cursor::new(Vec::new());
100
101 [5u8, 7, 9, 11].write(&mut buffer, &Settings::default()).unwrap();
102 assert_eq!(buffer.into_inner(), vec![5, 7, 9, 11]);
103 }
104}