bevy_mesh/
conversions.rs

1//! These implementations allow you to
2//! convert `std::vec::Vec<T>` to `VertexAttributeValues::T` and back.
3//!
4//! # Examples
5//!
6//! ```
7//! use bevy_mesh::VertexAttributeValues;
8//!
9//! // creating std::vec::Vec
10//! let buffer = vec![[0_u32; 4]; 10];
11//!
12//! // converting std::vec::Vec to bevy_mesh::VertexAttributeValues
13//! let values = VertexAttributeValues::from(buffer.clone());
14//!
15//! // converting bevy_mesh::VertexAttributeValues to std::vec::Vec with two ways
16//! let result_into: Vec<[u32; 4]> = values.clone().try_into().unwrap();
17//! let result_from: Vec<[u32; 4]> = Vec::try_from(values.clone()).unwrap();
18//!
19//! // getting an error when trying to convert incorrectly
20//! let error: Result<Vec<u32>, _> = values.try_into();
21//!
22//! assert_eq!(buffer, result_into);
23//! assert_eq!(buffer, result_from);
24//! assert!(error.is_err());
25//! ```
26
27use 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}