version

A MoonBit library for parsing, comparing, and handling semantic versions. Port of hashicorp/go-version.

version
semver
semantic
versioning
constraints
moon add rami3l/version@0.1.0
Download zip
Author
Version
0.1.0
License
MPL-2.0
Last updated
11 months ago
Downloads
17
README

#MoonBit Version Library

A MoonBit library for parsing, comparing, and handling semantic versions. This is a port of the hashicorp/go-version library.

#Usage

#Version Parsing and Comparison

test "basic version usage" {
let v1 = Version::new("1.2.3") catch { _ => abort("Failed to parse v1") }
let v2 = Version::new("1.5.0+metadata") catch { _ => abort("Failed to parse v2") }

// Basic comparison
if v1.less_than(v2) {
println("\{v1} is less than \{v2}")
}

// Get version components
let segments = v1.segments() // [1, 2, 3]
let prerelease = v1.prerelease() // ""
let metadata = v1.metadata() // ""
}

#Version Constraints

test "version constraints" {
let version = Version::new("1.5.0") catch { _ => abort("Failed to parse version") }

// Single constraint
let constraint = Constraint::new(">= 1.0.0") catch { _ => abort("Failed to parse constraint") }
if constraint.check(version) {
println("Version satisfies constraint")
}

// Multiple constraints
let constraints = constraints_new(">= 1.0.0, < 2.0.0") catch { _ => abort("Failed to parse constraints") }
if constraints_check(constraints, version) {
println("Version satisfies all constraints")
}
}

#Version Collection Sorting

test "version sorting" {
let version_strings = ["1.4.0", "1.2.0", "1.10.0", "1.4.1"]
let sorted_versions = collection_from_strings(version_strings) catch { _ => abort("Failed to create collection") }

// Versions are now sorted: 1.2.0, 1.4.0, 1.4.1, 1.10.0
for version in sorted_versions {
println(version.to_string())
}
}

#New Utility Functions

test "version utilities" {
let version = Version::new("1.2.3-alpha") catch { _ => abort("Failed to parse") }

// Version stability and components
println("Is stable: \{version.is_stable()}") // false (has prerelease)
println("Major: \{version.major()}") // 1
println("Minor: \{version.minor()}") // 2
println("Patch: \{version.patch()}") // 3

// Version increments
let next_major = version.increment_major() catch { _ => abort("Failed") } // 2.0.0
let next_minor = version.increment_minor() catch { _ => abort("Failed") } // 1.3.0
let next_patch = version.increment_patch() catch { _ => abort("Failed") } // 1.2.4

// Constraint utilities
let at_least_1_0 = constraint_at_least("1.0.0") catch { _ => abort("Failed") }
let below_2_0 = constraint_below("2.0.0") catch { _ => abort("Failed") }
let range = constraint_range("1.0.0", "2.0.0") catch { _ => abort("Failed") }

// Constraint analysis
let constraints = [at_least_1_0, below_2_0]
match constraints_min_version(constraints) {
Some(min) => println("Min version: \{min.to_string()}") // 1.0.0
None => println("No minimum bound")
}
}

#Supported Features

  • Version Parsing: Supports semver-compliant version strings with metadata and prerelease information
  • Version Comparison: Full comparison support (equal, greater than, less than, etc.)
  • Version Constraints: Support for operators =, !=, >, <, >=, <=, ~>
  • Version Sorting: Built-in sorting for version collections
  • Metadata and Prerelease: Full support for version metadata and prerelease identifiers
  • Performance Optimizations: Fast path parsing for simple numeric versions like "1.2.3"
  • Large Number Support: Handles versions with Int64-sized segments (up to 9,223,372,036,854,775,807)
  • Utility Functions: Convenient helpers for version stability checks, component access, and version increments
  • Constraint Utilities: Helper functions for creating and analyzing constraint sets
  • Enhanced Error Handling: Descriptive error messages for easier debugging

#API Reference

#Version

  • Version::new(version_string) - Parse a version string
  • Version::new_semver(version_string) - Parse with strict semver rules
  • compare(other) - Compare two versions (-1, 0, 1)
  • equal(other), greater_than(other), less_than(other) - Boolean comparisons
  • segments() - Get version segments as Array[Int]
  • prerelease() - Get prerelease identifier
  • metadata() - Get build metadata
  • core() - Get core version (major.minor.patch only)

#New Utility Functions

  • is_stable() - Check if version is stable (no prerelease)
  • is_prerelease() - Check if version is prerelease
  • major(), minor(), patch() - Get individual version components
  • increment_major(), increment_minor(), increment_patch() - Create incremented versions

#Constraint

  • Constraint::new(constraint_string) - Parse constraint like ">= 1.0.0"
  • check(version) - Check if version satisfies constraint

#Constraint Utility Functions

  • constraint_at_least(version) - Create ">= version" constraint
  • constraint_below(version) - Create "< version" constraint
  • constraint_exactly(version) - Create "= version" constraint
  • constraint_pessimistic(version) - Create "~> version" constraint
  • constraint_range(min, max) - Create ">= min, < max" range constraint
  • constraints_min_version(constraints) - Find minimum bound from constraints
  • constraints_max_version(constraints) - Find maximum bound from constraints
  • constraints_allow_any(constraints) - Check if constraints are empty/permissive

#Collection

  • collection_from_strings(version_strings) - Create sorted collection from strings
  • collection_sort() - Sort versions in place
  • collection_is_sorted() - Check if collection is sorted

#Performance Notes

This MoonBit implementation includes several optimizations for common use cases:

  • Fast path parsing: Simple numeric versions like "1.2.3" use an optimized parsing path
  • Efficient character validation: Character code operations instead of string operations where possible
  • Optimized comparison: Quick equality checks before detailed comparison logic
  • Edge case handling: Robust handling of large numbers up to Int64 maximum value

#Examples

See cmd/example/main.mbt for a comprehensive demo of all library features.

#License

MPL-2.0 (same as original Go library)

#
Collection

typealias Array[Version] as Collection

Collection is a type alias for Array[Version] that provides sorting functionality

#
Constraints

typealias Array[Constraint] as Constraints

Constraints is an array of constraints

#
VersionError

pub suberror VersionError String

#
Constraint

pub struct Constraint {
op : Operator
version : Version
original : String
}

Constraint represents a single constraint for a version, such as ">= 1.0"
impl Eq for Constraint
impl Show for Constraint

#
Constraint::check

fn Constraint::check(self : Constraint, version : Version) -> Bool

Check if a version satisfies this constraint

#
Constraint::equals

fn Constraint::equals(self : Constraint, other : Constraint) -> Bool

Check if two constraints are equal

#
Constraint::has_prerelease

fn Constraint::has_prerelease(self : Constraint) -> Bool

Check if constraint has prerelease

#
Constraint::new

fn Constraint::new(constraint_str : String) -> Constraint raise VersionError

Create a new constraint from a string like ">= 1.0", "< 2.0", etc.

#
Constraint::to_string

fn Constraint::to_string(self : Constraint) -> String

Convert constraint to string

#
Operator

pub enum Operator {
Equal
NotEqual
GreaterThan
LessThan
GreaterThanEqual
LessThanEqual
Pessimistic
}

Operator types for version constraints
impl Eq for Operator
impl Show for Operator

#
Version

pub struct Version {
metadata : String
pre : String
segments : Array[Int64]
si : Int
original : String
}

Version represents a single version.
impl Eq for Version
impl Show for Version

#
Version::compare

fn Version::compare(self : Version, other : Version) -> Int

Compare compares this version to another version. This returns -1, 0, or 1 if this version is smaller, equal, or larger than the other version, respectively.

#
Version::core

fn Version::core(self : Version) -> Version raise VersionError

Core returns a new version constructed from only the MAJOR.MINOR.PATCH segments of the version, without prerelease or metadata.

#
Version::equal

fn Version::equal(self : Version, other : Version) -> Bool

Equal tests if two versions are equal.

#
Version::equal_segments

fn Version::equal_segments(self : Version, other : Version) -> Bool

#
Version::from_db_string

fn Version::from_db_string(db_str : String) -> Version raise VersionError

Create version from a database-compatible value (equivalent to Scan)

#
Version::from_json

fn Version::from_json(json_str : String) -> Version raise VersionError

Unmarshal version from JSON string (equivalent to UnmarshalText)

#
Version::greater_than

fn Version::greater_than(self : Version, other : Version) -> Bool

GreaterThan tests if this version is greater than another version.

#
Version::greater_than_or_equal

fn Version::greater_than_or_equal(self : Version, other : Version) -> Bool

GreaterThanOrEqual tests if this version is greater than or equal to another version.

#
Version::increment_major

fn Version::increment_major(self : Version) -> Version raise VersionError

Create a new version with incremented major version

#
Version::increment_minor

fn Version::increment_minor(self : Version) -> Version raise VersionError

Create a new version with incremented minor version

#
Version::increment_patch

fn Version::increment_patch(self : Version) -> Version raise VersionError

Create a new version with incremented patch version

#
Version::is_prerelease

fn Version::is_prerelease(self : Version) -> Bool

Check if version is prerelease

#
Version::is_stable

fn Version::is_stable(self : Version) -> Bool

Check if version is stable (no prerelease)

#
Version::less_than

fn Version::less_than(self : Version, other : Version) -> Bool

LessThan tests if this version is less than another version.

#
Version::less_than_or_equal

fn Version::less_than_or_equal(self : Version, other : Version) -> Bool

LessThanOrEqual tests if this version is less than or equal to another version.

#
Version::major

fn Version::major(self : Version) -> Int64

Get major version number (first segment)

#
Version::metadata

fn Version::metadata(self : Version) -> String

Metadata returns any metadata that was part of the version string. Metadata is anything that comes after the "+" in the version.

#
Version::minor

fn Version::minor(self : Version) -> Int64

Get minor version number (second segment)

#
Version::must

fn Version::must(v : String) -> Version

Must wrapper for Version::new

#
Version::must_semver

fn Version::must_semver(v : String) -> Version

Must wrapper for Version::new_semver

#
Version::new

fn Version::new(v : String) -> Version raise VersionError

Create a new Version from a string

#
Version::new_semver

fn Version::new_semver(v : String) -> Version raise VersionError

Create a new Version that adheres strictly to SemVer specs

#
Version::original

fn Version::original(self : Version) -> String

Original returns the original parsed version as-is

#
Version::patch

fn Version::patch(self : Version) -> Int64

Get patch version number (third segment)

#
Version::prerelease

fn Version::prerelease(self : Version) -> String

Prerelease returns any prerelease data that is part of the version. Prerelease information is anything that comes after the "-" in the version.

#
Version::segments

fn Version::segments(self : Version) -> Array[Int]

Segments returns the numeric segments of the version as a slice of ints.

#
Version::segments64

fn Version::segments64(self : Version) -> Array[Int64]

Segments64 returns the numeric segments of the version as a slice of int64s.

#
Version::to_db_string

fn Version::to_db_string(self : Version) -> String

Convert version to a database-compatible string (equivalent to Value)

#
Version::to_json

fn Version::to_json(self : Version) -> String

Marshal version to JSON string (equivalent to MarshalText)

#
Version::to_string

fn Version::to_string(self : Version) -> String

String returns the full version string including pre-release and metadata information. Optimized version using array-based concatenation for better performance

#
collection_from_strings

fn collection_from_strings(version_strings : Array[String]) -> Array[Version] raise VersionError

Create a new sorted collection from an array of version strings

#
collection_is_sorted

fn collection_is_sorted(versions : Array[Version]) -> Bool

Check if the collection is sorted

#
collection_sort

fn collection_sort(versions : Array[Version]) -> Unit

Sort versions in place

#
collection_sort_by_fn

fn collection_sort_by_fn(versions : Array[Version], compare : (Version, Version) -> Int) -> Unit

Sort versions in place using a custom comparison function

#
constraint_at_least

fn constraint_at_least(version_str : String) -> Constraint raise VersionError

Create a constraint that accepts any version >= the given version

#
constraint_below

fn constraint_below(version_str : String) -> Constraint raise VersionError

Create a constraint that accepts any version < the given version

#
constraint_exactly

fn constraint_exactly(version_str : String) -> Constraint raise VersionError

Create a constraint for an exact version match

#
constraint_pessimistic

fn constraint_pessimistic(version_str : String) -> Constraint raise VersionError

Create a pessimistic constraint (~>) for the given version

#
constraint_range

fn constraint_range(min_version : String, max_version : String) -> Array[Constraint] raise VersionError

Create a range constraint ">=min, <max"

#
constraints_allow_any

fn constraints_allow_any(constraints : Array[Constraint]) -> Bool

Check if constraints allow any version (i.e., are not overly restrictive)

#
constraints_check

fn constraints_check(constraints : Array[Constraint], version : Version) -> Bool

Check if a version satisfies all constraints

#
constraints_equal

fn constraints_equal(left : Array[Constraint], right : Array[Constraint]) -> Bool

Check if two constraint arrays are equal

#
constraints_max_version

fn constraints_max_version(constraints : Array[Constraint]) -> Version?

Get the strictest upper bound from a set of constraints

#
constraints_min_version

fn constraints_min_version(constraints : Array[Constraint]) -> Version?

Get the strictest lower bound from a set of constraints

#
constraints_must

fn constraints_must(constraints_str : String) -> Array[Constraint]

MustConstraints is a helper that wraps a call to constraints_new and panics if error is non-nil

#
constraints_new

fn constraints_new(constraints_str : String) -> Array[Constraint] raise VersionError

Create constraints from a comma-separated string like ">= 1.0, < 2.0"

#
constraints_to_string

fn constraints_to_string(constraints : Array[Constraint]) -> String

Convert constraints to string

#
must

fn must(v : Result[Version, VersionError]) -> Version

Must is a helper that wraps a call to a function returning (Version, error) and panics if error is non-nil.

Powered by MoonBit

Site sourceReport issuePackagesBuild queueSkillsStatistics

© 2026 mooncakes.io