1use crate::error::FieldValueError;
7
8#[derive(Debug, Clone, PartialEq)]
49pub enum FieldValue {
50 Boolean(bool),
52 String(String),
54 Float(f32),
56
57 Vector2D([f32; 2]),
59 Vector3D([f32; 3]),
61 Vector4D([f32; 4]),
63
64 Signed8(i8),
66 Signed16(i16),
68 Signed32(i32),
70 Signed64(i64),
72
73 Unsigned8(u8),
75 Unsigned16(u16),
77 Unsigned32(u32),
79 Unsigned64(u64),
81}
82
83pub trait IntoFieldValue {
85 fn into_field_value(self) -> FieldValue;
87}
88
89pub trait FieldRewriteResult {
94 fn into_field_rewrite_result(self) -> Option<FieldValue>;
96}
97
98impl<T> FieldRewriteResult for T
99where
100 T: IntoFieldValue,
101{
102 fn into_field_rewrite_result(self) -> Option<FieldValue> {
103 Some(self.into_field_value())
104 }
105}
106
107impl<T> FieldRewriteResult for Option<T>
108where
109 T: IntoFieldValue,
110{
111 fn into_field_rewrite_result(self) -> Option<FieldValue> {
112 self.map(IntoFieldValue::into_field_value)
113 }
114}
115
116impl IntoFieldValue for FieldValue {
117 fn into_field_value(self) -> FieldValue {
118 self
119 }
120}
121
122impl IntoFieldValue for String {
123 fn into_field_value(self) -> FieldValue {
124 FieldValue::String(self)
125 }
126}
127
128impl IntoFieldValue for &str {
129 fn into_field_value(self) -> FieldValue {
130 FieldValue::String(self.to_string())
131 }
132}
133
134impl IntoFieldValue for bool {
135 fn into_field_value(self) -> FieldValue {
136 FieldValue::Boolean(self)
137 }
138}
139
140impl IntoFieldValue for f32 {
141 fn into_field_value(self) -> FieldValue {
142 FieldValue::Float(self)
143 }
144}
145
146impl IntoFieldValue for [f32; 2] {
147 fn into_field_value(self) -> FieldValue {
148 FieldValue::Vector2D(self)
149 }
150}
151
152impl IntoFieldValue for [f32; 3] {
153 fn into_field_value(self) -> FieldValue {
154 FieldValue::Vector3D(self)
155 }
156}
157
158impl IntoFieldValue for [f32; 4] {
159 fn into_field_value(self) -> FieldValue {
160 FieldValue::Vector4D(self)
161 }
162}
163
164macro_rules! impl_into_field_value {
165 ($($ty:ty => $variant:ident),* $(,)?) => {
166 $(
167 impl IntoFieldValue for $ty {
168 fn into_field_value(self) -> FieldValue {
169 FieldValue::$variant(self)
170 }
171 }
172 )*
173 };
174}
175
176impl_into_field_value! {
177 i8 => Signed8,
178 i16 => Signed16,
179 i32 => Signed32,
180 i64 => Signed64,
181 u8 => Unsigned8,
182 u16 => Unsigned16,
183 u32 => Unsigned32,
184 u64 => Unsigned64,
185}
186
187impl TryInto<String> for FieldValue {
188 type Error = FieldValueError;
189
190 fn try_into(self) -> Result<String, FieldValueError> {
191 if let FieldValue::String(x) = self {
192 Ok(x)
193 } else {
194 Err(FieldValueError::ConversionError(
195 format!("{:?}", self),
196 "String".to_string(),
197 ))
198 }
199 }
200}
201
202impl TryInto<String> for &FieldValue {
203 type Error = FieldValueError;
204
205 fn try_into(self) -> Result<String, FieldValueError> {
206 if let FieldValue::String(x) = self {
207 Ok(x.to_owned())
208 } else {
209 Err(FieldValueError::ConversionError(
210 format!("{:?}", self),
211 "String".to_string(),
212 ))
213 }
214 }
215}
216
217impl TryInto<[f32; 2]> for FieldValue {
218 type Error = FieldValueError;
219
220 fn try_into(self) -> Result<[f32; 2], FieldValueError> {
221 if let FieldValue::Vector2D(x) = self {
222 Ok(x)
223 } else {
224 Err(FieldValueError::ConversionError(
225 format!("{:?}", self),
226 "[f32; 2]".to_string(),
227 ))
228 }
229 }
230}
231
232impl TryInto<[f32; 2]> for &FieldValue {
233 type Error = FieldValueError;
234
235 fn try_into(self) -> Result<[f32; 2], FieldValueError> {
236 if let FieldValue::Vector2D(x) = self {
237 Ok(*x)
238 } else {
239 Err(FieldValueError::ConversionError(
240 format!("{:?}", self),
241 "[f32; 2]".to_string(),
242 ))
243 }
244 }
245}
246
247impl TryInto<(f32, f32)> for FieldValue {
248 type Error = FieldValueError;
249
250 fn try_into(self) -> Result<(f32, f32), FieldValueError> {
251 if let FieldValue::Vector2D(x) = self {
252 Ok(x.into())
253 } else {
254 Err(FieldValueError::ConversionError(
255 format!("{:?}", self),
256 "(f32, f32)".to_string(),
257 ))
258 }
259 }
260}
261
262impl TryInto<(f32, f32)> for &FieldValue {
263 type Error = FieldValueError;
264
265 fn try_into(self) -> Result<(f32, f32), FieldValueError> {
266 if let FieldValue::Vector2D(x) = self {
267 Ok((*x).into())
268 } else {
269 Err(FieldValueError::ConversionError(
270 format!("{:?}", self),
271 "(f32, f32)".to_string(),
272 ))
273 }
274 }
275}
276
277impl TryInto<[f32; 3]> for FieldValue {
278 type Error = FieldValueError;
279
280 fn try_into(self) -> Result<[f32; 3], FieldValueError> {
281 if let FieldValue::Vector3D(x) = self {
282 Ok(x)
283 } else {
284 Err(FieldValueError::ConversionError(
285 format!("{:?}", self),
286 "[f32; 3]".to_string(),
287 ))
288 }
289 }
290}
291
292impl TryInto<[f32; 3]> for &FieldValue {
293 type Error = FieldValueError;
294
295 fn try_into(self) -> Result<[f32; 3], FieldValueError> {
296 if let FieldValue::Vector3D(x) = self {
297 Ok(*x)
298 } else {
299 Err(FieldValueError::ConversionError(
300 format!("{:?}", self),
301 "[f32; 3]".to_string(),
302 ))
303 }
304 }
305}
306
307impl TryInto<(f32, f32, f32)> for FieldValue {
308 type Error = FieldValueError;
309
310 fn try_into(self) -> Result<(f32, f32, f32), FieldValueError> {
311 if let FieldValue::Vector3D(x) = self {
312 Ok(x.into())
313 } else {
314 Err(FieldValueError::ConversionError(
315 format!("{:?}", self),
316 "(f32, f32, f32)".to_string(),
317 ))
318 }
319 }
320}
321
322impl TryInto<(f32, f32, f32)> for &FieldValue {
323 type Error = FieldValueError;
324
325 fn try_into(self) -> Result<(f32, f32, f32), FieldValueError> {
326 if let FieldValue::Vector3D(x) = self {
327 Ok((*x).into())
328 } else {
329 Err(FieldValueError::ConversionError(
330 format!("{:?}", self),
331 "(f32, f32, f32)".to_string(),
332 ))
333 }
334 }
335}
336
337impl TryInto<[f32; 4]> for FieldValue {
338 type Error = FieldValueError;
339
340 fn try_into(self) -> Result<[f32; 4], FieldValueError> {
341 if let FieldValue::Vector4D(x) = self {
342 Ok(x)
343 } else {
344 Err(FieldValueError::ConversionError(
345 format!("{:?}", self),
346 "[f32; 4]".to_string(),
347 ))
348 }
349 }
350}
351
352impl TryInto<[f32; 4]> for &FieldValue {
353 type Error = FieldValueError;
354
355 fn try_into(self) -> Result<[f32; 4], FieldValueError> {
356 if let FieldValue::Vector4D(x) = self {
357 Ok(*x)
358 } else {
359 Err(FieldValueError::ConversionError(
360 format!("{:?}", self),
361 "[f32; 4]".to_string(),
362 ))
363 }
364 }
365}
366
367impl TryInto<(f32, f32, f32, f32)> for FieldValue {
368 type Error = FieldValueError;
369
370 fn try_into(self) -> Result<(f32, f32, f32, f32), FieldValueError> {
371 if let FieldValue::Vector4D(x) = self {
372 Ok(x.into())
373 } else {
374 Err(FieldValueError::ConversionError(
375 format!("{:?}", self),
376 "(f32, f32, f32, f32)".to_string(),
377 ))
378 }
379 }
380}
381
382impl TryInto<(f32, f32, f32, f32)> for &FieldValue {
383 type Error = FieldValueError;
384
385 fn try_into(self) -> Result<(f32, f32, f32, f32), FieldValueError> {
386 if let FieldValue::Vector4D(x) = self {
387 Ok((*x).into())
388 } else {
389 Err(FieldValueError::ConversionError(
390 format!("{:?}", self),
391 "(f32, f32, f32, f32)".to_string(),
392 ))
393 }
394 }
395}
396
397impl TryInto<Vec<f32>> for FieldValue {
398 type Error = FieldValueError;
399
400 fn try_into(self) -> Result<Vec<f32>, FieldValueError> {
401 match self {
402 FieldValue::Vector2D(x) => Ok(x.to_vec()),
403 FieldValue::Vector3D(x) => Ok(x.to_vec()),
404 FieldValue::Vector4D(x) => Ok(x.to_vec()),
405 _ => Err(FieldValueError::ConversionError(
406 format!("{:?}", self),
407 "Vec<f32>".to_string(),
408 )),
409 }
410 }
411}
412
413impl TryInto<Vec<f32>> for &FieldValue {
414 type Error = FieldValueError;
415
416 fn try_into(self) -> Result<Vec<f32>, FieldValueError> {
417 match self {
418 FieldValue::Vector2D(x) => Ok(x.to_vec()),
419 FieldValue::Vector3D(x) => Ok(x.to_vec()),
420 FieldValue::Vector4D(x) => Ok(x.to_vec()),
421 _ => Err(FieldValueError::ConversionError(
422 format!("{:?}", self),
423 "Vec<f32>".to_string(),
424 )),
425 }
426 }
427}
428
429impl TryInto<f32> for FieldValue {
430 type Error = FieldValueError;
431
432 fn try_into(self) -> Result<f32, FieldValueError> {
433 if let FieldValue::Float(x) = self {
434 Ok(x)
435 } else {
436 Err(FieldValueError::ConversionError(
437 format!("{:?}", self),
438 "f32".to_string(),
439 ))
440 }
441 }
442}
443
444impl TryInto<f32> for &FieldValue {
445 type Error = FieldValueError;
446
447 fn try_into(self) -> Result<f32, FieldValueError> {
448 if let FieldValue::Float(x) = self {
449 Ok(*x)
450 } else {
451 Err(FieldValueError::ConversionError(
452 format!("{:?}", self),
453 "f32".to_string(),
454 ))
455 }
456 }
457}
458
459impl TryInto<bool> for FieldValue {
460 type Error = FieldValueError;
461
462 fn try_into(self) -> Result<bool, FieldValueError> {
463 if let FieldValue::Boolean(x) = self {
464 Ok(x)
465 } else {
466 Err(FieldValueError::ConversionError(
467 format!("{:?}", self),
468 "bool".to_string(),
469 ))
470 }
471 }
472}
473
474impl TryInto<bool> for &FieldValue {
475 type Error = FieldValueError;
476
477 fn try_into(self) -> Result<bool, FieldValueError> {
478 if let FieldValue::Boolean(x) = self {
479 Ok(*x)
480 } else {
481 Err(FieldValueError::ConversionError(
482 format!("{:?}", self),
483 "bool".to_string(),
484 ))
485 }
486 }
487}
488
489macro_rules! impl_try_into_for_integers {
490 ($target:ty) => {
491 impl TryInto<$target> for FieldValue {
492 type Error = FieldValueError;
493
494 fn try_into(self) -> Result<$target, FieldValueError> {
495 match self {
496 FieldValue::Signed8(x) => {
498 Ok(TryInto::<$target>::try_into(x).map_err(|_| {
499 FieldValueError::ConversionError(
500 format!("{:?}", x),
501 stringify!($target).to_string(),
502 )
503 })?)
504 }
505 FieldValue::Signed16(x) => {
506 Ok(TryInto::<$target>::try_into(x).map_err(|_| {
507 FieldValueError::ConversionError(
508 format!("{:?}", x),
509 stringify!($target).to_string(),
510 )
511 })?)
512 }
513 FieldValue::Signed32(x) => {
514 Ok(TryInto::<$target>::try_into(x).map_err(|_| {
515 FieldValueError::ConversionError(
516 format!("{:?}", x),
517 stringify!($target).to_string(),
518 )
519 })?)
520 }
521 FieldValue::Signed64(x) => {
522 Ok(TryInto::<$target>::try_into(x).map_err(|_| {
523 FieldValueError::ConversionError(
524 format!("{:?}", x),
525 stringify!($target).to_string(),
526 )
527 })?)
528 }
529 FieldValue::Unsigned8(x) => {
530 Ok(TryInto::<$target>::try_into(x).map_err(|_| {
531 FieldValueError::ConversionError(
532 format!("{:?}", x),
533 stringify!($target).to_string(),
534 )
535 })?)
536 }
537 FieldValue::Unsigned16(x) => {
538 Ok(TryInto::<$target>::try_into(x).map_err(|_| {
539 FieldValueError::ConversionError(
540 format!("{:?}", x),
541 stringify!($target).to_string(),
542 )
543 })?)
544 }
545 FieldValue::Unsigned32(x) => {
546 Ok(TryInto::<$target>::try_into(x).map_err(|_| {
547 FieldValueError::ConversionError(
548 format!("{:?}", x),
549 stringify!($target).to_string(),
550 )
551 })?)
552 }
553 FieldValue::Unsigned64(x) => {
554 Ok(TryInto::<$target>::try_into(x).map_err(|_| {
555 FieldValueError::ConversionError(
556 format!("{:?}", x),
557 stringify!($target).to_string(),
558 )
559 })?)
560 }
561 FieldValue::Float(x) => Ok(x as $target),
562 _ => Err(FieldValueError::ConversionError(
563 format!("{:?}", self),
564 stringify!($target).to_string(),
565 )),
566 }
567 }
568 }
569
570 impl TryInto<$target> for &FieldValue {
571 type Error = FieldValueError;
572
573 fn try_into(self) -> Result<$target, FieldValueError> {
574 match self {
575 FieldValue::Signed8(x) => {
577 Ok(TryInto::<$target>::try_into(*x).map_err(|_| {
578 FieldValueError::ConversionError(
579 format!("{:?}", x),
580 stringify!($target).to_string(),
581 )
582 })?)
583 }
584 FieldValue::Signed16(x) => {
585 Ok(TryInto::<$target>::try_into(*x).map_err(|_| {
586 FieldValueError::ConversionError(
587 format!("{:?}", x),
588 stringify!($target).to_string(),
589 )
590 })?)
591 }
592 FieldValue::Signed32(x) => {
593 Ok(TryInto::<$target>::try_into(*x).map_err(|_| {
594 FieldValueError::ConversionError(
595 format!("{:?}", x),
596 stringify!($target).to_string(),
597 )
598 })?)
599 }
600 FieldValue::Signed64(x) => {
601 Ok(TryInto::<$target>::try_into(*x).map_err(|_| {
602 FieldValueError::ConversionError(
603 format!("{:?}", x),
604 stringify!($target).to_string(),
605 )
606 })?)
607 }
608 FieldValue::Unsigned8(x) => {
609 Ok(TryInto::<$target>::try_into(*x).map_err(|_| {
610 FieldValueError::ConversionError(
611 format!("{:?}", x),
612 stringify!($target).to_string(),
613 )
614 })?)
615 }
616 FieldValue::Unsigned16(x) => {
617 Ok(TryInto::<$target>::try_into(*x).map_err(|_| {
618 FieldValueError::ConversionError(
619 format!("{:?}", x),
620 stringify!($target).to_string(),
621 )
622 })?)
623 }
624 FieldValue::Unsigned32(x) => {
625 Ok(TryInto::<$target>::try_into(*x).map_err(|_| {
626 FieldValueError::ConversionError(
627 format!("{:?}", x),
628 stringify!($target).to_string(),
629 )
630 })?)
631 }
632 FieldValue::Unsigned64(x) => {
633 Ok(TryInto::<$target>::try_into(*x).map_err(|_| {
634 FieldValueError::ConversionError(
635 format!("{:?}", x),
636 stringify!($target).to_string(),
637 )
638 })?)
639 }
640 FieldValue::Float(x) => Ok(*x as $target),
641 _ => Err(FieldValueError::ConversionError(
642 format!("{:?}", self),
643 stringify!($target).to_string(),
644 )),
645 }
646 }
647 }
648 };
649}
650
651impl_try_into_for_integers!(i8);
652impl_try_into_for_integers!(i16);
653impl_try_into_for_integers!(i32);
654impl_try_into_for_integers!(i64);
655impl_try_into_for_integers!(i128);
656impl_try_into_for_integers!(u8);
657impl_try_into_for_integers!(u16);
658impl_try_into_for_integers!(u32);
659impl_try_into_for_integers!(u64);
660impl_try_into_for_integers!(u128);
661impl_try_into_for_integers!(usize);
662impl_try_into_for_integers!(isize);
663
664#[allow(dead_code)]
665impl FieldValue {
666 #[inline]
668 pub fn string(&self) -> String {
669 if let FieldValue::String(s) = self {
670 s.to_string()
671 } else {
672 panic!("Tried to read as String, Found {:?}", self);
673 }
674 }
675
676 #[inline]
678 pub fn bool(&self) -> bool {
679 if let FieldValue::Boolean(b) = self {
680 *b
681 } else {
682 panic!("Tried to read as Boolean, Found {:?}", self);
683 }
684 }
685
686 #[inline]
688 pub fn f32(&self) -> f32 {
689 if let FieldValue::Float(f) = self {
690 *f
691 } else {
692 panic!("Tried to read as Float, Found {:?}", self);
693 }
694 }
695
696 #[inline]
699 pub fn vec2(&self) -> &[f32; 2] {
700 if let FieldValue::Vector2D(v) = self {
701 v
702 } else {
703 panic!("Tried to read as Vector2D, Found {:?}", self);
704 }
705 }
706
707 #[inline]
710 pub fn vec3(&self) -> &[f32; 3] {
711 if let FieldValue::Vector3D(v) = self {
712 v
713 } else {
714 panic!("Tried to read as Vector3D, Found {:?}", self);
715 }
716 }
717
718 #[inline]
721 pub fn vec4(&self) -> &[f32; 4] {
722 if let FieldValue::Vector4D(v) = self {
723 v
724 } else {
725 panic!("Tried to read as Vector4D, Found {:?}", self);
726 }
727 }
728
729 #[inline]
731 pub fn i8(&self) -> i8 {
732 match self {
733 FieldValue::Signed8(x) => *x,
734 _ => panic!("Tried to read as i8, Found {:?}", self),
735 }
736 }
737
738 #[inline]
740 pub fn i16(&self) -> i16 {
741 match self {
742 FieldValue::Signed16(x) => *x,
743 _ => panic!("Tried to read as i16, Found {:?}", self),
744 }
745 }
746
747 #[inline]
749 pub fn i32(&self) -> i32 {
750 match self {
751 FieldValue::Signed32(x) => *x,
752 _ => panic!("Tried to read as i32, Found {:?}", self),
753 }
754 }
755
756 #[inline]
758 pub fn i64(&self) -> i64 {
759 match self {
760 FieldValue::Signed64(x) => *x,
761 _ => panic!("Tried to read as i64, Found {:?}", self),
762 }
763 }
764
765 #[inline]
767 pub fn u8(&self) -> u8 {
768 match self {
769 FieldValue::Unsigned8(x) => *x,
770 _ => panic!("Tried to read as u8, Found {:?}", self),
771 }
772 }
773
774 #[inline]
776 pub fn u16(&self) -> u16 {
777 match self {
778 FieldValue::Unsigned16(x) => *x,
779 _ => panic!("Tried to read as u16, Found {:?}", self),
780 }
781 }
782
783 #[inline]
785 pub fn u32(&self) -> u32 {
786 match self {
787 FieldValue::Unsigned32(x) => *x,
788 _ => panic!("Tried to read as u32, Found {:?}", self),
789 }
790 }
791
792 #[inline]
794 pub fn u64(&self) -> u64 {
795 match self {
796 FieldValue::Unsigned64(x) => *x,
797 _ => panic!("Tried to read as u64, Found {:?}", self),
798 }
799 }
800
801 #[inline]
804 pub fn usize(&self) -> usize {
805 match self {
806 FieldValue::Unsigned32(x) => *x as usize,
807 FieldValue::Unsigned64(x) => *x as usize,
808 _ => panic!("Tried to read as usize, Found {:?}", self),
809 }
810 }
811}