1 // Copyright (c) 2016 The vulkano developers 2 // Licensed under the Apache License, Version 2.0 3 // <LICENSE-APACHE or 4 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT 5 // license <LICENSE-MIT or https://opensource.org/licenses/MIT>, 6 // at your option. All files in the project carrying such 7 // notice may not be copied, modified, or distributed except 8 // according to those terms. 9 10 // The `Version` object is reexported from the `instance` module. 11 12 use std::{ 13 fmt::{Debug, Display, Error as FmtError, Formatter}, 14 num::ParseIntError, 15 str::FromStr, 16 }; 17 18 // Generated by build.rs 19 include!(concat!(env!("OUT_DIR"), "/version.rs")); 20 21 /// Represents an API version of Vulkan. 22 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] 23 pub struct Version { 24 /// Major version number. 25 pub major: u32, 26 /// Minor version number. 27 pub minor: u32, 28 /// Patch version number. 29 pub patch: u32, 30 } 31 32 impl Version { 33 pub const V1_0: Version = Version::major_minor(1, 0); 34 pub const V1_1: Version = Version::major_minor(1, 1); 35 pub const V1_2: Version = Version::major_minor(1, 2); 36 pub const V1_3: Version = Version::major_minor(1, 3); 37 pub const V1_4: Version = Version::major_minor(1, 4); 38 pub const V1_5: Version = Version::major_minor(1, 5); 39 pub const V1_6: Version = Version::major_minor(1, 6); 40 41 /// Constructs a `Version` from the given major and minor version numbers. 42 #[inline] major_minor(major: u32, minor: u32) -> Version43 pub const fn major_minor(major: u32, minor: u32) -> Version { 44 Version { 45 major, 46 minor, 47 patch: 0, 48 } 49 } 50 } 51 52 impl Default for Version { 53 #[inline] default() -> Self54 fn default() -> Self { 55 Self::V1_0 56 } 57 } 58 59 impl From<u32> for Version { 60 #[inline] from(val: u32) -> Self61 fn from(val: u32) -> Self { 62 Version { 63 major: ash::vk::api_version_major(val), 64 minor: ash::vk::api_version_minor(val), 65 patch: ash::vk::api_version_patch(val), 66 } 67 } 68 } 69 70 impl TryFrom<Version> for u32 { 71 type Error = (); 72 73 #[inline] try_from(val: Version) -> Result<Self, Self::Error>74 fn try_from(val: Version) -> Result<Self, Self::Error> { 75 if val.major <= 0x3ff && val.minor <= 0x3ff && val.patch <= 0xfff { 76 Ok(ash::vk::make_api_version( 77 0, val.major, val.minor, val.patch, 78 )) 79 } else { 80 Err(()) 81 } 82 } 83 } 84 85 impl FromStr for Version { 86 type Err = ParseIntError; 87 88 #[inline] from_str(s: &str) -> Result<Self, Self::Err>89 fn from_str(s: &str) -> Result<Self, Self::Err> { 90 let mut iter = s.splitn(3, '.'); 91 let major: u32 = iter.next().unwrap().parse()?; 92 let minor: u32 = iter.next().map_or(Ok(0), |n| n.parse())?; 93 let patch: u32 = iter.next().map_or(Ok(0), |n| n.parse())?; 94 95 Ok(Version { 96 major, 97 minor, 98 patch, 99 }) 100 } 101 } 102 103 impl Debug for Version { fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError>104 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { 105 write!(f, "{}.{}.{}", self.major, self.minor, self.patch) 106 } 107 } 108 109 impl Display for Version { 110 #[inline] fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError>111 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { 112 Debug::fmt(self, f) 113 } 114 } 115 116 #[cfg(test)] 117 mod tests { 118 use super::Version; 119 120 #[test] into_vk_version()121 fn into_vk_version() { 122 let version = Version { 123 major: 1, 124 minor: 0, 125 patch: 0, 126 }; 127 assert_eq!(u32::try_from(version).unwrap(), 0x400000); 128 } 129 130 #[test] greater_major()131 fn greater_major() { 132 let v1 = Version { 133 major: 1, 134 minor: 0, 135 patch: 0, 136 }; 137 let v2 = Version { 138 major: 2, 139 minor: 0, 140 patch: 0, 141 }; 142 assert!(v2 > v1); 143 } 144 145 #[test] greater_minor()146 fn greater_minor() { 147 let v1 = Version { 148 major: 1, 149 minor: 1, 150 patch: 0, 151 }; 152 let v2 = Version { 153 major: 1, 154 minor: 3, 155 patch: 0, 156 }; 157 assert!(v2 > v1); 158 } 159 160 #[test] greater_patch()161 fn greater_patch() { 162 let v1 = Version { 163 major: 1, 164 minor: 0, 165 patch: 4, 166 }; 167 let v2 = Version { 168 major: 1, 169 minor: 0, 170 patch: 5, 171 }; 172 assert!(v2 > v1); 173 } 174 175 #[test] version_parse()176 fn version_parse() { 177 assert!(matches!( 178 "1.1.1".parse::<Version>(), 179 Ok(Version { 180 major: 1, 181 minor: 1, 182 patch: 1, 183 }) 184 )); 185 assert!(matches!( 186 "1.1".parse::<Version>(), 187 Ok(Version { 188 major: 1, 189 minor: 1, 190 patch: 0, 191 }) 192 )); 193 assert!(matches!( 194 "1".parse::<Version>(), 195 Ok(Version { 196 major: 1, 197 minor: 0, 198 patch: 0, 199 }) 200 )); 201 202 assert!("".parse::<Version>().is_err()); 203 assert!("1.1.1.1".parse::<Version>().is_err()); 204 assert!("foobar".parse::<Version>().is_err()); 205 assert!("1.bar".parse::<Version>().is_err()); 206 } 207 } 208