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