Rust语义化版本解析库node-semver的使用,支持Node.js风格版本号比较与校验

Rust语义化版本解析库node-semver的使用,支持Node.js风格版本号比较与校验

这个crate是一个基于Rust的JavaScript node-semver实现。它专门设计用于与Node/NPM特有的语义化版本格式兼容(而标准的semver crate不兼容这种格式)。

它适用于为JavaScript工具链设计的Rust程序和库,并尽力保持与node-semver的兼容性。

它还支持serde序列化,可以将版本和范围转换为字符串。

使用方法

node-semver包含两个主要类型:[Version]和[Range]。以下是基本用法示例:

use node_semver::{Range, Version};

let version: Version = "1.2.3".parse().unwrap();
let range: Range = "^1.2".parse().unwrap();

assert!(version.satisfies(&range));

最低建议Rust版本(MSRV)

必须使用1.70.0或更高版本。

完整示例

以下是一个更完整的示例,展示如何使用node-semver进行版本比较和校验:

use node_semver::{Version, Range};

fn main() {
    // 解析版本号
    let version1: Version = "1.2.3".parse().unwrap();
    let version2: Version = "1.3.0-alpha.1".parse().unwrap();
    
    // 解析版本范围
    let range1: Range = "^1.2".parse().unwrap();
    let range2: Range = "~1.2.3".parse().unwrap();
    let range3: Range = ">=1.2.3 <2.0.0".parse().unwrap();
    
    // 检查版本是否满足范围
    println!("1.2.3 satisfies ^1.2: {}", version1.satisfies(&range1)); // true
    println!("1.3.0-alpha.1 satisfies ^1.2: {}", version2.satisfies(&range1)); // true
    println!("1.2.3 satisfies ~1.2.3: {}", version1.satisfies(&range2)); // true
    println!("1.3.0-alpha.1 satisfies ~1.2.3: {}", version2.satisfies(&range2)); // false
    
    // 比较版本
    println!("1.2.3 < 1.3.0-alpha.1: {}", version1 < version2); // true
    println!("1.2.3 == 1.2.3: {}", version1 == Version::new(1, 2, 3)); // true
    
    // 检查版本是否符合多个范围
    println!("1.2.3 satisfies >=1.2.3 <2.0.0: {}", version1.satisfies(&range3)); // true
    println!("2.0.0 satisfies >=1.2.3 <2.0.0: {}", 
        Version::new(2, 0, 0).satisfies(&range3)); // false
}

安装

在项目目录中运行以下Cargo命令:

cargo add node-semver

或者在Cargo.toml中添加以下行:

node-semver = "2.2.0"

许可证

Apache-2.0


1 回复

Rust语义化版本解析库 node-semver 使用指南

node-semver 是一个 Rust 实现的语义化版本解析库,兼容 Node.js 风格的版本号比较与校验。它完全遵循 SemVer 2.0.0 规范,并提供了 Node.js 中 semver 包的类似功能。

功能特性

  • 解析和比较语义化版本号
  • 支持 Node.js 风格的版本范围语法
  • 版本号校验
  • 版本范围匹配检查
  • 支持预发布版本处理

使用方法

首先在 Cargo.toml 中添加依赖:

[dependencies]
node-semver = "1.0"

基本示例

use node_semver::{Version, Range};

fn main() {
    // 解析版本号
    let version = Version::parse("1.2.3-alpha.1").unwrap();
    println!("版本号: {}", version);
    
    // 比较版本
    let v1 = Version::parse("1.2.3").unwrap();
    let v2 = Version::parse("1.2.4").unwrap();
    println!("v1 < v2: {}", v1 < v2);  // true
    
    // 解析版本范围
    let range = Range::parse(">=1.2.3 <2.0.0").unwrap();
    println!("范围: {}", range);
    
    // 检查版本是否满足范围
    let version_to_check = Version::parse("1.5.0").unwrap();
    println!("是否满足: {}", range.satisfies(&version_to_check));  // true
}

版本号校验

use node_semver::Version;

fn validate_version(version_str: &str) {
    match Version::parse(version_str) {
        Ok(v) => println!("'{}' 是有效的版本号: {}", version_str, v),
        Err(e) => println!("'{}' 无效: {}", version_str, e),
    }
}

validate_version("1.2.3");         // 有效
validate_version("1.2.3-alpha.1"); // 有效
validate_version("1.2");           // 无效

版本范围匹配

use node_semver::{Version, Range};

fn check_version_in_range(version: &str, range: &str) {
    let v = Version::parse(version).unwrap();
    let r = Range::parse(range).unwrap();
    
    println!("版本 {} 在范围 {} 内: {}", v, r, r.satisfies(&v));
}

check_version_in_range("1.2.3", "^1.0.0");  // true
check_version_in_range("2.0.0", "^1.0.0");  // false
check_version_in_range("1.5.0", "1.x || >=2.5.0 || 5.0.0 - 7.2.3"); // true

支持的版本范围语法

node-semver 支持 Node.js 风格的各种版本范围语法:

  • 基本比较: >1.2.3, >=1.2.3, <1.2.3, <=1.2.3
  • 范围连词: >1.2.3 <2.0.0
  • 连字符范围: 1.2.3 - 2.3.4
  • 通配符: 1.2.x, 1.*, *
  • 兼容版本(^): ^1.2.3 (表示 >=1.2.3 <2.0.0)
  • 近似版本(~): ~1.2.3 (表示 >=1.2.3 <1.3.0)
  • 逻辑或: 1.2.3 || 2.x

预发布版本处理

use node_semver::{Version, Range};

let stable = Version::parse("1.2.3").unwrap();
let prerelease = Version::parse("1.2.3-alpha.1").unwrap();

// 默认情况下预发布版本不会匹配范围
let range = Range::parse(">=1.2.3").unwrap();
println!("稳定版匹配: {}", range.satisfies(&stable));      // true
println!("预发布版匹配: {}", range.satisfies(&prerelease)); // false

// 可以显式包含预发布版本
let range_with_prerelease = Range::parse(">=1.2.3-0").unwrap();
println!("预发布版匹配: {}", range_with_prerelease.satisfies(&prerelease)); // true

完整示例代码

use node_semver::{Version, Range, SemverError};

fn main() -> Result<(), SemverError> {
    // 示例1:基本版本比较
    let v1 = Version::parse("1.2.3")?;
    let v2 = Version::parse("1.5.0")?;
    println!("比较 {} 和 {}: {}", v1, v2, v1 < v2); // true
    
    // 示例2:版本范围检查
    let range = Range::parse(">=1.2.3 <2.0.0")?;
    let versions = ["1.2.3", "1.5.0", "2.0.0", "0.9.0"];
    
    for ver_str in versions {
        let ver = Version::parse(ver_str)?;
        println!("版本 {} 满足范围 {}: {}", ver, range, range.satisfies(&ver));
    }
    
    // 示例3:处理预发布版本
    let stable = Version::parse("1.2.3")?;
    let alpha = Version::parse("1.2.3-alpha.1")?;
    let beta = Version::parse("1.2.3-beta.2")?;
    
    let standard_range = Range::parse("^1.0.0")?;
    let prerelease_range = Range::parse("^1.0.0-0")?;
    
    println!("稳定版检查:");
    println!("标准范围: {}", standard_range.satisfies(&stable)); // true
    println!("预发布范围: {}", prerelease_range.satisfies(&stable)); // true
    
    println!("预发布版检查:");
    println!("标准范围: {}", standard_range.satisfies(&alpha)); // false
    println!("预发布范围: {}", prerelease_range.satisfies(&alpha)); // true
    
    // 示例4:通配符和逻辑或
    let wildcard_range = Range::parse("1.2.x || 2.*")?;
    let test_versions = ["1.2.0", "1.2.99", "2.0.0", "2.5.0", "1.3.0"];
    
    println!("\n通配符范围测试:");
    for ver_str in test_versions {
        let ver = Version::parse(ver_str)?;
        println!("版本 {} 满足范围 {}: {}", ver, wildcard_range, wildcard_range.satisfies(&ver));
    }
    
    Ok(())
}

注意事项

  1. 解析错误时会返回 node_semver::SemverError,实际使用时应该处理这些错误
  2. 对于性能敏感的场景,可以重用 VersionRange 实例以避免重复解析
  3. 库的 API 设计尽量与 Node.js 的 semver 包保持一致,方便从 JavaScript 迁移

node-semver 为 Rust 开发者提供了处理语义化版本号的完整解决方案,特别适合需要与 Node.js 生态交互的项目。

回到顶部