You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
3.5 KiB
120 lines
3.5 KiB
![]()
4 years ago
|
use crate::version::Version;
|
||
|
|
||
|
#[derive(Clone, Debug)]
|
||
|
pub enum UserVersion {
|
||
|
OnlyMajor(u64),
|
||
|
MajorMinor(u64, u64),
|
||
|
Full(Version),
|
||
|
}
|
||
|
|
||
|
impl UserVersion {
|
||
|
pub fn to_version<'a, T>(&self, available_versions: T) -> Option<&'a Version>
|
||
|
where
|
||
|
T: IntoIterator<Item = &'a Version>,
|
||
|
{
|
||
|
available_versions.into_iter().filter(|x| &self == x).max()
|
||
|
}
|
||
|
|
||
|
pub fn alias_name(&self) -> Option<String> {
|
||
|
match self {
|
||
|
Self::Full(version) => version.alias_name(),
|
||
|
_ => None,
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl PartialEq<Version> for UserVersion {
|
||
|
fn eq(&self, other: &Version) -> bool {
|
||
|
match (self, other) {
|
||
|
(Self::Full(a), b) if a == b => true,
|
||
|
(Self::Full(_), _) => false,
|
||
|
(_, Version::Bypassed) => false,
|
||
|
(_, Version::Lts(_)) => false,
|
||
|
(_, Version::Alias(_)) => false,
|
||
|
(Self::OnlyMajor(major), Version::Semver(other)) => *major == other.major,
|
||
|
(Self::MajorMinor(major, minor), Version::Semver(other)) => {
|
||
|
*major == other.major && *minor == other.minor
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn next_of<'a, T: std::str::FromStr, It: Iterator<Item = &'a str>>(i: &mut It) -> Option<T> {
|
||
|
let x = i.next()?;
|
||
|
T::from_str(x).ok()
|
||
|
}
|
||
|
|
||
|
impl std::fmt::Display for UserVersion {
|
||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||
|
match self {
|
||
|
Self::Full(x) => x.fmt(f),
|
||
|
Self::OnlyMajor(major) => write!(f, "v{}.x.x", major),
|
||
|
Self::MajorMinor(major, minor) => write!(f, "v{}.{}.x", major, minor),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl std::str::FromStr for UserVersion {
|
||
|
type Err = semver::SemVerError;
|
||
|
fn from_str(s: &str) -> Result<UserVersion, Self::Err> {
|
||
|
match Version::parse(s) {
|
||
|
Ok(v) => Ok(Self::Full(v)),
|
||
|
Err(e) => {
|
||
|
let mut parts = s.trim().split('.');
|
||
|
match (next_of::<u64, _>(&mut parts), next_of::<u64, _>(&mut parts)) {
|
||
|
(Some(major), None) => Ok(Self::OnlyMajor(major)),
|
||
|
(Some(major), Some(minor)) => Ok(Self::MajorMinor(major, minor)),
|
||
|
_ => Err(e),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[cfg(test)]
|
||
|
mod tests {
|
||
|
use super::*;
|
||
|
|
||
|
#[test]
|
||
|
fn test_major_to_version() {
|
||
|
let expected = Version::parse("6.1.0").unwrap();
|
||
|
let versions = vec![
|
||
|
Version::parse("6.0.0").unwrap(),
|
||
|
Version::parse("6.0.1").unwrap(),
|
||
|
expected.clone(),
|
||
|
Version::parse("7.0.1").unwrap(),
|
||
|
];
|
||
|
let result = UserVersion::OnlyMajor(6).to_version(&versions);
|
||
|
|
||
|
assert_eq!(result, Some(&expected));
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn test_major_minor_to_version() {
|
||
|
let expected = Version::parse("6.0.1").unwrap();
|
||
|
let versions = vec![
|
||
|
Version::parse("6.0.0").unwrap(),
|
||
|
Version::parse("6.1.0").unwrap(),
|
||
|
expected.clone(),
|
||
|
Version::parse("7.0.1").unwrap(),
|
||
|
];
|
||
|
let result = UserVersion::MajorMinor(6, 0).to_version(&versions);
|
||
|
|
||
|
assert_eq!(result, Some(&expected));
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn test_semver_to_version() {
|
||
|
let expected = Version::parse("6.0.0").unwrap();
|
||
|
let versions = vec![
|
||
|
expected.clone(),
|
||
|
Version::parse("6.1.0").unwrap(),
|
||
|
Version::parse("6.0.1").unwrap(),
|
||
|
Version::parse("7.0.1").unwrap(),
|
||
|
];
|
||
|
let result = UserVersion::Full(expected.clone()).to_version(&versions);
|
||
|
|
||
|
assert_eq!(result, Some(&expected));
|
||
|
}
|
||
|
}
|