havok_types/
pointer.rs

1//! Havok C++ Class unique number.
2//!
3//! - In XML, it takes the place of a pointer.
4//! - Not present in binary data.
5//!
6//! # Example
7//! - `#0457`
8//! - `#0007`
9use core::str::FromStr;
10use parse_display::Display;
11
12/// Havok C++ Class unique number.
13///
14/// It is automatically assigned as an index during XML deserialization.
15///
16/// - XML: Class pointer. (e.g. `#0050`)
17/// - hkx binary data: Not exist.
18///
19/// # Examples
20/// ```
21/// use havok_types::pointer::Pointer;
22///
23/// assert_eq!(Pointer::new(50).to_string(), "#0050");
24/// assert_eq!(Pointer::new(100).to_string(), "#0100");
25/// assert_eq!(Pointer::new(1000).to_string(), "#1000");
26/// assert_eq!(Pointer::new(10000).to_string(), "#10000");
27///
28/// assert_eq!("#0050".parse(), Ok(Pointer::new(50)));
29/// assert_eq!("#100".parse(),  Ok(Pointer::new(100)));
30/// assert_eq!("#1000".parse(), Ok(Pointer::new(1000)));
31/// assert_eq!("#10000".parse(),Ok(Pointer::new(10000)));
32/// ```
33///
34/// # Note
35/// The [`Copy`] is derive for [`usize`] wrapper type.
36#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
37#[cfg_attr(feature = "json_schema", schemars(transparent))]
38#[cfg_attr(
39    feature = "serde",
40    derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr)
41)]
42#[repr(transparent)]
43#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Display)]
44#[display("#{0:04}")]
45pub struct Pointer(#[cfg_attr(feature = "json_schema", schemars(with = "String"))] usize);
46
47impl Pointer {
48    /// Creates a new `Pointer`
49    #[inline]
50    pub const fn new(ptr: usize) -> Self {
51        Self(ptr)
52    }
53
54    /// Pointer(Class index) is null(`#0000`)?
55    #[inline]
56    pub const fn is_null(&self) -> bool {
57        self.0 == 0
58    }
59
60    /// Get inner value.
61    #[inline]
62    pub const fn get(&self) -> usize {
63        self.0
64    }
65}
66
67impl FromStr for Pointer {
68    type Err = &'static str;
69
70    #[inline]
71    fn from_str(s: &str) -> Result<Self, Self::Err> {
72        Ok(Self::new(
73            crate::parse_int::ParseNumber::parse(s.trim_start_matches('#'))
74                .map_err(|_err| "Invalid integer for Name")?,
75        ))
76    }
77}
78
79impl From<usize> for Pointer {
80    #[inline]
81    fn from(value: usize) -> Self {
82        Self(value)
83    }
84}
85
86impl From<Pointer> for usize {
87    #[inline]
88    fn from(value: Pointer) -> Self {
89        value.0
90    }
91}