Skip to main content

source2_demo/entity/field/
value.rs

1//! Field value types and conversions.
2//!
3//! This module defines the [`FieldValue`] enum which represents all possible
4//! types that entity properties can have.
5
6use crate::error::FieldValueError;
7
8/// Value type for entity properties.
9///
10/// This enum represents all possible types that can be stored in entity
11/// properties. Use [`TryInto`] to convert to Rust types, or use the `property!`
12/// macro for convenient access.
13///
14/// # Variants
15///
16/// - Numeric types: `i8`, `i16`, `i32`, `i64`, `u8`, `u16`, `u32`, `u64`
17/// - Floating point: `f32`
18/// - Text: `String`
19/// - Vectors: 2D, 3D, and 4D float arrays
20/// - Boolean: `bool`
21///
22/// # Examples
23///
24/// ## Manual conversion
25///
26/// ```no_run
27/// use source2_demo::prelude::*;
28///
29/// # fn example(entity: &Entity) -> anyhow::Result<()> {
30/// let field_value = entity.get_property_by_name("m_iHealth")?;
31/// let health: i32 = field_value.try_into()?;
32/// println!("Health: {}", health);
33/// # Ok(())
34/// # }
35/// ```
36///
37/// ## Using property! macro
38///
39/// ```no_run
40/// use source2_demo::prelude::*;
41///
42/// # fn example(entity: &Entity) -> anyhow::Result<()> {
43/// // Type is inferred
44/// let health: i32 = property!(entity, "m_iHealth");
45/// # Ok(())
46/// # }
47/// ```
48#[derive(Debug, Clone, PartialEq)]
49pub enum FieldValue {
50    /// Boolean value
51    Boolean(bool),
52    /// String value
53    String(String),
54    /// 32-bit floating point value
55    Float(f32),
56
57    /// 2D vector
58    Vector2D([f32; 2]),
59    /// 3D vector
60    Vector3D([f32; 3]),
61    /// 4D vector
62    Vector4D([f32; 4]),
63
64    /// Signed 8-bit integer
65    Signed8(i8),
66    /// Signed 16-bit integer
67    Signed16(i16),
68    /// Signed 32-bit integer
69    Signed32(i32),
70    /// Signed 64-bit integer
71    Signed64(i64),
72
73    /// Unsigned 8-bit integer
74    Unsigned8(u8),
75    /// Unsigned 16-bit integer
76    Unsigned16(u16),
77    /// Unsigned 32-bit integer
78    Unsigned32(u32),
79    /// Unsigned 64-bit integer
80    Unsigned64(u64),
81}
82
83/// Converts ordinary Rust values into [`FieldValue`] replacements.
84pub trait IntoFieldValue {
85    /// Converts this value into a [`FieldValue`].
86    fn into_field_value(self) -> FieldValue;
87}
88
89/// Converts a field rewrite handler result into an optional replacement.
90///
91/// Returning a plain value replaces the field. Returning `Option<T>` allows a
92/// handler to keep the original field by returning `None`.
93pub trait FieldRewriteResult {
94    /// Converts this handler result into an optional [`FieldValue`].
95    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                    // EntityFieldType::Boolean(x) => Ok((x == 1) as $target),
497                    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                    // EntityFieldType::Boolean(x) => Ok(x == 1 as $target),
576                    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    /// Return the inner string. Panics if this is not a `FieldValue::String`.
667    #[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    /// Return the inner boolean. Panics if this is not a `FieldValue::Boolean`.
677    #[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    /// Return the inner f32. Panics if this is not a `FieldValue::Float`.
687    #[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    /// Return a reference to a 2D vector ([f32; 2]). Panics if the value is not
697    /// `Vector2D`.
698    #[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    /// Return a reference to a 3D vector ([f32; 3]). Panics if the value is not
708    /// `Vector3D`.
709    #[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    /// Return a reference to a 4D vector ([f32; 4]). Panics if the value is not
719    /// `Vector4D`.
720    #[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    /// Read as signed 8-bit integer. Panics if value is not `Signed8`.
730    #[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    /// Read as signed 16-bit integer. Panics if value is not `Signed16`.
739    #[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    /// Read as signed 32-bit integer. Panics if value is not `Signed32`.
748    #[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    /// Read as signed 64-bit integer. Panics if value is not `Signed64`.
757    #[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    /// Read as unsigned 8-bit integer. Panics if value is not `Unsigned8`.
766    #[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    /// Read as unsigned 16-bit integer. Panics if value is not `Unsigned16`.
775    #[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    /// Read as unsigned 32-bit integer. Panics if value is not `Unsigned32`.
784    #[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    /// Read as unsigned 64-bit integer. Panics if value is not `Unsigned64`.
793    #[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    /// Read as `usize`. Accepts `Unsigned32` or `Unsigned64` and casts to
802    /// `usize`. Panics for other variants.
803    #[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}