1use super::VertexAttributeValues;
28use bevy_math::{IVec2, IVec3, IVec4, UVec2, UVec3, UVec4, Vec2, Vec3, Vec3A, Vec4};
29use derive_more::derive::{Display, Error};
30
31#[derive(Debug, Clone, Error, Display)]
32#[display("cannot convert VertexAttributeValues::{variant} to {into}")]
33pub struct FromVertexAttributeError {
34 from: VertexAttributeValues,
35 variant: &'static str,
36 into: &'static str,
37}
38
39impl FromVertexAttributeError {
40 fn new<T: 'static>(from: VertexAttributeValues) -> Self {
41 Self {
42 variant: from.enum_variant_name(),
43 into: core::any::type_name::<T>(),
44 from,
45 }
46 }
47}
48
49macro_rules! impl_from {
50 ($from:ty, $variant:tt) => {
51 impl From<Vec<$from>> for VertexAttributeValues {
52 fn from(vec: Vec<$from>) -> Self {
53 VertexAttributeValues::$variant(vec)
54 }
55 }
56 };
57}
58
59macro_rules! impl_from_into {
60 ($from:ty, $variant:tt) => {
61 impl From<Vec<$from>> for VertexAttributeValues {
62 fn from(vec: Vec<$from>) -> Self {
63 let vec: Vec<_> = vec.into_iter().map(|t| t.into()).collect();
64 VertexAttributeValues::$variant(vec)
65 }
66 }
67 };
68}
69
70impl_from!(f32, Float32);
71impl_from!([f32; 2], Float32x2);
72impl_from_into!(Vec2, Float32x2);
73impl_from!([f32; 3], Float32x3);
74impl_from_into!(Vec3, Float32x3);
75impl_from_into!(Vec3A, Float32x3);
76impl_from!([f32; 4], Float32x4);
77impl_from_into!(Vec4, Float32x4);
78
79impl_from!(i32, Sint32);
80impl_from!([i32; 2], Sint32x2);
81impl_from_into!(IVec2, Sint32x2);
82impl_from!([i32; 3], Sint32x3);
83impl_from_into!(IVec3, Sint32x3);
84impl_from!([i32; 4], Sint32x4);
85impl_from_into!(IVec4, Sint32x4);
86
87impl_from!(u32, Uint32);
88impl_from!([u32; 2], Uint32x2);
89impl_from_into!(UVec2, Uint32x2);
90impl_from!([u32; 3], Uint32x3);
91impl_from_into!(UVec3, Uint32x3);
92impl_from!([u32; 4], Uint32x4);
93impl_from_into!(UVec4, Uint32x4);
94
95macro_rules! impl_try_from {
96 ($into:ty, $($variant:tt), +) => {
97 impl TryFrom<VertexAttributeValues> for Vec<$into> {
98 type Error = FromVertexAttributeError;
99
100 fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> {
101 match value {
102 $(VertexAttributeValues::$variant(value)) |+ => Ok(value),
103 _ => Err(FromVertexAttributeError::new::<Self>(value)),
104 }
105 }
106 }
107 };
108}
109
110macro_rules! impl_try_from_into {
111 ($into:ty, $($variant:tt), +) => {
112 impl TryFrom<VertexAttributeValues> for Vec<$into> {
113 type Error = FromVertexAttributeError;
114
115 fn try_from(value: VertexAttributeValues) -> Result<Self, Self::Error> {
116 match value {
117 $(VertexAttributeValues::$variant(value)) |+ => {
118 Ok(value.into_iter().map(|t| t.into()).collect())
119 }
120 _ => Err(FromVertexAttributeError::new::<Self>(value)),
121 }
122 }
123 }
124 };
125}
126
127impl_try_from!(f32, Float32);
128impl_try_from!([f32; 2], Float32x2);
129impl_try_from_into!(Vec2, Float32x2);
130impl_try_from!([f32; 3], Float32x3);
131impl_try_from_into!(Vec3, Float32x3);
132impl_try_from_into!(Vec3A, Float32x3);
133impl_try_from!([f32; 4], Float32x4);
134impl_try_from_into!(Vec4, Float32x4);
135
136impl_try_from!(i32, Sint32);
137impl_try_from!([i32; 2], Sint32x2);
138impl_try_from_into!(IVec2, Sint32x2);
139impl_try_from!([i32; 3], Sint32x3);
140impl_try_from_into!(IVec3, Sint32x3);
141impl_try_from!([i32; 4], Sint32x4);
142impl_try_from_into!(IVec4, Sint32x4);
143
144impl_try_from!(u32, Uint32);
145impl_try_from!([u32; 2], Uint32x2);
146impl_try_from_into!(UVec2, Uint32x2);
147impl_try_from!([u32; 3], Uint32x3);
148impl_try_from_into!(UVec3, Uint32x3);
149impl_try_from!([u32; 4], Uint32x4);
150impl_try_from_into!(UVec4, Uint32x4);
151
152impl_try_from!([i8; 2], Sint8x2, Snorm8x2);
153impl_try_from!([i8; 4], Sint8x4, Snorm8x4);
154
155impl_try_from!([u8; 2], Uint8x2, Unorm8x2);
156impl_try_from!([u8; 4], Uint8x4, Unorm8x4);
157
158impl_try_from!([i16; 2], Sint16x2, Snorm16x2);
159impl_try_from!([i16; 4], Sint16x4, Snorm16x4);
160
161impl_try_from!([u16; 2], Uint16x2, Unorm16x2);
162impl_try_from!([u16; 4], Uint16x4, Unorm16x4);
163
164#[cfg(test)]
165mod tests {
166 use bevy_math::{IVec2, IVec3, IVec4, UVec2, UVec3, UVec4, Vec2, Vec3, Vec3A, Vec4};
167
168 use super::VertexAttributeValues;
169 #[test]
170 fn f32() {
171 let buffer = vec![0.0; 10];
172 let values = VertexAttributeValues::from(buffer.clone());
173 let result_into: Vec<f32> = values.clone().try_into().unwrap();
174 let result_from: Vec<f32> = Vec::try_from(values.clone()).unwrap();
175 let error: Result<Vec<u32>, _> = values.try_into();
176 assert_eq!(buffer, result_into);
177 assert_eq!(buffer, result_from);
178 assert!(error.is_err());
179 }
180
181 #[test]
182 fn i32() {
183 let buffer = vec![0; 10];
184 let values = VertexAttributeValues::from(buffer.clone());
185 let result_into: Vec<i32> = values.clone().try_into().unwrap();
186 let result_from: Vec<i32> = Vec::try_from(values.clone()).unwrap();
187 let error: Result<Vec<u32>, _> = values.try_into();
188 assert_eq!(buffer, result_into);
189 assert_eq!(buffer, result_from);
190 assert!(error.is_err());
191 }
192
193 #[test]
194 fn u32() {
195 let buffer = vec![0_u32; 10];
196 let values = VertexAttributeValues::from(buffer.clone());
197 let result_into: Vec<u32> = values.clone().try_into().unwrap();
198 let result_from: Vec<u32> = Vec::try_from(values.clone()).unwrap();
199 let error: Result<Vec<f32>, _> = values.try_into();
200 assert_eq!(buffer, result_into);
201 assert_eq!(buffer, result_from);
202 assert!(error.is_err());
203 }
204
205 #[test]
206 fn f32_2() {
207 let buffer = vec![[0.0; 2]; 10];
208 let values = VertexAttributeValues::from(buffer.clone());
209 let result_into: Vec<[f32; 2]> = values.clone().try_into().unwrap();
210 let result_from: Vec<[f32; 2]> = Vec::try_from(values.clone()).unwrap();
211 let error: Result<Vec<u32>, _> = values.try_into();
212 assert_eq!(buffer, result_into);
213 assert_eq!(buffer, result_from);
214 assert!(error.is_err());
215 }
216
217 #[test]
218 fn vec2() {
219 let buffer = vec![Vec2::ZERO; 10];
220 let values = VertexAttributeValues::from(buffer.clone());
221 assert!(matches!(values, VertexAttributeValues::Float32x2(_)));
222 let result_into: Vec<Vec2> = values.clone().try_into().unwrap();
223 let result_from: Vec<Vec2> = Vec::try_from(values.clone()).unwrap();
224 let error: Result<Vec<u32>, _> = values.try_into();
225 assert_eq!(buffer, result_into);
226 assert_eq!(buffer, result_from);
227 assert!(error.is_err());
228 }
229
230 #[test]
231 fn i32_2() {
232 let buffer = vec![[0; 2]; 10];
233 let values = VertexAttributeValues::from(buffer.clone());
234 let result_into: Vec<[i32; 2]> = values.clone().try_into().unwrap();
235 let result_from: Vec<[i32; 2]> = Vec::try_from(values.clone()).unwrap();
236 let error: Result<Vec<u32>, _> = values.try_into();
237 assert_eq!(buffer, result_into);
238 assert_eq!(buffer, result_from);
239 assert!(error.is_err());
240 }
241
242 #[test]
243 fn ivec2() {
244 let buffer = vec![IVec2::ZERO; 10];
245 let values = VertexAttributeValues::from(buffer.clone());
246 assert!(matches!(values, VertexAttributeValues::Sint32x2(_)));
247 let result_into: Vec<IVec2> = values.clone().try_into().unwrap();
248 let result_from: Vec<IVec2> = Vec::try_from(values.clone()).unwrap();
249 let error: Result<Vec<u32>, _> = values.try_into();
250 assert_eq!(buffer, result_into);
251 assert_eq!(buffer, result_from);
252 assert!(error.is_err());
253 }
254
255 #[test]
256 fn u32_2() {
257 let buffer = vec![[0_u32; 2]; 10];
258 let values = VertexAttributeValues::from(buffer.clone());
259 let result_into: Vec<[u32; 2]> = values.clone().try_into().unwrap();
260 let result_from: Vec<[u32; 2]> = Vec::try_from(values.clone()).unwrap();
261 let error: Result<Vec<u32>, _> = values.try_into();
262 assert_eq!(buffer, result_into);
263 assert_eq!(buffer, result_from);
264 assert!(error.is_err());
265 }
266
267 #[test]
268 fn uvec2() {
269 let buffer = vec![UVec2::ZERO; 10];
270 let values = VertexAttributeValues::from(buffer.clone());
271 assert!(matches!(values, VertexAttributeValues::Uint32x2(_)));
272 let result_into: Vec<UVec2> = values.clone().try_into().unwrap();
273 let result_from: Vec<UVec2> = Vec::try_from(values.clone()).unwrap();
274 let error: Result<Vec<u32>, _> = values.try_into();
275 assert_eq!(buffer, result_into);
276 assert_eq!(buffer, result_from);
277 assert!(error.is_err());
278 }
279
280 #[test]
281 fn f32_3() {
282 let buffer = vec![[0.0; 3]; 10];
283 let values = VertexAttributeValues::from(buffer.clone());
284 let result_into: Vec<[f32; 3]> = values.clone().try_into().unwrap();
285 let result_from: Vec<[f32; 3]> = Vec::try_from(values.clone()).unwrap();
286 let error: Result<Vec<u32>, _> = values.try_into();
287 assert_eq!(buffer, result_into);
288 assert_eq!(buffer, result_from);
289 assert!(error.is_err());
290 }
291
292 #[test]
293 fn vec3() {
294 let buffer = vec![Vec3::ZERO; 10];
295 let values = VertexAttributeValues::from(buffer.clone());
296 assert!(matches!(values, VertexAttributeValues::Float32x3(_)));
297 let result_into: Vec<Vec3> = values.clone().try_into().unwrap();
298 let result_from: Vec<Vec3> = Vec::try_from(values.clone()).unwrap();
299 let error: Result<Vec<u32>, _> = values.try_into();
300 assert_eq!(buffer, result_into);
301 assert_eq!(buffer, result_from);
302 assert!(error.is_err());
303 }
304
305 #[test]
306 fn vec3a() {
307 let buffer = vec![Vec3A::ZERO; 10];
308 let values = VertexAttributeValues::from(buffer.clone());
309 assert!(matches!(values, VertexAttributeValues::Float32x3(_)));
310 let result_into: Vec<Vec3A> = values.clone().try_into().unwrap();
311 let result_from: Vec<Vec3A> = Vec::try_from(values.clone()).unwrap();
312 let error: Result<Vec<u32>, _> = values.try_into();
313 assert_eq!(buffer, result_into);
314 assert_eq!(buffer, result_from);
315 assert!(error.is_err());
316 }
317
318 #[test]
319 fn i32_3() {
320 let buffer = vec![[0; 3]; 10];
321 let values = VertexAttributeValues::from(buffer.clone());
322 let result_into: Vec<[i32; 3]> = values.clone().try_into().unwrap();
323 let result_from: Vec<[i32; 3]> = Vec::try_from(values.clone()).unwrap();
324 let error: Result<Vec<u32>, _> = values.try_into();
325 assert_eq!(buffer, result_into);
326 assert_eq!(buffer, result_from);
327 assert!(error.is_err());
328 }
329
330 #[test]
331 fn ivec3() {
332 let buffer = vec![IVec3::ZERO; 10];
333 let values = VertexAttributeValues::from(buffer.clone());
334 assert!(matches!(values, VertexAttributeValues::Sint32x3(_)));
335 let result_into: Vec<IVec3> = values.clone().try_into().unwrap();
336 let result_from: Vec<IVec3> = Vec::try_from(values.clone()).unwrap();
337 let error: Result<Vec<u32>, _> = values.try_into();
338 assert_eq!(buffer, result_into);
339 assert_eq!(buffer, result_from);
340 assert!(error.is_err());
341 }
342
343 #[test]
344 fn u32_3() {
345 let buffer = vec![[0_u32; 3]; 10];
346 let values = VertexAttributeValues::from(buffer.clone());
347 let result_into: Vec<[u32; 3]> = values.clone().try_into().unwrap();
348 let result_from: Vec<[u32; 3]> = Vec::try_from(values.clone()).unwrap();
349 let error: Result<Vec<u32>, _> = values.try_into();
350 assert_eq!(buffer, result_into);
351 assert_eq!(buffer, result_from);
352 assert!(error.is_err());
353 }
354
355 #[test]
356 fn uvec3() {
357 let buffer = vec![UVec3::ZERO; 10];
358 let values = VertexAttributeValues::from(buffer.clone());
359 assert!(matches!(values, VertexAttributeValues::Uint32x3(_)));
360 let result_into: Vec<UVec3> = values.clone().try_into().unwrap();
361 let result_from: Vec<UVec3> = Vec::try_from(values.clone()).unwrap();
362 let error: Result<Vec<u32>, _> = values.try_into();
363 assert_eq!(buffer, result_into);
364 assert_eq!(buffer, result_from);
365 assert!(error.is_err());
366 }
367
368 #[test]
369 fn f32_4() {
370 let buffer = vec![[0.0; 4]; 10];
371 let values = VertexAttributeValues::from(buffer.clone());
372 let result_into: Vec<[f32; 4]> = values.clone().try_into().unwrap();
373 let result_from: Vec<[f32; 4]> = Vec::try_from(values.clone()).unwrap();
374 let error: Result<Vec<u32>, _> = values.try_into();
375 assert_eq!(buffer, result_into);
376 assert_eq!(buffer, result_from);
377 assert!(error.is_err());
378 }
379
380 #[test]
381 fn vec4() {
382 let buffer = vec![Vec4::ZERO; 10];
383 let values = VertexAttributeValues::from(buffer.clone());
384 assert!(matches!(values, VertexAttributeValues::Float32x4(_)));
385 let result_into: Vec<Vec4> = values.clone().try_into().unwrap();
386 let result_from: Vec<Vec4> = Vec::try_from(values.clone()).unwrap();
387 let error: Result<Vec<u32>, _> = values.try_into();
388 assert_eq!(buffer, result_into);
389 assert_eq!(buffer, result_from);
390 assert!(error.is_err());
391 }
392
393 #[test]
394 fn i32_4() {
395 let buffer = vec![[0; 4]; 10];
396 let values = VertexAttributeValues::from(buffer.clone());
397 let result_into: Vec<[i32; 4]> = values.clone().try_into().unwrap();
398 let result_from: Vec<[i32; 4]> = Vec::try_from(values.clone()).unwrap();
399 let error: Result<Vec<u32>, _> = values.try_into();
400 assert_eq!(buffer, result_into);
401 assert_eq!(buffer, result_from);
402 assert!(error.is_err());
403 }
404
405 #[test]
406 fn ivec4() {
407 let buffer = vec![IVec4::ZERO; 10];
408 let values = VertexAttributeValues::from(buffer.clone());
409 assert!(matches!(values, VertexAttributeValues::Sint32x4(_)));
410 let result_into: Vec<IVec4> = values.clone().try_into().unwrap();
411 let result_from: Vec<IVec4> = Vec::try_from(values.clone()).unwrap();
412 let error: Result<Vec<u32>, _> = values.try_into();
413 assert_eq!(buffer, result_into);
414 assert_eq!(buffer, result_from);
415 assert!(error.is_err());
416 }
417
418 #[test]
419 fn u32_4() {
420 let buffer = vec![[0_u32; 4]; 10];
421 let values = VertexAttributeValues::from(buffer.clone());
422 let result_into: Vec<[u32; 4]> = values.clone().try_into().unwrap();
423 let result_from: Vec<[u32; 4]> = Vec::try_from(values.clone()).unwrap();
424 let error: Result<Vec<u32>, _> = values.try_into();
425 assert_eq!(buffer, result_into);
426 assert_eq!(buffer, result_from);
427 assert!(error.is_err());
428 }
429
430 #[test]
431 fn uvec4() {
432 let buffer = vec![UVec4::ZERO; 10];
433 let values = VertexAttributeValues::from(buffer.clone());
434 assert!(matches!(values, VertexAttributeValues::Uint32x4(_)));
435 let result_into: Vec<UVec4> = values.clone().try_into().unwrap();
436 let result_from: Vec<UVec4> = Vec::try_from(values.clone()).unwrap();
437 let error: Result<Vec<u32>, _> = values.try_into();
438 assert_eq!(buffer, result_into);
439 assert_eq!(buffer, result_from);
440 assert!(error.is_err());
441 }
442
443 #[test]
444 fn correct_message() {
445 let buffer = vec![[0_u32; 4]; 3];
446 let values = VertexAttributeValues::from(buffer);
447 let error_result: Result<Vec<u32>, _> = values.try_into();
448 let error = match error_result {
449 Ok(..) => unreachable!(),
450 Err(error) => error,
451 };
452 assert_eq!(
453 error.to_string(),
454 "cannot convert VertexAttributeValues::Uint32x4 to alloc::vec::Vec<u32>"
455 );
456 assert_eq!(format!("{error:?}"),
457 "FromVertexAttributeError { from: Uint32x4([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]), variant: \"Uint32x4\", into: \"alloc::vec::Vec<u32>\" }");
458 }
459}