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}