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