From d9eae8da3a85ba50e665e9dde59cff060be6869c Mon Sep 17 00:00:00 2001 From: David Runge <dvzrv@archlinux.org> Date: Sun, 28 May 2023 17:48:01 +0200 Subject: [PATCH 1/3] feat: Derive Architecture from Ord and PartialOrd to allow comparison. --- src/system.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/system.rs b/src/system.rs index 60acf12..10fc5f8 100644 --- a/src/system.rs +++ b/src/system.rs @@ -31,7 +31,7 @@ use strum_macros::EnumString; /// assert_eq!("x86_64_v3", format!("{}", Architecture::X86_64V3)); /// assert_eq!("x86_64_v4", format!("{}", Architecture::X86_64V4)); /// ``` -#[derive(Debug, Display, EnumString, Eq, PartialEq)] +#[derive(Debug, Display, EnumString, Eq, Ord, PartialEq, PartialOrd)] #[non_exhaustive] pub enum Architecture { #[strum(to_string = "aarch64")] -- GitLab From 25b1001d99e9c2fa8d82140471c1f22118311bf1 Mon Sep 17 00:00:00 2001 From: David Runge <dvzrv@archlinux.org> Date: Tue, 30 May 2023 20:59:24 +0200 Subject: [PATCH 2/3] feat(Version): Add method to create Version with Pkgrel Add `with_pkgrel()` to create a new `Version` which is guaranteed to have a `Pkgrel`. --- README.md | 4 ++++ src/version.rs | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/README.md b/README.md index e290313..ab01fce 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,10 @@ let version_a = Version::new("1.0.0").unwrap(); let version_b = Version::new("1.1.0").unwrap(); assert_eq!(Version::vercmp(&version_a, &version_b), -1); + +// create a Version that is guaranteed to have a Pkgrel +assert!(Version::with_pkgrel("1.0.0-1").is_ok()); +assert!(Version::with_pkgrel("1.0.0").is_err()); ``` ## Contributing diff --git a/src/version.rs b/src/version.rs index f3af4e2..c731bc3 100644 --- a/src/version.rs +++ b/src/version.rs @@ -482,6 +482,14 @@ impl Version { }) } + /// Create a new Version, which is guaranteed to have a Pkgrel + pub fn with_pkgrel(version: &str) -> Result<Self, Error> { + match Version::new(version) { + Ok(version) if version.pkgrel().is_some() => Ok(version), + _ => Err(Error::InvalidVersion(version.to_string())), + } + } + /// Return the optional reference to the Epoch of the Version pub fn epoch(&self) -> Option<&Epoch> { self.epoch.as_ref() @@ -649,6 +657,20 @@ mod tests { } } + #[rstest] + #[case( + "1.0.0-1", + Ok(Version{ + pkgver: Pkgver::new("1.0.0".to_string()).unwrap(), + pkgrel: Some(Pkgrel::new("1".to_string()).unwrap()), + epoch: None, + }) + )] + #[case("1.0.0", Err(Error::InvalidVersion("1.0.0".to_string())))] + fn version_with_pkgrel(#[case] version: &str, #[case] result: Result<Version, Error>) { + assert_eq!(result, Version::with_pkgrel(version)); + } + #[rstest] #[case("1".to_string(), Ok(Epoch(NonZeroUsize::new(1).unwrap())))] #[case("0".to_string(), Err(Error::InvalidEpoch("0".to_string())))] -- GitLab From 6276f82eb10edc368dce441a94962246097f4b8d Mon Sep 17 00:00:00 2001 From: David Runge <dvzrv@archlinux.org> Date: Sun, 28 May 2023 17:48:20 +0200 Subject: [PATCH 3/3] feat: Implement BuildToolVer type Implement `BuildToolVer` which tracks a `Version` (that is guaranteed to have a `Pkgrel`) and an `Architecture` and can be used to denote this information for a given `BuildTool`. --- README.md | 10 ++++++ src/error.rs | 6 ++++ src/lib.rs | 1 + src/version.rs | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+) diff --git a/README.md b/README.md index ab01fce..8dc879d 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,16 @@ assert_eq!(PkgType::from_str("pkg"), Ok(PkgType::Package)); ### Version +The version and CPU architecture of a build tool is tracked using `BuildToolVer`: + +```rust +use alpm_types::BuildToolVer; + +let buildtoolver = BuildToolVer::new("1.0.0-1-any").unwrap(); + +assert_eq!("1.0.0-1-any", format!("{}", buildtoolver)); +``` + Schemas of compound types (e.g. those used to describe `.BUILDINFO` or `.PKGINFO` files) need a schema version to version their features. This is what `SchemaVersion` is for: ```rust diff --git a/src/error.rs b/src/error.rs index ff7f681..a00334e 100644 --- a/src/error.rs +++ b/src/error.rs @@ -6,6 +6,9 @@ use thiserror::Error; #[derive(Debug, Error, PartialEq)] #[non_exhaustive] pub enum Error { + /// An invalid CPU architecture + #[error("Invalid architecture: {0}")] + InvalidArchitecture(String), /// An invalid build date (in seconds since the epoch) #[error("Invalid build date: {0}")] InvalidBuildDate(String), @@ -18,6 +21,9 @@ pub enum Error { /// An invalid BuildTool #[error("Invalid buildtool: {0}")] InvalidBuildTool(String), + /// An invalid BuildToolVer + #[error("Invalid buildtool version: {0}")] + InvalidBuildToolVer(String), /// An invalid compressed file size (in bytes) #[error("Invalid compressed size: {0}")] InvalidCompressedSize(String), diff --git a/src/lib.rs b/src/lib.rs index eff1ba3..0127c8a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,6 +40,7 @@ mod system; pub use system::Architecture; mod version; +pub use version::BuildToolVer; pub use version::Epoch; pub use version::Pkgrel; pub use version::Pkgver; diff --git a/src/version.rs b/src/version.rs index c731bc3..d39ccb5 100644 --- a/src/version.rs +++ b/src/version.rs @@ -9,8 +9,71 @@ use std::str::FromStr; use semver::Version as SemverVersion; use crate::regex_once; +use crate::Architecture; use crate::Error; +/// The version and architecture of a build tool +/// +/// `BuildToolVer` is used in conjunction with `BuildTool` to denote the specific build tool a package is built with. +/// A `BuildToolVer` wraps a `Version` (that is guaranteed to have a `Pkgrel`) and an `Architecture`. +/// +/// ## Examples +/// ``` +/// use alpm_types::BuildToolVer; +/// +/// assert!(BuildToolVer::new("1-1-any").is_ok()); +/// assert!(BuildToolVer::new("1").is_err()); +/// assert!(BuildToolVer::new("1-1-foo").is_err()); +/// ``` +#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)] +pub struct BuildToolVer { + version: Version, + architecture: Architecture, +} + +impl BuildToolVer { + /// Create a new BuildToolVer and return it in a Result + pub fn new(buildtoolver: &str) -> Result<Self, Error> { + match buildtoolver.rsplit_once('-') { + Some((version, architecture)) => { + if let Ok(architecture) = Architecture::from_str(architecture) { + Ok(BuildToolVer { + version: Version::with_pkgrel(version)?, + architecture, + }) + } else { + Err(Error::InvalidArchitecture(architecture.to_string())) + } + } + None => Err(Error::InvalidBuildToolVer(buildtoolver.to_string())), + } + } + + /// Return a reference to the Architecture + pub fn architecture(&self) -> &Architecture { + &self.architecture + } + + /// Return a reference to the Version + pub fn version(&self) -> &Version { + &self.version + } +} + +impl FromStr for BuildToolVer { + type Err = Error; + /// Create an BuildToolVer from a string and return it in a Result + fn from_str(input: &str) -> Result<Self, Self::Err> { + BuildToolVer::new(input) + } +} + +impl Display for BuildToolVer { + fn fmt(&self, fmt: &mut Formatter) -> std::fmt::Result { + write!(fmt, "{}-{}", self.version, self.architecture) + } +} + /// An epoch of a package /// /// Epoch is used to indicate the downgrade of a package and is prepended to a version, delimited by a `":"` (e.g. `1:` @@ -604,6 +667,35 @@ mod tests { assert_eq!(result, SchemaVersion::new(version)) } + #[rstest] + #[case( + "1.0.0-1-any", + Ok(BuildToolVer{version: Version::new("1.0.0-1").unwrap(), architecture: Architecture::from_str("any").unwrap()}), + )] + #[case( + "1:1.0.0-1-any", + Ok(BuildToolVer{version: Version::new("1:1.0.0-1").unwrap(), architecture: Architecture::from_str("any").unwrap()}), + )] + #[case( + "1.0.0", + Err(Error::InvalidBuildToolVer("1.0.0".to_string())), + )] + #[case( + "1.0.0-any", + Err(Error::InvalidVersion("1.0.0".to_string())), + )] + #[case( + ".1.0.0-1-any", + Err(Error::InvalidVersion(".1.0.0-1".to_string())), + )] + #[case( + "1.0.0-1-foo", + Err(Error::InvalidArchitecture("foo".to_string())), + )] + fn buildtoolver_new(#[case] buildtoolver: &str, #[case] result: Result<BuildToolVer, Error>) { + assert_eq!(BuildToolVer::new(buildtoolver), result); + } + #[rstest] #[case( SchemaVersion(SemverVersion::new(1, 0, 0)), -- GitLab