use semver::VersionReq;
use std::cmp::Ordering;
use std::fmt::{Display, Formatter};
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct Version {
name: String,
version: String,
}
impl Version {
fn instance() -> Self {
let name = env!("CARGO_PKG_NAME");
let version = env!("CARGO_PKG_VERSION");
Self {
name: name.to_string(),
version: version.to_string(),
}
}
pub fn new(build: &str, version: &str) -> Self {
Self {
name: build.to_string(),
version: version.to_string(),
}
}
pub fn with_version(version: &str) -> Self {
Self::new(env!("CARGO_PKG_NAME"), version)
}
pub fn name(&self) -> &str {
&self.name
}
pub fn version(&self) -> &str {
&self.version
}
pub fn match_requirement(&self, req: &str) -> bool {
let req = VersionReq::parse(req)
.unwrap_or_else(|_| panic!("Invalid requirement string: {req:?}"));
let semver = semver::Version::parse(&self.version)
.unwrap_or_else(|_| panic!("Invalid version string: {:?}", self.version));
req.matches(&semver)
}
}
impl Display for Version {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "v{}", self.version)
}
}
pub fn version() -> Version {
Version::instance()
}
impl PartialOrd for Version {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
if self.name != other.name {
return None;
}
let this_version = semver::Version::parse(&self.version).ok()?;
let other_version = semver::Version::parse(&other.version).ok()?;
this_version.partial_cmp(&other_version)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn get_version_info() {
let version = version();
assert_eq!(version.name(), "assemble-core");
let semver = semver::Version::parse(version.version()).unwrap();
let added = semver::Version::new(0, 1, 2);
assert!(semver >= added);
}
}