1#[macro_export]
26macro_rules! try_vec_to_array {
27 ($vec:ident, $t:ty, $size:expr) => {
28 {
29 if $vec.len() == $size {
30 let mut arr: [std::mem::MaybeUninit<$t>; $size] = unsafe {
31 std::mem::MaybeUninit::uninit().assume_init()
32 };
33 for (i, item) in $vec.into_iter().enumerate() {
34 arr[i] = std::mem::MaybeUninit::new(item);
35 }
36 Ok(unsafe { std::mem::transmute::<_, [$t; $size]>(arr) })
37 } else {
38 Err($crate::VecToArrayError::SizeMismatch { expected: $size, found: $vec.len() })
39 }
40 }
41 }
42}
43
44#[macro_export]
67macro_rules! vec_to_array {
68 ($vec:ident, $t:ty, $size:expr) => {
69 {
70 if $vec.len() != $size {
71 panic!("{}", $crate::VecToArrayError::SizeMismatch {
72 expected: $size,
73 found: $vec.len()
74 });
75 }
76 let mut arr: [std::mem::MaybeUninit<$t>; $size] = unsafe {
77 std::mem::MaybeUninit::uninit().assume_init()
78 };
79 for (i, item) in $vec.into_iter().enumerate() {
80 arr[i] = std::mem::MaybeUninit::new(item);
81 }
82 unsafe { std::mem::transmute::<_, [$t; $size]>(arr) }
83 }
84 }
85}
86
87#[derive(Debug)]
88pub enum VecToArrayError {
89 SizeMismatch { expected: usize, found: usize },
90}
91
92impl std::fmt::Display for VecToArrayError {
93 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
94 match self {
95 VecToArrayError::SizeMismatch { expected, found } => write!(f, "Expected vector of size {}, but found size {}", expected, found),
96 }
98 }
99}
100
101impl std::error::Error for VecToArrayError {}
102
103
104#[cfg(test)]
105mod tests {
106 use crate::VecToArrayError;
107
108 #[test]
109 fn basic_test() {
110 let vec: Vec<i64> = vec![1, 2, 3];
111 let array: [i64; 3] = vec_to_array!(vec, i64, 3);
112 assert_eq!(array, [1, 2, 3]);
113 let vec: Vec<i32> = vec![1, 2, 3];
114 let array: Result<[i32; 3], VecToArrayError> = try_vec_to_array!(vec, i32, 3);
115 assert_eq!(array.unwrap(), [1, 2, 3]);
116
117 let v: Vec<i32> = vec![0; 768];
118 let _arr: [i32; 768] = vec_to_array!(v, i32, 768);
119
120 let v: Vec<i32> = Vec::with_capacity(768);
121 let arr = try_vec_to_array!(v, i32, 768);
122 match arr {
123 Err(VecToArrayError::SizeMismatch { expected: 768, found: 0 }) => (),
124 _ => panic!()
125 }
126 let v: Vec<i32> = vec![0; 768];
127 let arr: Result<[i32; 768], VecToArrayError> = try_vec_to_array!(v, i32, 768);
128 assert!(arr.is_ok());
129 }
130
131 #[test]
132 fn more_complex_test() {
133 let mut x: Vec<Vec<String>> = Vec::new();
134 x.push(vec![String::from("12"), String::from("3")]);
135 let exp = x.clone();
136 let y: [Vec<String>; 1] = vec_to_array!(x, Vec<String>, 1);
137 let act = y.to_vec();
138 assert_eq!(act, exp);
139 }
140
141 #[test]
142 fn test_will_not_panic() {
143 let v: Vec<i32> = vec![0; 768];
144 let _arr: Result<[i32; 769], VecToArrayError> = try_vec_to_array!(v, i32, 769);
145 let v: Vec<i32> = vec![0; 768];
146 let _arr: Result<[i32; 767], VecToArrayError> = try_vec_to_array!(v, i32, 767);
147 }
148
149 #[test]
150 #[should_panic]
151 fn test_panics1() {
152 let v: Vec<i32> = vec![0; 768];
153 let _arr: [i32; 767] = vec_to_array!(v, i32, 767);
154 }
155
156 #[test]
157 #[should_panic]
158 fn test_panics2() {
159 let v: Vec<i32> = vec![0; 768];
160 let _arr: [i32; 769] = vec_to_array!(v, i32, 769);
161 }
162
163 #[test]
164 #[should_panic]
165 fn test_panics3() {
166 let v: Vec<i32> = Vec::with_capacity(768);
167 let _arr: [i32; 768] = vec_to_array!(v, i32, 768);
168 }
169
170 }