Independent implementation of semver.org 2.0.0. Supports full version strings including pre-release identifiers and build metadata. Comparison follows § 11 precedence rules (build metadata ignored).
let v = Version.from("1.2.3-alpha.1+exp.sha.5114f85")
assert(v.major == 1 && v.is_prerelease())
let a = Version.from("1.0.0-alpha")
let b = Version.from("1.0.0")
assert(a < b) // pre-release < release
Types
Version
stable since 0.1export type Version {
readonly major u64
readonly minor u64
readonly patch u64
readonly pre []str
readonly build []str
}
SemVer version (semver.org 2.0.0). All fields are readonly — Version is immutable; operations return a new value. pre holds pre-release identifiers split by . (e.g. "alpha.1" → ["alpha", "1"]). build holds build metadata identifiers; they are not considered for precedence comparison.
ParseVersionError
stable since 0.1export type ParseVersionError
| EmptyInput
| MissingMinor
| MissingPatch
| LeadingZero { component str; value str }
| InvalidComponent { component str; value str }
| EmptyIdentifier { section str }
| InvalidIdentifier { section str; value str }
Error variants returned by Version.from. Each carries positional info (component / section + value) for diagnostic messages.
Constructors
Version.from
stable since 0.1fn Version.from(s str) Fail[ParseVersionError] -> Self
Parses a semver string per § 9–10 grammar. Throws Fail[ParseVersionError] on any error. Handle it with a with Fail[ParseVersionError] block.
Examples
let v = Version.from("2.5.1")
assert(v.major == 2 && v.minor == 5 && v.patch == 1)
let v2 = Version.from("1.0.0-beta+exp.sha.5114f85")
assert(v2.pre[0] == "beta")
Version.new
stable since 0.1fn Version.new(major u64, minor u64, patch u64) -> Self
Simple constructor without pre-release or build metadata. The most common case.
Examples
let v = Version.new(1, 2, 3)
assert(v.into() == "1.2.3")
Version.full
stable since 0.1fn Version.full(major u64, minor u64, patch u64, pre []str, build []str) -> Self
Full constructor with explicit pre-release and build metadata arrays.
Inspection
is_prerelease
stable since 0.1fn Version @is_prerelease() -> bool
Returns true if the version has at least one pre-release identifier.
is_stable
stable since 0.1fn Version @is_stable() -> bool
Returns true if major > 0 and there is no pre-release identifier (stable release per semver convention).
Examples
assert(Version.from("1.0.0").is_stable())
assert(!Version.from("0.9.0").is_stable()) // 0.x.y — unstable
assert(!Version.from("1.0.0-alpha").is_stable()) // pre-release
has_build
stable since 0.1fn Version @has_build() -> bool
Returns true if build metadata is present.
Comparison
All comparisons implement § 11 precedence: major > minor > patch > pre-release. Build metadata is ignored. Pre-release versions have lower precedence than the release (1.0.0-alpha < 1.0.0).
Operator overloading (D46) means v1 < v2, v1 == v2, v1 != v2 work directly.
lt / gt / le / ge
stable since 0.1fn Version @lt(other Version) -> bool // <
fn Version @le(other Version) -> bool // <=
fn Version @gt(other Version) -> bool // >
fn Version @ge(other Version) -> bool // >=
Examples
// semver.org §11 chain example
let chain = [
Version.from("1.0.0-alpha"),
Version.from("1.0.0-alpha.1"),
Version.from("1.0.0-beta"),
Version.from("1.0.0-rc.1"),
Version.from("1.0.0"),
]
for i in 0..chain.len() - 1 {
assert(chain[i] < chain[i + 1])
}
eq / eq_precedence
stable since 0.1fn Version @eq(other Version) -> bool // structural (includes build)
fn Version @eq_precedence(other Version) -> bool // semver §10 (ignores build)
eq is structural — it compares all fields including build. eq_precedence follows § 10 and ignores build metadata.
Examples
let a = Version.from("1.0.0+build.1")
let b = Version.from("1.0.0+build.2")
assert(a.eq_precedence(b)) // same precedence
assert(!a.eq(b)) // different build metadata
Serialization
into
stable since 0.1fn Version @into() -> str
Serializes to MAJOR.MINOR.PATCH[-PRE][+BUILD]. Round-trip: Version.from(v.into()).eq(v) holds for any valid Version.
Examples
let v = Version.new(1, 2, 3)
let s str = v.into()
assert(s == "1.2.3")