Skip to main content

vulkan_rust/
version.rs

1use core::fmt;
2
3/// Decoded Vulkan API version (major.minor.patch).
4///
5/// Vulkan packs versions into a `u32`: major (bits 31-22), minor (21-12),
6/// patch (11-0). This type provides named fields and a `Display` impl.
7///
8/// # Examples
9///
10/// ```
11/// use vulkan_rust::Version;
12///
13/// let v = Version::from_raw(0x00403000);
14/// assert_eq!(v.to_string(), "1.3.0");
15/// assert_eq!(v.to_raw(), 0x00403000);
16/// ```
17#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
18pub struct Version {
19    /// Major version number (bits 31-22 of the packed `u32`).
20    pub major: u32,
21    /// Minor version number (bits 21-12 of the packed `u32`).
22    pub minor: u32,
23    /// Patch version number (bits 11-0 of the packed `u32`).
24    pub patch: u32,
25}
26
27impl Version {
28    /// Create a version from major, minor, and patch components.
29    ///
30    /// ```
31    /// use vulkan_rust::Version;
32    ///
33    /// let v = Version::new(1, 3, 0);
34    /// assert_eq!(v.to_raw(), 0x00403000);
35    /// assert_eq!(v.to_string(), "1.3.0");
36    /// ```
37    pub const fn new(major: u32, minor: u32, patch: u32) -> Self {
38        Self {
39            major,
40            minor,
41            patch,
42        }
43    }
44
45    /// Decode a packed Vulkan version `u32` into its components.
46    ///
47    /// ```
48    /// use vulkan_rust::Version;
49    ///
50    /// let v = Version::from_raw(0x00403000); // Vulkan 1.3.0
51    /// assert_eq!(v.major, 1);
52    /// assert_eq!(v.minor, 3);
53    /// assert_eq!(v.patch, 0);
54    /// ```
55    pub const fn from_raw(raw: u32) -> Self {
56        Self {
57            major: raw >> 22,
58            minor: (raw >> 12) & 0x3FF,
59            patch: raw & 0xFFF,
60        }
61    }
62
63    /// Encode this version back into the packed `u32` representation.
64    ///
65    /// ```
66    /// use vulkan_rust::Version;
67    ///
68    /// let v = Version { major: 1, minor: 3, patch: 0 };
69    /// assert_eq!(v.to_raw(), 0x00403000);
70    /// ```
71    pub const fn to_raw(self) -> u32 {
72        (self.major << 22) | (self.minor << 12) | self.patch
73    }
74}
75
76impl fmt::Display for Version {
77    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78        write!(f, "{}.{}.{}", self.major, self.minor, self.patch)
79    }
80}
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85
86    #[test]
87    fn round_trip() {
88        let v = Version {
89            major: 1,
90            minor: 3,
91            patch: 250,
92        };
93        assert_eq!(Version::from_raw(v.to_raw()), v);
94    }
95
96    #[test]
97    fn from_raw_known_versions() {
98        // VK_API_VERSION_1_0 = VK_MAKE_API_VERSION(0, 1, 0, 0)
99        let v10 = Version::from_raw(1 << 22);
100        assert_eq!(
101            v10,
102            Version {
103                major: 1,
104                minor: 0,
105                patch: 0
106            }
107        );
108
109        // VK_API_VERSION_1_3 = 0x00403000
110        let v13 = Version::from_raw(0x00403000);
111        assert_eq!(
112            v13,
113            Version {
114                major: 1,
115                minor: 3,
116                patch: 0
117            }
118        );
119    }
120
121    #[test]
122    fn display_format() {
123        let v = Version {
124            major: 1,
125            minor: 2,
126            patch: 195,
127        };
128        assert_eq!(v.to_string(), "1.2.195");
129    }
130
131    #[test]
132    fn ordering() {
133        let v10 = Version {
134            major: 1,
135            minor: 0,
136            patch: 0,
137        };
138        let v12 = Version {
139            major: 1,
140            minor: 2,
141            patch: 0,
142        };
143        let v13 = Version {
144            major: 1,
145            minor: 3,
146            patch: 0,
147        };
148        assert!(v10 < v12);
149        assert!(v12 < v13);
150    }
151
152    #[test]
153    fn to_raw_known_versions() {
154        let v13 = Version {
155            major: 1,
156            minor: 3,
157            patch: 0,
158        };
159        assert_eq!(v13.to_raw(), 0x00403000);
160    }
161}