pub struct ConstraintSet { /* private fields */ }Expand description
A collection of version constraints that must all be satisfied simultaneously.
ConstraintSet manages multiple VersionConstraints for a single dependency,
ensuring that all constraints are compatible and can be resolved together.
It provides conflict detection, version matching, and best-match selection.
§Constraint Combination
When multiple constraints are added to a set, they create an intersection of requirements. For example:
>=1.0.0AND<2.0.0= versions in range[1.0.0, 2.0.0)^1.0.0AND~1.2.0= versions compatible with both (e.g.,1.2.x)
§Conflict Detection
The constraint set detects and prevents conflicting constraints:
- Multiple exact versions:
1.0.0AND2.0.0(impossible to satisfy) - Conflicting Git refs:
mainANDdevelop(can’t be both branches)
§Resolution Strategy
When selecting from available versions, the set:
- Filters versions that satisfy ALL constraints
- Excludes prereleases unless explicitly allowed
- Selects the highest remaining version
§Examples
§Basic Usage
use agpm_cli::version::constraints::{ConstraintSet, VersionConstraint};
use semver::Version;
let mut set = ConstraintSet::new();
set.add(VersionConstraint::parse(">=1.0.0")?)?;
set.add(VersionConstraint::parse("<2.0.0")?)?;
let version = Version::parse("1.5.0")?;
assert!(set.satisfies(&version));
let version = Version::parse("2.0.0")?;
assert!(!set.satisfies(&version)); // Outside range§Best Match Selection
use agpm_cli::version::constraints::{ConstraintSet, VersionConstraint};
use semver::Version;
let mut set = ConstraintSet::new();
set.add(VersionConstraint::parse("^1.0.0")?)?;
let versions = vec![
Version::parse("0.9.0")?, // Too old
Version::parse("1.0.0")?, // Matches
Version::parse("1.5.0")?, // Matches, higher
Version::parse("2.0.0")?, // Too new
];
let best = set.find_best_match(&versions).unwrap();
assert_eq!(best, &Version::parse("1.5.0")?); // Highest compatible§Conflict Detection
use agpm_cli::version::constraints::{ConstraintSet, VersionConstraint};
use semver::Version;
let mut set = ConstraintSet::new();
set.add(VersionConstraint::parse("1.0.0")?)?; // Exact version
// This will fail - can't have two different exact versions
let result = set.add(VersionConstraint::parse("2.0.0")?);
assert!(result.is_err());Implementations§
Source§impl ConstraintSet
impl ConstraintSet
Sourcepub fn add(&mut self, constraint: VersionConstraint) -> Result<()>
pub fn add(&mut self, constraint: VersionConstraint) -> Result<()>
Add a constraint to this set with conflict detection.
This method adds a new constraint to the set after checking for conflicts with existing constraints. If the new constraint would create an impossible situation (like requiring two different exact versions), an error is returned.
§Arguments
constraint- TheVersionConstraintto add to this set
§Returns
Returns Ok(()) if the constraint was added successfully, or Err if it
conflicts with existing constraints.
§Conflict Detection
Current conflict detection covers:
- Exact version conflicts: Different exact versions for the same dependency
- Git ref conflicts: Different Git references for the same dependency
Future versions may add more sophisticated conflict detection for semantic version ranges.
§Examples
use agpm_cli::version::constraints::{ConstraintSet, VersionConstraint};
let mut set = ConstraintSet::new();
// These constraints are compatible
set.add(VersionConstraint::parse(">=1.0.0")?)?;
set.add(VersionConstraint::parse("<2.0.0")?)?;
// This would conflict with exact versions
set.add(VersionConstraint::parse("1.5.0")?)?;
let result = set.add(VersionConstraint::parse("1.6.0")?);
assert!(result.is_err()); // Conflict: can't be both 1.5.0 AND 1.6.0Sourcepub fn satisfies(&self, version: &Version) -> bool
pub fn satisfies(&self, version: &Version) -> bool
Check if a version satisfies all constraints in this set.
This method tests whether a given version passes all the constraints in this set. For a version to be acceptable, it must satisfy every single constraint - this represents a logical AND operation.
§Arguments
version- The semantic version to test against all constraints
§Returns
Returns true if the version satisfies ALL constraints, false if it
fails to satisfy any constraint.
§Examples
use agpm_cli::version::constraints::{ConstraintSet, VersionConstraint};
use semver::Version;
let mut set = ConstraintSet::new();
set.add(VersionConstraint::parse(">=1.0.0")?)?; // Must be at least 1.0.0
set.add(VersionConstraint::parse("<2.0.0")?)?; // Must be less than 2.0.0
set.add(VersionConstraint::parse("^1.0.0")?)?; // Must be compatible with 1.0.0
assert!(set.satisfies(&Version::parse("1.5.0")?)); // Satisfies all three
assert!(!set.satisfies(&Version::parse("0.9.0")?)); // Fails >=1.0.0
assert!(!set.satisfies(&Version::parse("2.0.0")?)); // Fails <2.0.0§Performance Note
This method short-circuits on the first constraint that fails, making it efficient even with many constraints.
Sourcepub fn find_best_match<'a>(
&self,
versions: &'a [Version],
) -> Option<&'a Version>
pub fn find_best_match<'a>( &self, versions: &'a [Version], ) -> Option<&'a Version>
Find the best matching version from a list of available versions.
This method filters provided versions to find those that satisfy all constraints, then selects the “best” match according to AGPM’s resolution strategy. The selection prioritizes newer versions while respecting prerelease preferences.
§Resolution Strategy
- Filter candidates: Keep only versions that satisfy all constraints
- Sort by version: Order candidates from highest to lowest version
- Apply prerelease policy: Remove prereleases unless explicitly allowed
- Select best: Return the highest remaining version
§Arguments
versions- Slice of available versions to choose from
§Returns
Returns Some(&Version) with the best matching version, or None if no
version satisfies all constraints.
§Examples
use agpm_cli::version::constraints::{ConstraintSet, VersionConstraint};
use semver::Version;
let mut set = ConstraintSet::new();
set.add(VersionConstraint::parse("^1.0.0")?)?;
let versions = vec![
Version::parse("0.9.0")?, // Too old
Version::parse("1.0.0")?, // Compatible
Version::parse("1.2.0")?, // Compatible, newer
Version::parse("1.5.0")?, // Compatible, newest
Version::parse("2.0.0")?, // Too new
];
let best = set.find_best_match(&versions).unwrap();
assert_eq!(best, &Version::parse("1.5.0")?); // Highest compatible version§Prerelease Handling
use agpm_cli::version::constraints::{ConstraintSet, VersionConstraint};
use semver::Version;
let mut set = ConstraintSet::new();
set.add(VersionConstraint::parse("^1.0.0")?)?; // Doesn't allow prereleases
let versions = vec![
Version::parse("1.0.0")?,
Version::parse("1.1.0-alpha.1")?, // Prerelease
Version::parse("1.1.0")?, // Stable
];
let best = set.find_best_match(&versions).unwrap();
assert_eq!(best, &Version::parse("1.1.0")?); // Stable version preferredSourcepub fn allows_prerelease(&self) -> bool
pub fn allows_prerelease(&self) -> bool
Check if any constraint in this set allows prerelease versions.
This method determines the prerelease policy for the entire constraint set.
If ANY constraint in the set allows prereleases, the entire set is considered
to allow prereleases. This ensures that explicit prerelease constraints
(like latest-prerelease or Git refs) are respected.
§Returns
Returns true if any constraint allows prereleases, false if all constraints
exclude prereleases.
§Examples
use agpm_cli::version::constraints::{ConstraintSet, VersionConstraint};
let mut stable_set = ConstraintSet::new();
stable_set.add(VersionConstraint::parse("^1.0.0")?)?;
stable_set.add(VersionConstraint::parse("~1.2.0")?)?;
assert!(!stable_set.allows_prerelease()); // All constraints exclude prereleases
let mut prerelease_set = ConstraintSet::new();
prerelease_set.add(VersionConstraint::parse("^1.0.0")?)?;
prerelease_set.add(VersionConstraint::parse("main")?)?; // Git ref allows prereleases
assert!(prerelease_set.allows_prerelease()); // One constraint allows prereleases§Impact on Resolution
This setting affects find_best_match behavior:
- If
false: Prerelease versions are filtered out before selection - If
true: Prerelease versions are included in selection
Trait Implementations§
Source§impl Clone for ConstraintSet
impl Clone for ConstraintSet
Source§fn clone(&self) -> ConstraintSet
fn clone(&self) -> ConstraintSet
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ConstraintSet
impl Debug for ConstraintSet
Auto Trait Implementations§
impl Freeze for ConstraintSet
impl RefUnwindSafe for ConstraintSet
impl Send for ConstraintSet
impl Sync for ConstraintSet
impl Unpin for ConstraintSet
impl UnwindSafe for ConstraintSet
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more