VersionConstraint

Enum VersionConstraint 

Source
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 version
  • Requirement: Matches versions using semver ranges
  • GitRef: 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:

  • GitRef constraints (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”)

Fields

§prefix: Option<String>
§version: Version
§

Requirement

Semantic version requirement with optional prefix (e.g., “^1.0.0”, “agents-^v1.0.0”)

Fields

§prefix: Option<String>
§

GitRef(String)

Git tag or branch name (including “latest” - it’s just a tag name)

Implementations§

Source§

impl VersionConstraint

Source

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
  1. Special keywords: "*" (wildcard for any version)
  2. Exact versions: "1.0.0", "v1.0.0" (without range operators)
  3. Version requirements: "^1.0.0", "~1.2.0", ">=1.0.0", "<2.0.0"
  4. 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.

Source

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.

Source

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.

Source

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 prefix
Source

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.0 requirement
  • Requirement: Returns the inner VersionReq directly
  • GitRef: Returns None (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.

Source

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.

Source

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
  • true for semver constraints (Exact or Requirement)
  • false for 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

Source§

fn clone(&self) -> VersionConstraint

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for VersionConstraint

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for VersionConstraint

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T> ToStringFallible for T
where T: Display,

Source§

fn try_to_string(&self) -> Result<String, TryReserveError>

ToString::to_string, but without panic on OOM.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more