semver-php
Rust implementation of Composer's semver library for parsing and matching version constraints.
This library implements Composer's versioning specification, which differs from standard semver in several important ways. You likely want to use the semver crate instead.
Differences from Standard Semver
Composer's semver differs from standard semver in several ways:
- Four components: Versions are normalized to
MAJOR.MINOR.PATCH.EXTRA(e.g.,1.2.3.0) - Branch handling: Dev branches like
dev-masterand1.x-devare first-class citizens - Stability modifiers: Versions can have stability suffixes (
-dev,-alpha,-beta,-RC) - Short forms: Stability can use short forms (
-afor alpha,-bfor beta, etc.) - Tilde behavior:
~1.2means>=1.2 <2.0(not>=1.2.0 <1.3.0as in npm)
Usage
use Semver;
// Check if a version satisfies a constraint
assert!;
assert!;
assert!;
// Filter versions by constraint
let matching = satisfied_by.unwrap;
assert_eq!;
// Sort versions
let sorted = sort.unwrap;
assert_eq!;
Constraint Syntax
The library supports all Composer constraint formats:
Exact Version
use Semver;
assert!;
Comparison Operators
use Semver;
assert!;
assert!;
assert!;
assert!;
assert!;
Tilde Ranges (~)
The tilde operator allows patch-level changes:
use Semver;
assert!;
assert!;
assert!;
Caret Ranges (^)
The caret operator allows changes that don't modify the left-most non-zero digit:
use Semver;
assert!;
assert!;
assert!;
assert!;
Wildcard Ranges
use Semver;
assert!;
assert!;
assert!;
assert!;
Hyphen Ranges
use Semver;
assert!;
assert!;
assert!;
assert!;
AND Constraints
Separate constraints with a space or comma:
use Semver;
assert!;
assert!;
OR Constraints
Separate alternatives with ||:
use Semver;
assert!;
assert!;
assert!;
Stability Handling
Composer semver includes stability modifiers:
use VersionParser;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
Version Normalization
Composer normalizes versions to a 4-component format:
use VersionParser;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
Comparing Versions
For direct version comparison:
assert!;
assert!;
assert!;
assert!;
assert!;
assert!;
Working with Constraints Directly
For more control, use the constraint types directly:
use ;
let constraint = parse_constraints.unwrap;
assert!;
Benchmarks
This library is benchmarked against the original PHP composer/semver using Criterion (Rust) and PHPBench (PHP).
| Operation | PHP | Rust | Speedup |
|---|---|---|---|
| Normalize (simple) | 7.7 µs | 3.6 µs | 2.1x |
| Normalize (complex) | 13.8 µs | 6.1 µs | 2.3x |
| Parse constraints (simple) | 19.0 µs | 9.2 µs | 2.1x |
| Parse constraints (complex) | 53.2 µs | 22.4 µs | 2.4x |
| Satisfies check | 64.8 µs | 38.2 µs | 1.7x |
| Sort (10 versions) | 29.3 µs | 12.0 µs | 2.4x |
| Sort (100 versions) | 392 µs | 252 µs | 1.6x |
| Parse stability | 6.2 µs | 0.9 µs | 7.3x |
Geometric mean speedup: 2.1x
To run the benchmarks yourself (requires Rust and PHP):
License
This project is licensed under the MIT License - see the LICENSE file for details