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