pub enum VersionConstraint {
Exact {
prefix: Option<String>,
version: Version,
},
Requirement {
prefix: Option<String>,
req: VersionReq,
},
GitRef(String),
}Expand description
A version constraint that defines acceptable versions for a dependency.
Version constraints in AGPM support multiple formats to handle different versioning strategies and Git-based dependencies. Each constraint type provides specific matching behavior for version resolution.
§Constraint Types
Exact: Matches exactly one specific semantic versionRequirement: Matches versions using semver rangesGitRef: Matches specific Git branches, tags, or commit hashes (including “latest”)
§Examples
use agpm_cli::version::constraints::VersionConstraint;
use semver::Version;
// Parse various constraint formats
let exact = VersionConstraint::parse("1.0.0")?;
let caret = VersionConstraint::parse("^1.0.0")?; // Compatible versions
let tilde = VersionConstraint::parse("~1.2.0")?; // Patch-level compatible
let range = VersionConstraint::parse(">=1.0.0, <2.0.0")?; // Version range
let branch = VersionConstraint::parse("main")?;
let latest_tag = VersionConstraint::parse("latest")?; // Just a tag name
let commit = VersionConstraint::parse("abc123def")?;
// Test version matching
let version = Version::parse("1.2.3")?;
assert!(caret.matches(&version));§Prerelease Handling
By default, most constraints exclude prerelease versions to ensure stability:
GitRefconstraints (including “latest” tag names) may reference any commit
§Git Reference Matching
Git references are matched by name rather than semantic version:
- Branch names:
"main","develop","feature/auth" - Tag names:
"v1.0.0","release-2023-01" - Commit hashes:
"abc123def456"(full or abbreviated)
§Prefix Support (Monorepo Versioning)
Constraints can include optional prefixes for monorepo-style versioning:
"agents-v1.0.0": Exact version with prefix"agents-^v1.0.0": Compatible version range with prefix- Prefixed constraints only match tags with the same prefix
Variants§
Exact
Exact version match with optional prefix (e.g., “1.0.0”, “agents-v1.0.0”)
Requirement
Semantic version requirement with optional prefix (e.g., “^1.0.0”, “agents-^v1.0.0”)
GitRef(String)
Git tag or branch name (including “latest” - it’s just a tag name)
Implementations§
Source§impl VersionConstraint
impl VersionConstraint
Sourcepub fn parse(constraint: &str) -> Result<Self>
pub fn parse(constraint: &str) -> Result<Self>
Parse a constraint string into a VersionConstraint.
This method intelligently determines the constraint type based on the input format. It handles various syntaxes including semantic versions, version ranges, special keywords, and Git references.
§Parsing Logic
- Special keywords:
"*"(wildcard for any version) - Exact versions:
"1.0.0","v1.0.0"(without range operators) - Version requirements:
"^1.0.0","~1.2.0",">=1.0.0","<2.0.0" - Git references: Any string that doesn’t match the above patterns (including “latest”)
§Arguments
constraint- The constraint string to parse (whitespace is trimmed)
§Returns
Returns Ok(VersionConstraint) on successful parsing, or Err if the
semantic version parsing fails (Git references always succeed).
§Examples
use agpm_cli::version::constraints::VersionConstraint;
// Exact version matching
let exact = VersionConstraint::parse("1.0.0")?;
let exact_with_v = VersionConstraint::parse("v1.0.0")?;
// Semantic version ranges
let caret = VersionConstraint::parse("^1.0.0")?; // 1.x.x compatible
let tilde = VersionConstraint::parse("~1.2.0")?; // 1.2.x compatible
let gte = VersionConstraint::parse(">=1.0.0")?; // Greater or equal
let range = VersionConstraint::parse(">1.0.0, <2.0.0")?; // Range
// Special keywords
let any = VersionConstraint::parse("*")?; // Any version
// Git references
let branch = VersionConstraint::parse("main")?; // Branch name
let tag = VersionConstraint::parse("release-v1")?; // Tag name
let latest = VersionConstraint::parse("latest")?; // Just a tag/branch name
let commit = VersionConstraint::parse("abc123def")?; // Commit hash§Error Handling
This method only returns errors for malformed semantic version strings. Git references and special keywords always parse successfully.
Sourcepub fn matches(&self, version: &Version) -> bool
pub fn matches(&self, version: &Version) -> bool
Check if a semantic version satisfies this constraint.
This method tests whether a given semantic version matches the requirements of this constraint. Different constraint types use different matching logic:
- Exact: Version must match exactly
- Requirement: Version must satisfy the semver range
GitRef: Never matches semantic versions (Git refs are matched separately)
§Arguments
version- The semantic version to test against this constraint
§Returns
Returns true if the version satisfies the constraint, false otherwise.
§Examples
use agpm_cli::version::constraints::VersionConstraint;
use semver::Version;
let constraint = VersionConstraint::parse("^1.0.0")?;
let version = Version::parse("1.2.3")?;
assert!(constraint.matches(&version)); // 1.2.3 is compatible with ^1.0.0§Note
Git reference constraints always return false for this method since they
operate on Git refs rather than semantic versions. Use matches_ref
to test Git reference matching.
Sourcepub fn matches_ref(&self, git_ref: &str) -> bool
pub fn matches_ref(&self, git_ref: &str) -> bool
Check if a Git reference satisfies this constraint.
This method tests whether a Git reference (branch, tag, or commit hash)
matches a Git reference constraint. Only GitRef constraints
can match Git references - all other constraint types return false.
§Arguments
git_ref- The Git reference string to test (branch, tag, or commit)
§Returns
Returns true if this is a GitRef constraint with matching reference name,
false otherwise.
§Examples
use agpm_cli::version::constraints::VersionConstraint;
let branch_constraint = VersionConstraint::parse("main")?;
assert!(branch_constraint.matches_ref("main"));
assert!(!branch_constraint.matches_ref("develop"));
let version_constraint = VersionConstraint::parse("^1.0.0")?;
assert!(!version_constraint.matches_ref("main")); // Version constraints don't match refs§Use Cases
This method is primarily used during dependency resolution to match dependencies that specify Git branches, tags, or commit hashes rather than semantic versions.
Sourcepub fn matches_version_info(&self, version_info: &VersionInfo) -> bool
pub fn matches_version_info(&self, version_info: &VersionInfo) -> bool
Check if a VersionInfo satisfies this constraint, including prefix matching.
This method performs comprehensive matching that considers both the prefix (for monorepo-style versioning) and the semantic version. It’s the preferred method for version resolution when working with potentially prefixed versions.
§Matching Rules
- Prefix matching: Constraint and version must have the same prefix (both None, or same String)
- Version matching: After prefix check, applies standard semver matching rules
- Prerelease handling: Follows same rules as
matches
§Arguments
version_info- The version information to test, including prefix and semver
§Returns
Returns true if both the prefix matches AND the version satisfies the constraint.
§Examples
use agpm_cli::version::constraints::VersionConstraint;
use agpm_cli::version::VersionInfo;
use semver::Version;
// Prefixed version matching
let constraint = VersionConstraint::parse("agents-^v1.0.0")?;
let version = VersionInfo {
prefix: Some("agents".to_string()),
version: Version::parse("1.2.0")?,
tag: "agents-v1.2.0".to_string(),
prerelease: false,
};
assert!(constraint.matches_version_info(&version));
// Prefix mismatch
let wrong_prefix = VersionInfo {
prefix: Some("snippets".to_string()),
version: Version::parse("1.2.0")?,
tag: "snippets-v1.2.0".to_string(),
prerelease: false,
};
assert!(!constraint.matches_version_info(&wrong_prefix));
// Unprefixed constraint only matches unprefixed versions
let no_prefix_constraint = VersionConstraint::parse("^1.0.0")?;
let no_prefix_version = VersionInfo {
prefix: None,
version: Version::parse("1.2.0")?,
tag: "v1.2.0".to_string(),
prerelease: false,
};
assert!(no_prefix_constraint.matches_version_info(&no_prefix_version));
assert!(!no_prefix_constraint.matches_version_info(&version)); // Has prefixSourcepub fn to_version_req(&self) -> Option<VersionReq>
pub fn to_version_req(&self) -> Option<VersionReq>
Convert this constraint to a semantic version requirement if applicable.
This method converts version-based constraints into VersionReq objects
that can be used with the semver crate for version matching. Git reference
constraints cannot be converted since they don’t represent version ranges.
§Returns
Returns Some(VersionReq) for constraints that can be expressed as semantic
version requirements, or None for Git reference constraints.
§Conversion Rules
- Exact: Converted to
=1.0.0requirement - Requirement: Returns the inner
VersionReqdirectly GitRef: ReturnsNone(cannot be converted)
§Examples
use agpm_cli::version::constraints::VersionConstraint;
use semver::Version;
let exact = VersionConstraint::parse("1.0.0")?;
let req = exact.to_version_req().unwrap();
assert!(req.matches(&Version::parse("1.0.0")?));
let caret = VersionConstraint::parse("^1.0.0")?;
let req = caret.to_version_req().unwrap();
assert!(req.matches(&Version::parse("1.2.0")?));
let git_ref = VersionConstraint::parse("main")?;
assert!(git_ref.to_version_req().is_none()); // Git refs can't be converted§Use Cases
This method is useful for integrating with existing semver-based tooling
or for performing version calculations that require VersionReq objects.
Sourcepub const fn allows_prerelease(&self) -> bool
pub const fn allows_prerelease(&self) -> bool
Check if this constraint allows prerelease versions.
Prerelease versions contain identifiers like -alpha, -beta, -rc that
indicate pre-release status. This method determines whether the constraint
should consider such versions during resolution.
§Prerelease Policy
GitRef: Allows prereleases (Git refs may point to any commit)- Exact/Requirement: Excludes prereleases unless explicitly specified
§Returns
Returns true if prerelease versions should be considered, false if only
stable versions should be considered.
§Examples
use agpm_cli::version::constraints::VersionConstraint;
let branch = VersionConstraint::parse("main")?;
assert!(branch.allows_prerelease()); // Git refs may be any version
let latest = VersionConstraint::parse("latest")?;
assert!(latest.allows_prerelease()); // Git ref - just a tag name
let exact = VersionConstraint::parse("1.0.0")?;
assert!(!exact.allows_prerelease()); // Exact stable version§Impact on Resolution
During version resolution, if any constraint in a set allows prereleases, the entire constraint set will consider prerelease versions as candidates.
Sourcepub const fn is_semver(&self) -> bool
pub const fn is_semver(&self) -> bool
Check if this constraint represents a semantic version constraint.
Returns true for Exact and Requirement
variants, false for GitRef. This distinguishes between
stable version tags (e.g., v1.0.0, ^1.0.0) and floating refs (e.g.,
branch names like main, commit SHAs).
§Returns
truefor semver constraints (ExactorRequirement)falsefor git references (GitRef)
§Examples
use agpm_cli::version::constraints::VersionConstraint;
let exact = VersionConstraint::parse("v1.0.0")?;
assert!(exact.is_semver()); // Exact version
let caret = VersionConstraint::parse("^1.0.0")?;
assert!(caret.is_semver()); // Requirement
let branch = VersionConstraint::parse("main")?;
assert!(!branch.is_semver()); // Git branch ref
let commit = VersionConstraint::parse("abc123")?;
assert!(!commit.is_semver()); // Git commit ref§Use Cases
This method is useful during version conflict resolution to prefer semver constraints over floating git refs. Semver constraints provide more stable, reproducible builds.
Trait Implementations§
Source§impl Clone for VersionConstraint
impl Clone for VersionConstraint
Source§fn clone(&self) -> VersionConstraint
fn clone(&self) -> VersionConstraint
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for VersionConstraint
impl Debug for VersionConstraint
Auto Trait Implementations§
impl Freeze for VersionConstraint
impl RefUnwindSafe for VersionConstraint
impl Send for VersionConstraint
impl Sync for VersionConstraint
impl Unpin for VersionConstraint
impl UnwindSafe for VersionConstraint
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 moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T> ToStringFallible for Twhere
T: Display,
impl<T> ToStringFallible for Twhere
T: Display,
Source§fn try_to_string(&self) -> Result<String, TryReserveError>
fn try_to_string(&self) -> Result<String, TryReserveError>
ToString::to_string, but without panic on OOM.