use super::super::Version;
#[derive(Clone, Debug, PartialEq, Eq)]
pub(super) enum Bound {
Ge(Version),
Gt(Version),
Le(Version),
Lt(Version),
Eq(Version),
Ne(Version),
Compatible(Version),
Any,
None,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub(super) struct BoundSet {
pub(super) bounds: Vec<Bound>,
}
impl BoundSet {
pub(super) fn any() -> Self {
BoundSet {
bounds: vec![Bound::Any],
}
}
pub(super) fn none() -> Self {
BoundSet {
bounds: vec![Bound::None],
}
}
pub(super) fn contains(&self, version: &Version) -> bool {
for bound in &self.bounds {
if !bound_matches(bound, version) {
return false;
}
}
true
}
}
pub(super) fn bound_matches(bound: &Bound, version: &Version) -> bool {
match bound {
Bound::Any => true,
Bound::None => false,
Bound::Ge(v) => version >= v,
Bound::Gt(v) => version > v,
Bound::Le(v) => version <= v,
Bound::Lt(v) => version < v,
Bound::Eq(v) => version == v,
Bound::Ne(v) => version != v,
Bound::Compatible(v) => {
if version < v {
return false; }
let parts: Vec<&str> = v.as_str().split('.').collect();
if parts.len() < 2 {
return version >= v;
}
let upper_str = if parts.len() == 2 {
if let Ok(x) = parts[0].parse::<u64>() {
format!("{}.0", x + 1)
} else {
return true;
}
} else {
if let Ok(y) = parts[1].parse::<u64>() {
format!("{}.{}.0", parts[0], y + 1)
} else {
return true;
}
};
if let Ok(upper) = Version::parse(&upper_str) {
version < &upper
} else {
version >= v
}
}
}
}