1use crate::{
2 DataTypeOps,
3 macros::{impl_data_arithmetic, impl_data_type_ops, impl_try_from_vec},
4 *,
5};
6#[cfg(feature = "matrix3")]
7use bytemuck::cast;
8use bytemuck::cast_slice;
9use std::{
10 fmt::Display,
11 ops::{Add, Div, Mul, Sub},
12 str::FromStr,
13};
14
15#[derive(Debug, Clone, PartialEq, strum::AsRefStr, strum::EnumDiscriminants)]
22#[strum_discriminants(name(DataType), derive(Hash))]
23#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
24#[cfg_attr(feature = "facet", derive(Facet))]
25#[cfg_attr(feature = "facet", facet(opaque))]
26#[cfg_attr(feature = "facet", repr(u8))]
27#[cfg_attr(feature = "rkyv", derive(Archive, RkyvSerialize, RkyvDeserialize))]
28pub enum Data {
29 Boolean(Boolean),
31 Integer(Integer),
33 Real(Real),
35 String(String),
37 Color(Color),
39 #[cfg(feature = "vector2")]
41 Vector2(Vector2),
42 #[cfg(feature = "vector3")]
44 Vector3(Vector3),
45 #[cfg(feature = "matrix3")]
47 Matrix3(Matrix3),
48 #[cfg(feature = "normal3")]
50 Normal3(Normal3),
51 #[cfg(feature = "point3")]
53 Point3(Point3),
54 #[cfg(feature = "matrix4")]
56 Matrix4(Matrix4),
57 BooleanVec(BooleanVec),
59 IntegerVec(IntegerVec),
61 RealVec(RealVec),
63 ColorVec(ColorVec),
65 StringVec(StringVec),
67 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
69 Vector2Vec(Vector2Vec),
70 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
72 Vector3Vec(Vector3Vec),
73 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
75 Matrix3Vec(Matrix3Vec),
76 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
78 Normal3Vec(Normal3Vec),
79 #[cfg(all(feature = "point3", feature = "vec_variants"))]
81 Point3Vec(Point3Vec),
82 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
84 Matrix4Vec(Matrix4Vec),
85}
86
87impl_data_type_ops!(Data);
88
89impl Data {
90 #[allow(clippy::len_without_is_empty)]
92 pub fn len(&self) -> usize {
93 self.try_len().unwrap_or(1)
94 }
95
96 pub fn try_len(&self) -> Option<usize> {
98 match self {
99 Data::BooleanVec(v) => Some(v.0.len()),
100 Data::IntegerVec(v) => Some(v.0.len()),
101 Data::RealVec(v) => Some(v.0.len()),
102 Data::StringVec(v) => Some(v.0.len()),
103 Data::ColorVec(v) => Some(v.0.len()),
104 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
105 Data::Vector2Vec(v) => Some(v.0.len()),
106 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
107 Data::Vector3Vec(v) => Some(v.0.len()),
108 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
109 Data::Matrix3Vec(v) => Some(v.0.len()),
110 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
111 Data::Normal3Vec(v) => Some(v.0.len()),
112 #[cfg(all(feature = "point3", feature = "vec_variants"))]
113 Data::Point3Vec(v) => Some(v.0.len()),
114 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
115 Data::Matrix4Vec(v) => Some(v.0.len()),
116 _ => None,
117 }
118 }
119
120 pub fn is_vec(&self) -> bool {
122 self.try_len().is_some()
123 }
124
125 #[named]
126 pub fn to_bool(&self) -> Result<bool> {
127 match self {
128 Data::Boolean(value) => Ok(value.0),
129 Data::Real(value) => Ok(value.0 != 0.0),
130 Data::Integer(value) => Ok(value.0 != 0),
131 Data::String(value) => Ok(value.0.parse::<bool>().unwrap_or(false)),
132 _ => Err(Error::IncompatibleType {
133 method: function_name!(),
134 got: self.data_type(),
135 }),
136 }
137 }
138
139 pub fn to_f32(&self) -> Result<f32> {
140 match self {
141 Data::Boolean(value) => {
142 if value.0 {
143 Ok(1.0)
144 } else {
145 Ok(0.0)
146 }
147 }
148 Data::Real(value) => Ok(value.0 as _),
149 Data::Integer(value) => Ok(value.0 as _),
150 _ => Err(Error::IncompatibleType {
151 method: "to_f32",
152 got: self.data_type(),
153 }),
154 }
155 }
156
157 pub fn to_f64(&self) -> Result<f64> {
158 match self {
159 Data::Boolean(value) => {
160 if value.0 {
161 Ok(1.0)
162 } else {
163 Ok(0.0)
164 }
165 }
166 Data::Real(value) => Ok(value.0),
167 Data::Integer(value) => Ok(value.0 as _),
168 _ => Err(Error::IncompatibleType {
169 method: "to_f64",
170 got: self.data_type(),
171 }),
172 }
173 }
174
175 #[named]
176 pub fn to_i32(&self) -> Result<i32> {
177 match self {
178 Data::Boolean(value) => Ok(if value.0 { 1 } else { 0 }),
179 Data::Real(value) => Ok((value.0 + 0.5) as i32),
180 Data::Integer(value) => value.0.try_into().map_err(Error::IntegerOverflow),
181 _ => Err(Error::IncompatibleType {
182 method: function_name!(),
183 got: self.data_type(),
184 }),
185 }
186 }
187
188 #[named]
189 pub fn to_i64(&self) -> Result<i64> {
190 match self {
191 Data::Boolean(value) => {
192 if value.0 {
193 Ok(1)
194 } else {
195 Ok(0)
196 }
197 }
198 Data::Real(value) => Ok((value.0 + 0.5) as _),
199 Data::Integer(value) => Ok(value.0),
200 _ => Err(Error::IncompatibleType {
201 method: function_name!(),
202 got: self.data_type(),
203 }),
204 }
205 }
206
207 #[named]
208 pub fn as_slice_f64(&self) -> Result<&[f64]> {
209 match self {
210 Data::RealVec(value) => Ok(value.0.as_slice()),
211 #[cfg(feature = "matrix4")]
212 Data::Matrix4(value) => Ok(crate::math::mat4_as_slice(&value.0)),
213 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
214 Data::Matrix4Vec(value) => {
215 Ok(bytemuck::cast_slice(&value.0))
217 }
218 _ => Err(Error::IncompatibleType {
219 method: function_name!(),
220 got: self.data_type(),
221 }),
222 }
223 }
224
225 #[named]
226 pub fn as_slice_f32(&self) -> Result<&[f32]> {
227 match self {
228 Data::Color(value) => Ok(value.0.as_slice()),
229 #[cfg(feature = "vector2")]
230 Data::Vector2(value) => Ok(crate::math::vec2_as_slice(&value.0)),
231 #[cfg(feature = "vector3")]
232 Data::Vector3(value) => Ok(crate::math::vec3_as_slice(&value.0)),
233 #[cfg(feature = "matrix3")]
234 Data::Matrix3(value) => Ok(crate::math::mat3_as_slice(&value.0)),
235 #[cfg(feature = "normal3")]
236 Data::Normal3(value) => Ok(crate::math::vec3_as_slice(&value.0)),
237 #[cfg(feature = "point3")]
238 Data::Point3(value) => Ok(crate::math::point3_as_slice(&value.0)),
239 Data::ColorVec(value) => Ok(cast_slice(value.0.as_slice())),
240 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
241 Data::Vector2Vec(value) => {
242 Ok(bytemuck::cast_slice(&value.0))
244 }
245 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
246 Data::Vector3Vec(value) => {
247 Ok(bytemuck::cast_slice(&value.0))
249 }
250 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
251 Data::Matrix3Vec(value) => {
252 Ok(bytemuck::cast_slice(&value.0))
254 }
255 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
256 Data::Normal3Vec(value) => {
257 Ok(bytemuck::cast_slice(&value.0))
259 }
260 #[cfg(all(feature = "point3", feature = "vec_variants"))]
261 Data::Point3Vec(value) => {
262 Ok(bytemuck::cast_slice(&value.0))
264 }
265 _ => Err(Error::IncompatibleType {
266 method: function_name!(),
267 got: self.data_type(),
268 }),
269 }
270 }
271
272 #[named]
273 pub fn as_slice_i64(&self) -> Result<&[i64]> {
274 match self {
275 Data::IntegerVec(value) => Ok(value.0.as_slice()),
276 _ => Err(Error::IncompatibleType {
277 method: function_name!(),
278 got: self.data_type(),
279 }),
280 }
281 }
282
283 #[named]
284 pub fn as_vector2_ref(&self) -> Result<&[f32; 2]> {
285 match self {
286 #[cfg(feature = "vector2")]
287 Data::Vector2(value) => Ok(math::vec2_as_ref(&value.0)),
288 _ => Err(Error::IncompatibleType {
289 method: function_name!(),
290 got: self.data_type(),
291 }),
292 }
293 }
294
295 #[named]
296 pub fn as_vector3_ref(&self) -> Result<&[f32; 3]> {
297 match self {
298 #[cfg(feature = "vector3")]
299 Data::Vector3(value) => Ok(math::vec3_as_ref(&value.0)),
300 _ => Err(Error::IncompatibleType {
301 method: function_name!(),
302 got: self.data_type(),
303 }),
304 }
305 }
306
307 #[named]
308 pub fn as_matrix3_ref(&self) -> Result<&[f32; 9]> {
309 match self {
310 #[cfg(feature = "matrix3")]
311 Data::Matrix3(value) => {
312 Ok(bytemuck::cast_ref(&value.0))
315 }
316 _ => Err(Error::IncompatibleType {
317 method: function_name!(),
318 got: self.data_type(),
319 }),
320 }
321 }
322
323 #[named]
324 pub fn as_color_ref(&self) -> Result<&[f32; 4]> {
325 match self {
326 Data::Color(value) => Ok(&value.0),
327 _ => Err(Error::IncompatibleType {
328 method: function_name!(),
329 got: self.data_type(),
330 }),
331 }
332 }
333
334 #[named]
335 #[cfg(feature = "normal3")]
336 pub fn as_normal3_ref(&self) -> Result<&[f32; 3]> {
337 match self {
338 Data::Normal3(value) => Ok(math::vec3_as_ref(&value.0)),
339 _ => Err(Error::IncompatibleType {
340 method: function_name!(),
341 got: self.data_type(),
342 }),
343 }
344 }
345
346 #[named]
347 #[cfg(feature = "point3")]
348 pub fn as_point3_ref(&self) -> Result<&[f32; 3]> {
349 match self {
350 Data::Point3(value) => Ok(crate::math::point3_as_ref(&value.0)),
351 _ => Err(Error::IncompatibleType {
352 method: function_name!(),
353 got: self.data_type(),
354 }),
355 }
356 }
357
358 #[named]
359 #[cfg(feature = "matrix4")]
360 pub fn as_matrix4_ref(&self) -> Result<&[f64; 16]> {
361 match self {
362 Data::Matrix4(value) => {
363 Ok(bytemuck::cast_ref(&value.0))
366 }
367 _ => Err(Error::IncompatibleType {
368 method: function_name!(),
369 got: self.data_type(),
370 }),
371 }
372 }
373
374 #[named]
375 pub fn as_str(&self) -> Result<&str> {
376 match self {
377 Data::String(value) => Ok(value.0.as_str()),
378 _ => Err(Error::IncompatibleType {
379 method: function_name!(),
380 got: self.data_type(),
381 }),
382 }
383 }
384
385 #[named]
386 pub fn as_slice_string(&self) -> Result<&[std::string::String]> {
387 match self {
388 Data::StringVec(value) => Ok(value.0.as_slice()),
389 _ => Err(Error::IncompatibleType {
390 method: function_name!(),
391 got: self.data_type(),
392 }),
393 }
394 }
395}
396
397macro_rules! impl_from_primitive {
399 ($from:ty, $variant:ident, $wrapper:ident) => {
400 impl From<$from> for Data {
401 fn from(v: $from) -> Self {
402 Data::$variant($wrapper(v as _))
403 }
404 }
405 };
406}
407
408impl_from_primitive!(i64, Integer, Integer);
410impl_from_primitive!(i32, Integer, Integer);
411impl_from_primitive!(i16, Integer, Integer);
412impl_from_primitive!(i8, Integer, Integer);
413impl_from_primitive!(u32, Integer, Integer);
414impl_from_primitive!(u16, Integer, Integer);
415impl_from_primitive!(u8, Integer, Integer);
416
417impl_from_primitive!(f64, Real, Real);
418impl_from_primitive!(f32, Real, Real);
419
420impl_from_primitive!(bool, Boolean, Boolean);
421
422impl From<std::string::String> for Data {
423 fn from(v: std::string::String) -> Self {
424 Data::String(String(v))
425 }
426}
427
428impl From<&str> for Data {
429 fn from(v: &str) -> Self {
430 Data::String(String(v.into()))
431 }
432}
433
434#[cfg(feature = "vector2")]
436impl From<[f32; 2]> for Data {
437 fn from(v: [f32; 2]) -> Self {
438 Data::Vector2(Vector2(v.into()))
439 }
440}
441
442#[cfg(feature = "vector3")]
443impl From<[f32; 3]> for Data {
444 fn from(v: [f32; 3]) -> Self {
445 Data::Vector3(Vector3(v.into()))
446 }
447}
448
449#[cfg(feature = "matrix3")]
450impl From<[[f32; 3]; 3]> for Data {
451 fn from(v: [[f32; 3]; 3]) -> Self {
452 let arr: [f32; 9] = cast(v);
453 Data::Matrix3(Matrix3(crate::math::mat3_from_row_slice(&arr)))
454 }
455}
456
457#[cfg(feature = "matrix3")]
458impl From<[f32; 9]> for Data {
459 fn from(v: [f32; 9]) -> Self {
460 Data::Matrix3(Matrix3(crate::math::mat3_from_row_slice(&v)))
461 }
462}
463
464impl From<[f32; 4]> for Data {
465 fn from(v: [f32; 4]) -> Self {
466 Data::Color(Color(v))
467 }
468}
469
470#[cfg(feature = "vector2")]
472impl From<crate::math::Vec2Impl> for Data {
473 fn from(v: crate::math::Vec2Impl) -> Self {
474 Data::Vector2(Vector2(v))
475 }
476}
477
478#[cfg(feature = "vector3")]
479impl From<crate::math::Vec3Impl> for Data {
480 fn from(v: crate::math::Vec3Impl) -> Self {
481 Data::Vector3(Vector3(v))
482 }
483}
484
485#[cfg(feature = "matrix3")]
486impl From<crate::math::Mat3Impl> for Data {
487 fn from(v: crate::math::Mat3Impl) -> Self {
488 Data::Matrix3(Matrix3(v))
489 }
490}
491
492impl TryFrom<Vec<i64>> for Data {
494 type Error = Error;
495
496 fn try_from(v: Vec<i64>) -> Result<Self> {
497 Ok(Data::IntegerVec(IntegerVec::new(v)?))
498 }
499}
500
501impl TryFrom<Vec<f64>> for Data {
502 type Error = Error;
503
504 fn try_from(v: Vec<f64>) -> Result<Self> {
505 Ok(Data::RealVec(RealVec::new(v)?))
506 }
507}
508
509impl TryFrom<Vec<bool>> for Data {
510 type Error = Error;
511
512 fn try_from(v: Vec<bool>) -> Result<Self> {
513 Ok(Data::BooleanVec(BooleanVec::new(v)?))
514 }
515}
516
517impl TryFrom<Vec<&str>> for Data {
518 type Error = Error;
519
520 fn try_from(v: Vec<&str>) -> Result<Self> {
521 let string_vec: Vec<std::string::String> = v.into_iter().map(|s| s.to_string()).collect();
522 Ok(Data::StringVec(StringVec::new(string_vec)?))
523 }
524}
525
526impl TryFrom<Vec<[f32; 4]>> for Data {
527 type Error = Error;
528
529 fn try_from(v: Vec<[f32; 4]>) -> Result<Self> {
530 Ok(Data::ColorVec(ColorVec::new(v)?))
531 }
532}
533
534#[cfg(all(feature = "vector2", feature = "vec_variants"))]
535impl TryFrom<Vec<crate::math::Vec2Impl>> for Data {
536 type Error = Error;
537
538 fn try_from(v: Vec<crate::math::Vec2Impl>) -> Result<Self> {
539 Ok(Data::Vector2Vec(Vector2Vec::new(v)?))
540 }
541}
542
543#[cfg(all(feature = "vector3", feature = "vec_variants"))]
544impl TryFrom<Vec<crate::math::Vec3Impl>> for Data {
545 type Error = Error;
546
547 fn try_from(v: Vec<crate::math::Vec3Impl>) -> Result<Self> {
548 Ok(Data::Vector3Vec(Vector3Vec::new(v)?))
549 }
550}
551
552#[cfg(all(feature = "matrix3", feature = "vec_variants"))]
553impl TryFrom<Vec<crate::math::Mat3Impl>> for Data {
554 type Error = Error;
555
556 fn try_from(v: Vec<crate::math::Mat3Impl>) -> Result<Self> {
557 Ok(Data::Matrix3Vec(Matrix3Vec::new(v)?))
558 }
559}
560
561impl From<Vec<u32>> for Data {
562 fn from(v: Vec<u32>) -> Self {
563 let int_vec: Vec<i64> = v.into_iter().map(|x| x as i64).collect();
564 Data::IntegerVec(IntegerVec(int_vec))
565 }
566}
567
568impl From<Vec<f32>> for Data {
569 fn from(v: Vec<f32>) -> Self {
570 let real_vec: Vec<f64> = v.into_iter().map(|x| x as f64).collect();
571 Data::RealVec(RealVec(real_vec))
572 }
573}
574
575impl TryFrom<Vec<std::string::String>> for Data {
576 type Error = Error;
577
578 fn try_from(v: Vec<std::string::String>) -> Result<Self> {
579 Ok(Data::StringVec(StringVec::new(v)?))
580 }
581}
582
583macro_rules! impl_try_from_value {
584 ($target:ty, $variant:ident) => {
585 impl TryFrom<Data> for $target {
586 type Error = Error;
587
588 fn try_from(value: Data) -> std::result::Result<Self, Self::Error> {
589 match value {
590 Data::$variant(v) => Ok(v.0),
591 _ => Err(Error::IncompatibleType {
592 method: concat!("TryFrom<Data> for ", stringify!($target)),
593 got: value.data_type(),
594 }),
595 }
596 }
597 }
598
599 impl TryFrom<&Data> for $target {
600 type Error = Error;
601
602 fn try_from(value: &Data) -> std::result::Result<Self, Self::Error> {
603 match value {
604 Data::$variant(v) => Ok(v.0.clone()),
605 _ => Err(Error::IncompatibleType {
606 method: concat!("TryFrom<&Data> for ", stringify!($target)),
607 got: value.data_type(),
608 }),
609 }
610 }
611 }
612 };
613}
614
615impl_try_from_value!(bool, Boolean);
617impl_try_from_value!(i64, Integer);
618impl_try_from_value!(f64, Real);
619impl_try_from_value!(std::string::String, String);
620impl_try_from_value!([f32; 4], Color);
621#[cfg(feature = "vector2")]
622impl_try_from_value!(crate::math::Vec2Impl, Vector2);
623#[cfg(feature = "vector3")]
624impl_try_from_value!(crate::math::Vec3Impl, Vector3);
625#[cfg(feature = "matrix3")]
626impl_try_from_value!(crate::math::Mat3Impl, Matrix3);
627
628impl_try_from_vec!(
630 bool, BooleanVec, "bool";
631 i64, IntegerVec, "i64";
632 f64, RealVec, "f64";
633 std::string::String, StringVec, "String";
634 [f32; 4], ColorVec, "[f32; 4]";
635);
636
637#[cfg(all(feature = "vector2", feature = "vec_variants"))]
638impl_try_from_vec!(
639 crate::math::Vec2Impl, Vector2Vec, "Vector2<f32>";
640);
641
642#[cfg(all(feature = "vector3", feature = "vec_variants"))]
643impl_try_from_vec!(
644 crate::math::Vec3Impl, Vector3Vec, "Vector3<f32>";
645);
646
647#[cfg(all(feature = "matrix3", feature = "vec_variants"))]
648impl_try_from_vec!(
649 crate::math::Mat3Impl, Matrix3Vec, "Matrix3<f32>";
650);
651
652impl Hash for Data {
654 fn hash<H: Hasher>(&self, state: &mut H) {
655 std::mem::discriminant(self).hash(state);
656 match self {
657 Data::Boolean(Boolean(b)) => b.hash(state),
658 Data::Integer(Integer(i)) => i.hash(state),
659 Data::Real(Real(f)) => f.to_bits().hash(state),
660 Data::String(String(s)) => s.hash(state),
661 Data::Color(Color(c)) => {
662 c.iter().for_each(|v| v.to_bits().hash(state));
663 }
664 #[cfg(feature = "vector2")]
665 Data::Vector2(Vector2(v)) => {
666 crate::math::vec2_as_slice(v)
667 .iter()
668 .for_each(|v| v.to_bits().hash(state));
669 }
670 #[cfg(feature = "vector3")]
671 Data::Vector3(Vector3(v)) => {
672 crate::math::vec3_as_slice(v)
673 .iter()
674 .for_each(|v| v.to_bits().hash(state));
675 }
676 #[cfg(feature = "matrix3")]
677 Data::Matrix3(Matrix3(m)) => {
678 crate::math::mat3_iter(m).for_each(|v| v.to_bits().hash(state));
679 }
680 #[cfg(feature = "normal3")]
681 Data::Normal3(Normal3(v)) => {
682 crate::math::vec3_as_slice(v)
683 .iter()
684 .for_each(|v| v.to_bits().hash(state));
685 }
686 #[cfg(feature = "point3")]
687 Data::Point3(Point3(p)) => {
688 crate::math::point3_as_slice(p)
689 .iter()
690 .for_each(|v| v.to_bits().hash(state));
691 }
692 #[cfg(feature = "matrix4")]
693 Data::Matrix4(Matrix4(m)) => {
694 crate::math::mat4_iter(m).for_each(|v| v.to_bits().hash(state));
695 }
696 Data::BooleanVec(BooleanVec(v)) => v.hash(state),
697 Data::IntegerVec(IntegerVec(v)) => v.hash(state),
698 Data::RealVec(RealVec(v)) => {
699 v.len().hash(state);
700 v.iter().for_each(|v| v.to_bits().hash(state));
701 }
702 Data::StringVec(StringVec(v)) => v.hash(state),
703 Data::ColorVec(ColorVec(v)) => {
704 v.len().hash(state);
705 v.iter()
706 .for_each(|c| c.iter().for_each(|v| v.to_bits().hash(state)));
707 }
708 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
709 Data::Vector2Vec(Vector2Vec(v)) => {
710 v.len().hash(state);
711 v.iter().for_each(|v| {
712 crate::math::vec2_as_slice(v)
713 .iter()
714 .for_each(|v| v.to_bits().hash(state))
715 });
716 }
717 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
718 Data::Vector3Vec(Vector3Vec(v)) => {
719 v.len().hash(state);
720 v.iter().for_each(|v| {
721 crate::math::vec3_as_slice(v)
722 .iter()
723 .for_each(|v| v.to_bits().hash(state))
724 });
725 }
726 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
727 Data::Matrix3Vec(Matrix3Vec(v)) => {
728 v.len().hash(state);
729 v.iter()
730 .for_each(|m| crate::math::mat3_iter(m).for_each(|v| v.to_bits().hash(state)));
731 }
732 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
733 Data::Normal3Vec(Normal3Vec(v)) => {
734 v.len().hash(state);
735 v.iter().for_each(|v| {
736 crate::math::vec3_as_slice(v)
737 .iter()
738 .for_each(|v| v.to_bits().hash(state))
739 });
740 }
741 #[cfg(all(feature = "point3", feature = "vec_variants"))]
742 Data::Point3Vec(Point3Vec(v)) => {
743 v.len().hash(state);
744 v.iter().for_each(|p| {
745 crate::math::point3_as_slice(p)
746 .iter()
747 .for_each(|v| v.to_bits().hash(state))
748 });
749 }
750 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
751 Data::Matrix4Vec(Matrix4Vec(v)) => {
752 v.len().hash(state);
753 v.iter()
754 .for_each(|m| crate::math::mat4_iter(m).for_each(|v| v.to_bits().hash(state)));
755 }
756 }
757 }
758}
759
760impl Data {
761 pub fn pad_to_length(&mut self, target_len: usize) {
764 match self {
765 Data::BooleanVec(BooleanVec(v)) => v.resize(target_len, false),
766 Data::IntegerVec(IntegerVec(v)) => v.resize(target_len, 0),
767 Data::RealVec(RealVec(v)) => v.resize(target_len, 0.0),
768 Data::StringVec(StringVec(v)) => v.resize(target_len, std::string::String::new()),
769 Data::ColorVec(ColorVec(v)) => v.resize(target_len, [0.0, 0.0, 0.0, 1.0]),
770 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
771 Data::Vector2Vec(Vector2Vec(v)) => v.resize(target_len, crate::math::vec2_zeros()),
772 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
773 Data::Vector3Vec(Vector3Vec(v)) => v.resize(target_len, crate::math::vec3_zeros()),
774 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
775 Data::Matrix3Vec(Matrix3Vec(v)) => v.resize(target_len, crate::math::mat3_zeros()),
776 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
777 Data::Normal3Vec(Normal3Vec(v)) => v.resize(target_len, crate::math::vec3_zeros()),
778 #[cfg(all(feature = "point3", feature = "vec_variants"))]
779 Data::Point3Vec(Point3Vec(v)) => v.resize(target_len, crate::math::point3_origin()),
780 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
781 Data::Matrix4Vec(Matrix4Vec(v)) => v.resize(target_len, crate::math::mat4_zeros()),
782 _ => {} }
784 }
785
786 pub fn try_convert(&self, to: DataType) -> Result<Data> {
788 match (self, to) {
789 (v, target) if v.data_type() == target => Ok(v.clone()),
791
792 (Data::Real(Real(f)), DataType::Integer) => Ok(Data::Integer(Integer(*f as i64))),
794 (Data::Boolean(Boolean(b)), DataType::Integer) => {
795 Ok(Data::Integer(Integer(if *b { 1 } else { 0 })))
796 }
797 (Data::String(String(s)), DataType::Integer) => s
798 .parse::<i64>()
799 .map(|i| Data::Integer(Integer(i)))
800 .map_err(|_| Error::ParseFailed {
801 input: s.clone(),
802 target_type: "Integer",
803 }),
804
805 (Data::Integer(Integer(i)), DataType::Real) => Ok(Data::Real(Real(*i as f64))),
807 (Data::Boolean(Boolean(b)), DataType::Real) => {
808 Ok(Data::Real(Real(if *b { 1.0 } else { 0.0 })))
809 }
810 (Data::String(String(s)), DataType::Real) => s
811 .parse::<f64>()
812 .map(|f| Data::Real(Real(f)))
813 .map_err(|_| Error::ParseFailed {
814 input: s.clone(),
815 target_type: "Real",
816 }),
817
818 (Data::Integer(Integer(i)), DataType::Boolean) => Ok(Data::Boolean(Boolean(*i != 0))),
820 (Data::Real(Real(f)), DataType::Boolean) => Ok(Data::Boolean(Boolean(*f != 0.0))),
821 (Data::String(String(s)), DataType::Boolean) => match s.to_lowercase().as_str() {
822 "true" | "yes" | "1" | "on" => Ok(Data::Boolean(Boolean(true))),
823 "false" | "no" | "0" | "off" | "" => Ok(Data::Boolean(Boolean(false))),
824 _ => Err(Error::ParseFailed {
825 input: s.clone(),
826 target_type: "Boolean",
827 }),
828 },
829
830 (Data::Integer(Integer(i)), DataType::String) => {
832 Ok(Data::String(String(i.to_string())))
833 }
834 (Data::Real(Real(f)), DataType::String) => Ok(Data::String(String(f.to_string()))),
835 (Data::Boolean(Boolean(b)), DataType::String) => {
836 Ok(Data::String(String(b.to_string())))
837 }
838 #[cfg(feature = "vector2")]
839 (Data::Vector2(Vector2(v)), DataType::String) => {
840 Ok(Data::String(String(format!("[{}, {}]", v[0], v[1]))))
841 }
842 #[cfg(feature = "vector3")]
843 (Data::Vector3(Vector3(v)), DataType::String) => Ok(Data::String(String(format!(
844 "[{}, {}, {}]",
845 v[0], v[1], v[2]
846 )))),
847 (Data::Color(Color(c)), DataType::String) => Ok(Data::String(String(format!(
848 "[{}, {}, {}, {}]",
849 c[0], c[1], c[2], c[3]
850 )))),
851 #[cfg(feature = "matrix3")]
852 (Data::Matrix3(Matrix3(m)), DataType::String) => {
853 Ok(Data::String(String(format!("{m:?}"))))
854 }
855 #[cfg(feature = "normal3")]
856 (Data::Normal3(Normal3(v)), DataType::String) => Ok(Data::String(String(format!(
857 "[{}, {}, {}]",
858 v[0], v[1], v[2]
859 )))),
860 #[cfg(feature = "point3")]
861 (Data::Point3(Point3(p)), DataType::String) => {
862 Ok(Data::String(String(format!("[{}, {}, {}]", p.x, p.y, p.z))))
863 }
864 #[cfg(feature = "matrix4")]
865 (Data::Matrix4(Matrix4(m)), DataType::String) => {
866 Ok(Data::String(String(format!("{m:?}"))))
867 }
868
869 #[cfg(feature = "vector2")]
871 (Data::Integer(Integer(i)), DataType::Vector2) => {
872 let v = *i as f32;
873 Ok(Data::Vector2(Vector2(crate::math::Vec2Impl::new(v, v))))
874 }
875 #[cfg(feature = "vector2")]
876 (Data::Real(Real(f)), DataType::Vector2) => {
877 let v = *f as f32;
878 Ok(Data::Vector2(Vector2(crate::math::Vec2Impl::new(v, v))))
879 }
880 #[cfg(feature = "vector2")]
881 (Data::RealVec(RealVec(vec)), DataType::Vector2) if vec.len() >= 2 => {
882 let v: Vec<f32> = vec.iter().take(2).map(|&x| x as f32).collect();
883 Ok(Data::Vector2(Vector2(crate::math::Vec2Impl::new(
884 v[0], v[1],
885 ))))
886 }
887 #[cfg(feature = "vector2")]
888 (Data::IntegerVec(IntegerVec(vec)), DataType::Vector2) if vec.len() >= 2 => {
889 let v: Vec<f32> = vec.iter().take(2).map(|&x| x as f32).collect();
890 Ok(Data::Vector2(Vector2(crate::math::Vec2Impl::new(
891 v[0], v[1],
892 ))))
893 }
894 #[cfg(feature = "vector2")]
895 (Data::String(String(s)), DataType::Vector2) => {
896 parse_to_array::<f32, 2>(s).map(|v| Data::Vector2(Vector2(v.into())))
897 }
898
899 #[cfg(feature = "vector3")]
901 (Data::Integer(Integer(i)), DataType::Vector3) => {
902 let v = *i as f32;
903 Ok(Data::Vector3(Vector3(crate::math::Vec3Impl::new(v, v, v))))
904 }
905 #[cfg(feature = "vector3")]
906 (Data::Real(Real(f)), DataType::Vector3) => {
907 let v = *f as f32;
908 Ok(Data::Vector3(Vector3(crate::math::Vec3Impl::new(v, v, v))))
909 }
910 #[cfg(all(feature = "vector2", feature = "vector3"))]
911 (Data::Vector2(Vector2(v)), DataType::Vector3) => Ok(Data::Vector3(Vector3(
912 crate::math::Vec3Impl::new(v.x, v.y, 0.0),
913 ))),
914 #[cfg(feature = "vector3")]
915 (Data::RealVec(RealVec(vec)), DataType::Vector3) if vec.len() >= 3 => {
916 let v: Vec<f32> = vec.iter().take(3).map(|&x| x as f32).collect();
917 Ok(Data::Vector3(Vector3(crate::math::Vec3Impl::new(
918 v[0], v[1], v[2],
919 ))))
920 }
921 #[cfg(feature = "vector3")]
922 (Data::IntegerVec(IntegerVec(vec)), DataType::Vector3) if vec.len() >= 3 => {
923 let v: Vec<f32> = vec.iter().take(3).map(|&x| x as f32).collect();
924 Ok(Data::Vector3(Vector3(crate::math::Vec3Impl::new(
925 v[0], v[1], v[2],
926 ))))
927 }
928 #[cfg(feature = "vector3")]
929 (Data::ColorVec(ColorVec(vec)), DataType::Vector3) if !vec.is_empty() => {
930 let c = &vec[0];
931 Ok(Data::Vector3(Vector3(crate::math::Vec3Impl::new(
932 c[0], c[1], c[2],
933 ))))
934 }
935 #[cfg(feature = "vector3")]
936 (Data::String(String(s)), DataType::Vector3) => {
937 parse_to_array::<f32, 3>(s).map(|v| Data::Vector3(Vector3(v.into())))
938 }
939
940 (Data::Real(Real(f)), DataType::Color) => {
942 let f = *f as f32;
943 Ok(Data::Color(Color([f, f, f, 1.0])))
944 }
945 (Data::RealVec(RealVec(vec)), DataType::Color) if vec.len() >= 3 => {
946 let mut color = [0.0f32; 4];
947 vec.iter()
948 .take(4)
949 .enumerate()
950 .for_each(|(i, &v)| color[i] = v as f32);
951 if vec.len() < 4 {
952 color[3] = 1.0;
953 }
954 Ok(Data::Color(Color(color)))
955 }
956 (Data::IntegerVec(IntegerVec(vec)), DataType::Color) if vec.len() >= 3 => {
957 let mut color = [0.0f32; 4];
958 vec.iter()
959 .take(4)
960 .enumerate()
961 .for_each(|(i, &v)| color[i] = v as f32);
962 if vec.len() < 4 {
963 color[3] = 1.0;
964 }
965 Ok(Data::Color(Color(color)))
966 }
967 #[cfg(feature = "vector3")]
968 (Data::Vector3(Vector3(v)), DataType::Color) => {
969 Ok(Data::Color(Color([v.x, v.y, v.z, 1.0])))
970 }
971 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
972 (Data::Vector3Vec(Vector3Vec(vec)), DataType::Color) if !vec.is_empty() => {
973 Ok(Data::Color(Color([vec[0].x, vec[0].y, vec[0].z, 1.0])))
974 }
975 #[cfg(feature = "vector2")]
976 (Data::Vector2(Vector2(v)), DataType::Color) => {
977 Ok(Data::Color(Color([v.x, v.y, 0.0, 1.0])))
978 }
979 #[cfg(feature = "point3")]
980 (Data::Point3(Point3(p)), DataType::Color) => {
981 Ok(Data::Color(Color([p.x, p.y, p.z, 1.0])))
982 }
983 #[cfg(feature = "normal3")]
984 (Data::Normal3(Normal3(v)), DataType::Color) => {
985 Ok(Data::Color(Color([v.x, v.y, v.z, 1.0])))
986 }
987 (Data::String(String(s)), DataType::Color) => parse_color_from_string(s)
988 .map(|c| Data::Color(Color(c)))
989 .ok_or_else(|| Error::ParseFailed {
990 input: s.clone(),
991 target_type: "Color",
992 }),
993
994 #[cfg(feature = "matrix3")]
996 (Data::Integer(Integer(i)), DataType::Matrix3) => {
997 let v = *i as f32;
998 Ok(Data::Matrix3(Matrix3(crate::math::mat3_from_row_slice(&[
999 v, 0.0, 0.0, 0.0, v, 0.0, 0.0, 0.0, 1.0,
1000 ]))))
1001 }
1002 #[cfg(feature = "matrix3")]
1003 (Data::Real(Real(f)), DataType::Matrix3) => {
1004 let v = *f as f32;
1005 Ok(Data::Matrix3(Matrix3(crate::math::mat3_from_row_slice(&[
1006 v, 0.0, 0.0, 0.0, v, 0.0, 0.0, 0.0, 1.0,
1007 ]))))
1008 }
1009 #[cfg(feature = "matrix3")]
1010 (Data::RealVec(RealVec(vec)), DataType::Matrix3) if vec.len() >= 9 => {
1011 let m: Vec<f32> = vec.iter().take(9).map(|&x| x as f32).collect();
1013 Ok(Data::Matrix3(Matrix3(crate::math::mat3_from_row_slice(&m))))
1014 }
1015 #[cfg(feature = "matrix3")]
1016 (Data::IntegerVec(IntegerVec(vec)), DataType::Matrix3) if vec.len() >= 9 => {
1017 let m: Vec<f32> = vec.iter().take(9).map(|&x| x as f32).collect();
1018 Ok(Data::Matrix3(Matrix3(crate::math::mat3_from_row_slice(&m))))
1019 }
1020 #[cfg(all(feature = "vector3", feature = "matrix3"))]
1021 (Data::Vector3(Vector3(v)), DataType::Matrix3) => {
1022 Ok(Data::Matrix3(Matrix3(crate::math::mat3_from_row_slice(&[
1023 v.x, 0.0, 0.0, 0.0, v.y, 0.0, 0.0, 0.0, v.z,
1024 ]))))
1025 }
1026 #[cfg(all(feature = "vector3", feature = "matrix3", feature = "vec_variants"))]
1027 (Data::Vector3Vec(Vector3Vec(vec)), DataType::Matrix3) if vec.len() >= 3 => {
1028 let cols: Vec<f32> = vec.iter().take(3).flat_map(|v| [v.x, v.y, v.z]).collect();
1030 Ok(Data::Matrix3(Matrix3(crate::math::mat3_from_column_slice(
1031 &cols,
1032 ))))
1033 }
1034 #[cfg(feature = "matrix3")]
1035 (Data::ColorVec(ColorVec(vec)), DataType::Matrix3) if vec.len() >= 3 => {
1036 let rows: Vec<f32> = vec
1038 .iter()
1039 .take(3)
1040 .flat_map(|c| c[0..3].iter().copied())
1041 .collect();
1042 Ok(Data::Matrix3(Matrix3(crate::math::mat3_from_row_slice(
1043 &rows,
1044 ))))
1045 }
1046 #[cfg(feature = "matrix3")]
1047 (Data::String(String(s)), DataType::Matrix3) => {
1048 if let Ok(single_val) = s.trim().parse::<f32>() {
1050 Ok(Data::Matrix3(Matrix3(crate::math::mat3_from_row_slice(&[
1051 single_val, 0.0, 0.0, 0.0, single_val, 0.0, 0.0, 0.0, single_val,
1052 ]))))
1053 } else {
1054 parse_to_array::<f32, 9>(s)
1056 .map(|m| Data::Matrix3(Matrix3(crate::math::mat3_from_row_slice(&m))))
1057 }
1058 }
1059
1060 #[cfg(feature = "normal3")]
1062 (Data::Integer(Integer(i)), DataType::Normal3) => {
1063 let v = *i as f32;
1064 Ok(Data::Normal3(Normal3(crate::math::Vec3Impl::new(v, v, v))))
1065 }
1066 #[cfg(feature = "normal3")]
1067 (Data::Real(Real(f)), DataType::Normal3) => {
1068 let v = *f as f32;
1069 Ok(Data::Normal3(Normal3(crate::math::Vec3Impl::new(v, v, v))))
1070 }
1071 #[cfg(all(feature = "vector3", feature = "normal3"))]
1072 (Data::Vector3(Vector3(v)), DataType::Normal3) => {
1073 Ok(Data::Normal3(Normal3(math::vec3_normalized(v))))
1074 }
1075 #[cfg(feature = "normal3")]
1076 (Data::String(String(s)), DataType::Normal3) => parse_to_array::<f32, 3>(s).map(|v| {
1077 let vec = crate::math::Vec3Impl::new(v[0], v[1], v[2]);
1078 Data::Normal3(Normal3(math::vec3_normalized(&vec)))
1079 }),
1080
1081 #[cfg(feature = "point3")]
1083 (Data::Integer(Integer(i)), DataType::Point3) => {
1084 let v = *i as f32;
1085 Ok(Data::Point3(Point3(crate::math::Point3Impl::new(v, v, v))))
1086 }
1087 #[cfg(feature = "point3")]
1088 (Data::Real(Real(f)), DataType::Point3) => {
1089 let v = *f as f32;
1090 Ok(Data::Point3(Point3(crate::math::Point3Impl::new(v, v, v))))
1091 }
1092 #[cfg(all(feature = "vector3", feature = "point3"))]
1093 (Data::Vector3(Vector3(v)), DataType::Point3) => Ok(Data::Point3(Point3(
1094 crate::math::Point3Impl::new(v.x, v.y, v.z),
1095 ))),
1096 #[cfg(feature = "point3")]
1097 (Data::String(String(s)), DataType::Point3) => parse_to_array::<f32, 3>(s)
1098 .map(|v| Data::Point3(Point3(crate::math::Point3Impl::new(v[0], v[1], v[2])))),
1099
1100 #[cfg(feature = "matrix4")]
1102 (Data::Integer(Integer(i)), DataType::Matrix4) => {
1103 let v = *i as f64;
1104 Ok(Data::Matrix4(Matrix4(crate::math::mat4_from_row_slice(&[
1105 v, 0.0, 0.0, 0.0, 0.0, v, 0.0, 0.0, 0.0, 0.0, v, 0.0, 0.0, 0.0, 0.0, 1.0,
1106 ]))))
1107 }
1108 #[cfg(feature = "matrix4")]
1109 (Data::Real(Real(f)), DataType::Matrix4) => {
1110 let v = *f;
1111 Ok(Data::Matrix4(Matrix4(crate::math::mat4_from_row_slice(&[
1112 v, 0.0, 0.0, 0.0, 0.0, v, 0.0, 0.0, 0.0, 0.0, v, 0.0, 0.0, 0.0, 0.0, 1.0,
1113 ]))))
1114 }
1115 #[cfg(feature = "matrix4")]
1116 (Data::RealVec(RealVec(vec)), DataType::Matrix4) if vec.len() >= 16 => {
1117 let m: Vec<f64> = vec.iter().take(16).copied().collect();
1119 Ok(Data::Matrix4(Matrix4(crate::math::mat4_from_row_slice(&m))))
1120 }
1121 #[cfg(feature = "matrix4")]
1122 (Data::IntegerVec(IntegerVec(vec)), DataType::Matrix4) if vec.len() >= 16 => {
1123 let m: Vec<f64> = vec.iter().take(16).map(|&x| x as f64).collect();
1124 Ok(Data::Matrix4(Matrix4(crate::math::mat4_from_row_slice(&m))))
1125 }
1126 #[cfg(all(feature = "matrix3", feature = "matrix4"))]
1127 (Data::Matrix3(Matrix3(m)), DataType::Matrix4) => {
1128 let r0 = crate::math::mat3_row(m, 0);
1131 let r1 = crate::math::mat3_row(m, 1);
1132 let r2 = crate::math::mat3_row(m, 2);
1133 Ok(Data::Matrix4(Matrix4(crate::math::mat4_from_row_slice(&[
1135 r0[0] as f64,
1136 r0[1] as f64,
1137 r0[2] as f64,
1138 0.0,
1139 r1[0] as f64,
1140 r1[1] as f64,
1141 r1[2] as f64,
1142 0.0,
1143 r2[0] as f64,
1144 r2[1] as f64,
1145 r2[2] as f64,
1146 0.0,
1147 0.0,
1148 0.0,
1149 0.0,
1150 1.0,
1151 ]))))
1152 }
1153 #[cfg(all(feature = "matrix3", feature = "matrix4", feature = "vec_variants"))]
1154 (Data::Matrix3Vec(Matrix3Vec(vec)), DataType::Matrix4) if !vec.is_empty() => {
1155 let m = &vec[0];
1156 let r0 = crate::math::mat3_row(m, 0);
1159 let r1 = crate::math::mat3_row(m, 1);
1160 let r2 = crate::math::mat3_row(m, 2);
1161 Ok(Data::Matrix4(Matrix4(crate::math::mat4_from_row_slice(&[
1163 r0[0] as f64,
1164 r0[1] as f64,
1165 r0[2] as f64,
1166 0.0,
1167 r1[0] as f64,
1168 r1[1] as f64,
1169 r1[2] as f64,
1170 0.0,
1171 r2[0] as f64,
1172 r2[1] as f64,
1173 r2[2] as f64,
1174 0.0,
1175 0.0,
1176 0.0,
1177 0.0,
1178 1.0,
1179 ]))))
1180 }
1181 #[cfg(feature = "matrix4")]
1182 (Data::ColorVec(ColorVec(vec)), DataType::Matrix4) if vec.len() >= 4 => {
1183 let rows: Vec<f64> = vec
1185 .iter()
1186 .take(4)
1187 .flat_map(|c| c.iter().map(|&x| x as f64))
1188 .collect();
1189 Ok(Data::Matrix4(Matrix4(crate::math::mat4_from_row_slice(
1190 &rows,
1191 ))))
1192 }
1193 #[cfg(feature = "matrix4")]
1194 (Data::String(String(s)), DataType::Matrix4) => {
1195 if let Ok(single_val) = s.trim().parse::<f64>() {
1197 Ok(Data::Matrix4(Matrix4(crate::math::mat4_from_row_slice(&[
1198 single_val, 0.0, 0.0, 0.0, 0.0, single_val, 0.0, 0.0, 0.0, 0.0, single_val,
1199 0.0, 0.0, 0.0, 0.0, single_val,
1200 ]))))
1201 } else {
1202 parse_to_array::<f64, 16>(s)
1204 .map(|m| Data::Matrix4(Matrix4(crate::math::mat4_from_row_slice(&m))))
1205 }
1206 }
1207
1208 (Data::Integer(Integer(i)), DataType::RealVec) => {
1211 Ok(Data::RealVec(RealVec(vec![*i as f64])))
1212 }
1213 (Data::Real(Real(f)), DataType::RealVec) => Ok(Data::RealVec(RealVec(vec![*f]))),
1214 #[cfg(feature = "vector2")]
1215 (Data::Vector2(Vector2(v)), DataType::RealVec) => Ok(Data::RealVec(RealVec(
1216 crate::math::vec2_as_slice(v)
1217 .iter()
1218 .map(|&x| x as f64)
1219 .collect(),
1220 ))),
1221 #[cfg(feature = "vector3")]
1222 (Data::Vector3(Vector3(v)), DataType::RealVec) => Ok(Data::RealVec(RealVec(
1223 crate::math::vec3_as_slice(v)
1224 .iter()
1225 .map(|&x| x as f64)
1226 .collect(),
1227 ))),
1228 (Data::Color(Color(c)), DataType::RealVec) => Ok(Data::RealVec(RealVec(
1229 c.iter().map(|&x| x as f64).collect(),
1230 ))),
1231 #[cfg(feature = "matrix3")]
1232 (Data::Matrix3(Matrix3(m)), DataType::RealVec) => Ok(Data::RealVec(RealVec(
1233 crate::math::mat3_iter(m).map(|&x| x as f64).collect(),
1234 ))),
1235 #[cfg(feature = "matrix4")]
1236 (Data::Matrix4(Matrix4(m)), DataType::RealVec) => Ok(Data::RealVec(RealVec(
1237 crate::math::mat4_iter(m).copied().collect(),
1238 ))),
1239 #[cfg(feature = "normal3")]
1240 (Data::Normal3(Normal3(v)), DataType::RealVec) => Ok(Data::RealVec(RealVec(
1241 crate::math::vec3_as_slice(v)
1242 .iter()
1243 .map(|&x| x as f64)
1244 .collect(),
1245 ))),
1246 #[cfg(feature = "point3")]
1247 (Data::Point3(Point3(p)), DataType::RealVec) => Ok(Data::RealVec(RealVec(vec![
1248 p.x as f64, p.y as f64, p.z as f64,
1249 ]))),
1250
1251 (Data::Boolean(Boolean(b)), DataType::IntegerVec) => {
1253 Ok(Data::IntegerVec(IntegerVec(vec![if *b { 1 } else { 0 }])))
1254 }
1255 (Data::Integer(Integer(i)), DataType::IntegerVec) => {
1256 Ok(Data::IntegerVec(IntegerVec(vec![*i])))
1257 }
1258 (Data::Real(Real(f)), DataType::IntegerVec) => {
1259 Ok(Data::IntegerVec(IntegerVec(vec![*f as i64])))
1260 }
1261 #[cfg(feature = "vector2")]
1262 (Data::Vector2(Vector2(v)), DataType::IntegerVec) => Ok(Data::IntegerVec(IntegerVec(
1263 crate::math::vec2_as_slice(v)
1264 .iter()
1265 .map(|&x| x as i64)
1266 .collect(),
1267 ))),
1268 #[cfg(feature = "vector3")]
1269 (Data::Vector3(Vector3(v)), DataType::IntegerVec) => Ok(Data::IntegerVec(IntegerVec(
1270 crate::math::vec3_as_slice(v)
1271 .iter()
1272 .map(|&x| x as i64)
1273 .collect(),
1274 ))),
1275 (Data::Color(Color(c)), DataType::IntegerVec) => Ok(Data::IntegerVec(IntegerVec(
1276 c.iter().map(|&x| (x * 255.0) as i64).collect(),
1277 ))),
1278 #[cfg(feature = "matrix3")]
1279 (Data::Matrix3(Matrix3(m)), DataType::IntegerVec) => Ok(Data::IntegerVec(IntegerVec(
1280 crate::math::mat3_iter(m).map(|&x| x as i64).collect(),
1281 ))),
1282 #[cfg(feature = "matrix4")]
1283 (Data::Matrix4(Matrix4(m)), DataType::IntegerVec) => Ok(Data::IntegerVec(IntegerVec(
1284 crate::math::mat4_iter(m).map(|&x| x as i64).collect(),
1285 ))),
1286
1287 (Data::Color(Color(c)), DataType::ColorVec) => Ok(Data::ColorVec(ColorVec(vec![*c]))),
1289 #[cfg(feature = "vector3")]
1290 (Data::Vector3(Vector3(v)), DataType::ColorVec) => {
1291 Ok(Data::ColorVec(ColorVec(vec![[v.x, v.y, v.z, 1.0]])))
1292 }
1293 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
1294 (Data::Vector3Vec(Vector3Vec(vec)), DataType::ColorVec) => {
1295 let colors = vec.iter().map(|v| [v.x, v.y, v.z, 1.0]).collect();
1296 Ok(Data::ColorVec(ColorVec(colors)))
1297 }
1298 #[cfg(feature = "matrix3")]
1299 (Data::Matrix3(Matrix3(m)), DataType::ColorVec) => {
1300 let colors = (0..3)
1302 .map(|i| {
1303 let row = crate::math::mat3_row(m, i);
1304 [row[0], row[1], row[2], 1.0]
1305 })
1306 .collect();
1307 Ok(Data::ColorVec(ColorVec(colors)))
1308 }
1309
1310 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
1312 (Data::Vector2(Vector2(v)), DataType::Vector2Vec) => {
1313 Ok(Data::Vector2Vec(Vector2Vec(vec![*v])))
1314 }
1315 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
1316 (Data::RealVec(RealVec(vec)), DataType::Vector2Vec)
1317 if vec.len() >= 2 && vec.len() % 2 == 0 =>
1318 {
1319 let vectors = vec
1320 .chunks_exact(2)
1321 .map(|chunk| crate::math::Vec2Impl::new(chunk[0] as f32, chunk[1] as f32))
1322 .collect();
1323 Ok(Data::Vector2Vec(Vector2Vec(vectors)))
1324 }
1325
1326 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
1328 (Data::Vector3(Vector3(v)), DataType::Vector3Vec) => {
1329 Ok(Data::Vector3Vec(Vector3Vec(vec![*v])))
1330 }
1331 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
1332 (Data::RealVec(RealVec(vec)), DataType::Vector3Vec)
1333 if vec.len() >= 3 && vec.len() % 3 == 0 =>
1334 {
1335 let vectors = vec
1336 .chunks_exact(3)
1337 .map(|chunk| {
1338 crate::math::Vec3Impl::new(
1339 chunk[0] as f32,
1340 chunk[1] as f32,
1341 chunk[2] as f32,
1342 )
1343 })
1344 .collect();
1345 Ok(Data::Vector3Vec(Vector3Vec(vectors)))
1346 }
1347 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
1348 (Data::IntegerVec(IntegerVec(vec)), DataType::Vector3Vec)
1349 if vec.len() >= 3 && vec.len() % 3 == 0 =>
1350 {
1351 let vectors = vec
1352 .chunks_exact(3)
1353 .map(|chunk| {
1354 crate::math::Vec3Impl::new(
1355 chunk[0] as f32,
1356 chunk[1] as f32,
1357 chunk[2] as f32,
1358 )
1359 })
1360 .collect();
1361 Ok(Data::Vector3Vec(Vector3Vec(vectors)))
1362 }
1363 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
1364 (Data::ColorVec(ColorVec(vec)), DataType::Vector3Vec) => {
1365 let vectors = vec
1366 .iter()
1367 .map(|c| crate::math::Vec3Impl::new(c[0], c[1], c[2]))
1368 .collect();
1369 Ok(Data::Vector3Vec(Vector3Vec(vectors)))
1370 }
1371
1372 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
1374 (Data::Matrix3(Matrix3(m)), DataType::Matrix3Vec) => {
1375 Ok(Data::Matrix3Vec(Matrix3Vec(vec![*m])))
1376 }
1377 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
1378 (Data::RealVec(RealVec(vec)), DataType::Matrix3Vec)
1379 if vec.len() >= 9 && vec.len() % 9 == 0 =>
1380 {
1381 let matrices = vec
1382 .chunks_exact(9)
1383 .map(|chunk| {
1384 let m: Vec<f32> = chunk.iter().map(|&x| x as f32).collect();
1385 crate::math::mat3_from_row_slice(&m)
1386 })
1387 .collect();
1388 Ok(Data::Matrix3Vec(Matrix3Vec(matrices)))
1389 }
1390
1391 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
1393 (Data::Matrix4(Matrix4(m)), DataType::Matrix4Vec) => {
1394 Ok(Data::Matrix4Vec(Matrix4Vec(vec![*m])))
1395 }
1396 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
1397 (Data::RealVec(RealVec(vec)), DataType::Matrix4Vec)
1398 if vec.len() >= 16 && vec.len() % 16 == 0 =>
1399 {
1400 let matrices = vec
1401 .chunks_exact(16)
1402 .map(crate::math::mat4_from_row_slice)
1403 .collect();
1404 Ok(Data::Matrix4Vec(Matrix4Vec(matrices)))
1405 }
1406
1407 #[cfg(feature = "vec_variants")]
1409 (Data::RealVec(RealVec(vec)), DataType::IntegerVec) => {
1410 Ok(Data::IntegerVec(IntegerVec(
1412 vec.iter().map(|&f| f.round() as i64).collect(),
1413 )))
1414 }
1415 #[cfg(feature = "vec_variants")]
1416 (Data::IntegerVec(IntegerVec(vec)), DataType::RealVec) => {
1417 Ok(Data::RealVec(RealVec(
1419 vec.iter().map(|&i| i as f64).collect(),
1420 )))
1421 }
1422 #[cfg(feature = "vec_variants")]
1423 (Data::BooleanVec(BooleanVec(vec)), DataType::IntegerVec) => {
1424 Ok(Data::IntegerVec(IntegerVec(
1426 vec.iter().map(|&b| if b { 1 } else { 0 }).collect(),
1427 )))
1428 }
1429 #[cfg(feature = "vec_variants")]
1430 (Data::IntegerVec(IntegerVec(vec)), DataType::BooleanVec) => {
1431 Ok(Data::BooleanVec(BooleanVec(
1433 vec.iter().map(|&i| i != 0).collect(),
1434 )))
1435 }
1436 #[cfg(feature = "vec_variants")]
1437 (Data::BooleanVec(BooleanVec(vec)), DataType::RealVec) => {
1438 Ok(Data::RealVec(RealVec(
1440 vec.iter().map(|&b| if b { 1.0 } else { 0.0 }).collect(),
1441 )))
1442 }
1443 #[cfg(feature = "vec_variants")]
1444 (Data::RealVec(RealVec(vec)), DataType::BooleanVec) => {
1445 Ok(Data::BooleanVec(BooleanVec(
1447 vec.iter().map(|&f| f != 0.0).collect(),
1448 )))
1449 }
1450
1451 _ => Err(Error::ConversionUnsupported {
1453 from: self.data_type(),
1454 to,
1455 }),
1456 }
1457 }
1458}
1459
1460fn parse_color_from_string(s: &str) -> Option<[f32; 4]> {
1461 let s = s.trim();
1462
1463 if s.starts_with('#') {
1465 let hex = s.trim_start_matches('#');
1466 if (hex.len() == 6 || hex.len() == 8)
1467 && let Ok(val) = u32::from_str_radix(hex, 16)
1468 {
1469 let r = ((val >> 16) & 0xFF) as f32 / 255.0;
1470 let g = ((val >> 8) & 0xFF) as f32 / 255.0;
1471 let b = (val & 0xFF) as f32 / 255.0;
1472 let a = if hex.len() == 8 {
1473 ((val >> 24) & 0xFF) as f32 / 255.0
1474 } else {
1475 1.0
1476 };
1477 Some([r, g, b, a])
1478 } else {
1479 None
1480 }
1481 } else {
1482 let s = s.trim_start_matches('[').trim_end_matches(']');
1484 let parts: Vec<&str> = s
1485 .split([',', ' '])
1486 .map(|p| p.trim())
1487 .filter(|p| !p.is_empty())
1488 .collect();
1489
1490 match parts.len() {
1491 4 => {
1492 if let (Ok(r), Ok(g), Ok(b), Ok(a)) = (
1493 parts[0].parse::<f32>(),
1494 parts[1].parse::<f32>(),
1495 parts[2].parse::<f32>(),
1496 parts[3].parse::<f32>(),
1497 ) {
1498 Some([r, g, b, a])
1499 } else {
1500 None
1501 }
1502 }
1503 3 => {
1504 if let (Ok(r), Ok(g), Ok(b)) = (
1505 parts[0].parse::<f32>(),
1506 parts[1].parse::<f32>(),
1507 parts[2].parse::<f32>(),
1508 ) {
1509 Some([r, g, b, 1.0])
1510 } else {
1511 None
1512 }
1513 }
1514 1 => {
1515 if let Ok(v) = parts[0].parse::<f32>() {
1517 Some([v, v, v, 1.0])
1518 } else {
1519 None
1520 }
1521 }
1522 _ => None,
1523 }
1524 }
1525}
1526
1527fn parse_to_array<T, const N: usize>(input: &str) -> Result<[T; N]>
1533where
1534 T: FromStr + Default + Debug,
1535 <T as FromStr>::Err: Display,
1536{
1537 let cleaned_input = input.trim().trim_start_matches('[').trim_end_matches(']');
1539
1540 let mut result = cleaned_input
1541 .split(&[',', ' '][..])
1542 .map(|s| s.trim())
1543 .filter(|&s| !s.is_empty())
1544 .take(N)
1545 .map(|s| {
1546 s.parse::<T>().map_err(|_| Error::ParseFailed {
1547 input: input.to_string(),
1548 target_type: std::any::type_name::<T>(),
1549 })
1550 })
1551 .collect::<std::result::Result<SmallVec<[T; N]>, _>>()?;
1552
1553 if result.len() < N {
1554 result.extend((0..N - result.len()).map(|_| T::default()));
1555 }
1556
1557 Ok(result.into_inner().unwrap())
1559}
1560
1561impl_data_arithmetic!(binary Add, add, "add");
1563impl_data_arithmetic!(binary Sub, sub, "subtract");
1564impl_data_arithmetic!(scalar f32);
1565impl_data_arithmetic!(scalar f64);
1566impl_data_arithmetic!(div f32);
1567impl_data_arithmetic!(div f64);
1568
1569impl Eq for Data {}
1572
1573impl crate::traits::DataSystem for Data {
1575 type Animated = AnimatedData;
1576 type DataType = DataType;
1577
1578 fn discriminant(&self) -> DataType {
1579 DataTypeOps::data_type(self)
1580 }
1581
1582 fn variant_name(&self) -> &'static str {
1583 DataTypeOps::type_name(self)
1584 }
1585
1586 fn try_len(&self) -> Option<usize> {
1587 Data::try_len(self)
1588 }
1589
1590 fn pad_to_length(&mut self, target_len: usize) {
1591 Data::pad_to_length(self, target_len)
1592 }
1593}