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