| // Copyright (c) 2016 The vulkano developers | |
| // Licensed under the Apache License, Version 2.0 | |
| // <LICENSE-APACHE or | |
| // https://www.apache.org/licenses/LICENSE-2.0> or the MIT | |
| // license <LICENSE-MIT or https://opensource.org/licenses/MIT>, | |
| // at your option. All files in the project carrying such | |
| // notice may not be copied, modified, or distributed except | |
| // according to those terms. | |
| // The `Version` object is reexported from the `instance` module. | |
| use std::{ | |
| fmt::{Debug, Display, Error as FmtError, Formatter}, | |
| num::ParseIntError, | |
| str::FromStr, | |
| }; | |
| // Generated by build.rs | |
| include!(concat!(env!("OUT_DIR"), "/version.rs")); | |
| /// Represents an API version of Vulkan. | |
| #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] | |
| pub struct Version { | |
| /// Major version number. | |
| pub major: u32, | |
| /// Minor version number. | |
| pub minor: u32, | |
| /// Patch version number. | |
| pub patch: u32, | |
| } | |
| impl Version { | |
| pub const V1_0: Version = Version::major_minor(1, 0); | |
| pub const V1_1: Version = Version::major_minor(1, 1); | |
| pub const V1_2: Version = Version::major_minor(1, 2); | |
| pub const V1_3: Version = Version::major_minor(1, 3); | |
| pub const V1_4: Version = Version::major_minor(1, 4); | |
| pub const V1_5: Version = Version::major_minor(1, 5); | |
| pub const V1_6: Version = Version::major_minor(1, 6); | |
| /// Constructs a `Version` from the given major and minor version numbers. | |
| #[inline] | |
| pub const fn major_minor(major: u32, minor: u32) -> Version { | |
| Version { | |
| major, | |
| minor, | |
| patch: 0, | |
| } | |
| } | |
| } | |
| impl Default for Version { | |
| #[inline] | |
| fn default() -> Self { | |
| Self::V1_0 | |
| } | |
| } | |
| impl From<u32> for Version { | |
| #[inline] | |
| fn from(val: u32) -> Self { | |
| Version { | |
| major: ash::vk::api_version_major(val), | |
| minor: ash::vk::api_version_minor(val), | |
| patch: ash::vk::api_version_patch(val), | |
| } | |
| } | |
| } | |
| impl TryFrom<Version> for u32 { | |
| type Error = (); | |
| #[inline] | |
| fn try_from(val: Version) -> Result<Self, Self::Error> { | |
| if val.major <= 0x3ff && val.minor <= 0x3ff && val.patch <= 0xfff { | |
| Ok(ash::vk::make_api_version( | |
| 0, val.major, val.minor, val.patch, | |
| )) | |
| } else { | |
| Err(()) | |
| } | |
| } | |
| } | |
| impl FromStr for Version { | |
| type Err = ParseIntError; | |
| #[inline] | |
| fn from_str(s: &str) -> Result<Self, Self::Err> { | |
| let mut iter = s.splitn(3, '.'); | |
| let major: u32 = iter.next().unwrap().parse()?; | |
| let minor: u32 = iter.next().map_or(Ok(0), |n| n.parse())?; | |
| let patch: u32 = iter.next().map_or(Ok(0), |n| n.parse())?; | |
| Ok(Version { | |
| major, | |
| minor, | |
| patch, | |
| }) | |
| } | |
| } | |
| impl Debug for Version { | |
| fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { | |
| write!(f, "{}.{}.{}", self.major, self.minor, self.patch) | |
| } | |
| } | |
| impl Display for Version { | |
| #[inline] | |
| fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { | |
| Debug::fmt(self, f) | |
| } | |
| } | |
| #[cfg(test)] | |
| mod tests { | |
| use super::Version; | |
| #[test] | |
| fn into_vk_version() { | |
| let version = Version { | |
| major: 1, | |
| minor: 0, | |
| patch: 0, | |
| }; | |
| assert_eq!(u32::try_from(version).unwrap(), 0x400000); | |
| } | |
| #[test] | |
| fn greater_major() { | |
| let v1 = Version { | |
| major: 1, | |
| minor: 0, | |
| patch: 0, | |
| }; | |
| let v2 = Version { | |
| major: 2, | |
| minor: 0, | |
| patch: 0, | |
| }; | |
| assert!(v2 > v1); | |
| } | |
| #[test] | |
| fn greater_minor() { | |
| let v1 = Version { | |
| major: 1, | |
| minor: 1, | |
| patch: 0, | |
| }; | |
| let v2 = Version { | |
| major: 1, | |
| minor: 3, | |
| patch: 0, | |
| }; | |
| assert!(v2 > v1); | |
| } | |
| #[test] | |
| fn greater_patch() { | |
| let v1 = Version { | |
| major: 1, | |
| minor: 0, | |
| patch: 4, | |
| }; | |
| let v2 = Version { | |
| major: 1, | |
| minor: 0, | |
| patch: 5, | |
| }; | |
| assert!(v2 > v1); | |
| } | |
| #[test] | |
| fn version_parse() { | |
| assert!(matches!( | |
| "1.1.1".parse::<Version>(), | |
| Ok(Version { | |
| major: 1, | |
| minor: 1, | |
| patch: 1, | |
| }) | |
| )); | |
| assert!(matches!( | |
| "1.1".parse::<Version>(), | |
| Ok(Version { | |
| major: 1, | |
| minor: 1, | |
| patch: 0, | |
| }) | |
| )); | |
| assert!(matches!( | |
| "1".parse::<Version>(), | |
| Ok(Version { | |
| major: 1, | |
| minor: 0, | |
| patch: 0, | |
| }) | |
| )); | |
| assert!("".parse::<Version>().is_err()); | |
| assert!("1.1.1.1".parse::<Version>().is_err()); | |
| assert!("foobar".parse::<Version>().is_err()); | |
| assert!("1.bar".parse::<Version>().is_err()); | |
| } | |
| } |