///|
/// Does the version satisfy this one comparator, ignoring the prerelease policy?
fn comparator_satisfies(c : Comparator, v : Version) -> Bool {
let d = v.precedence_cmp(c.version)
match c.op {
Eq => d == 0
Ne => d != 0
Gt => d > 0
Ge => d >= 0
Lt => d < 0
Le => d <= 0
}
}
///|
/// Does the version satisfy this comparator set, prerelease policy included?
fn comparator_set_satisfies(
set : ComparatorSet,
v : Version,
policy : PrereleasePolicy,
) -> Bool {
if v.is_prerelease() {
match policy {
Never => return false
SameTuple => {
// npm and Cargo: at least one comparator must carry a prerelease
// whose major.minor.patch matches the version under test.
let mut anchored = false
for c in set.comparators {
if c.version.is_prerelease() && c.version.same_core(v) {
anchored = true
}
}
if !anchored {
return false
}
}
Always => ()
}
}
for c in set.comparators {
if !comparator_satisfies(c, v) {
return false
}
}
true
}
///|
/// Does the version fall inside the range?
///
/// The prerelease policy comes from the `Syntax` used to parse the range.
pub fn Range::satisfies(self : Range, version : Version) -> Bool {
self.satisfies_with(version, self.policy)
}
///|
/// Does the version fall inside the range, with the policy overridden for this call?
pub fn Range::satisfies_with(
self : Range,
version : Version,
policy : PrereleasePolicy,
) -> Bool {
for set in self.sets {
if comparator_set_satisfies(set, version, policy) {
return true
}
}
false
}
///|
/// The highest satisfying version, by precedence, with build metadata breaking ties.
pub fn Range::max_satisfying(
self : Range,
versions : Array[Version],
) -> Version? {
let mut best : Version? = None
for v in versions {
if self.satisfies(v) {
match best {
None => best = Some(v)
Some(b) => if v.compare(b) > 0 { best = Some(v) }
}
}
}
best
}
///|
/// The lowest satisfying version.
pub fn Range::min_satisfying(
self : Range,
versions : Array[Version],
) -> Version? {
let mut best : Version? = None
for v in versions {
if self.satisfies(v) {
match best {
None => best = Some(v)
Some(b) => if v.compare(b) < 0 { best = Some(v) }
}
}
}
best
}
///|
/// Every satisfying version, sorted ascending by precedence.
pub fn Range::satisfying(
self : Range,
versions : Array[Version],
) -> Array[Version] {
let out : Array[Version] = []
for v in versions {
if self.satisfies(v) {
out.push(v)
}
}
out.sort()
out
}
///|
/// Convenience wrapper: parse two strings and check whether the version satisfies.
///
/// Both strings are read with the same grammar, the version through `Version::parse`.
pub fn satisfies(
version : String,
range : String,
syntax~ : Syntax = Syntax::npm(),
) -> Bool raise Refused {
Range::parse(range, syntax~).satisfies(Version::parse(version, syntax~))
}