#semver #version #npm-package #semantic #parser #package-manager #comparison

semver_rs

基于NPM的node-semver包的语义版本解析和比较

5个版本

0.2.0 2021年11月22日
0.1.3 2019年4月30日
0.1.2 2019年4月30日
0.1.1 2019年4月30日
0.1.0 2019年4月30日

#1516解析器实现

47 每月下载量
2 crates 中使用

自定义许可证

77KB
1.5K SLoC

SemVer

CI semver_rs semver_rs

Semantic version parsing and comparison (semver). The implementation of this crate is based on the node-semver npm package. The tests are taken directly from node-semver's repo. This should make this crate as good at parsing semver expressions as the node package manager.

安装

将以下内容添加到您的 [dependencies] 部分 Cargo.toml

semver_rs = "0.2"

用法

比较两个版本

use semver_rs::Version;

// by constructing version instances manually
let ver1 = Version::new("2.0.0").parse()?;
let ver2 = Version::new("1.2.3").parse()?;

assert!(ver1 > ver2);

// by using the exported helper function
use semver_rs::compare;
use std::cmp::Ordering;

assert!(compare("2.0.0", "1.2.3", None)? == Ordering::Greater);

检查版本是否在范围内

use semver_rs::{Range, Version};

// by constructing version instances manually
let range = Range::new(">=1.2.3").parse()?;
let ver = Version::new("1.2.4").parse()?;

assert!(range.test(&ver));

// by using the exported helper function
use semver_rs::satisfies;

assert!(satisfies("1.2.4", ">=1.2.4", None)?);

使用特定选项解析

use semver_rs::{Version, Range, Options};

let opts = Options::builder().loose(true).include_prerelease(true).build();
let range = Range::new(">=1.2.3").with_options(opts).parse()?;
let ver = Version::new("1.2.4-pre1").with_options(opts).parse()?;

assert!(range.test(&ver));

序列化

为了允许序列化semver结构体,允许 serde 功能

semver_rs = { version = "0.2", features = ["serde"] }
use semver_rs::{Range, Options};

let opts = Options::builder().loose(true).include_prerelease(true).build();
let range = Range::new(">=1.2.3").with_options(opts).parse().unwrap();
let _ = serde_json::to_string(&opts).unwrap();

开发

安装 just 并运行设置

cargo install just && just setup

运行基准测试

要运行基准测试,请运行以下命令

just bench

这个shell脚本从随机的npm包中收集一些范围,并比较了三个实现的结果 - semver_nodesemver_rssteveklabnik/semver。从下面的表格中可以观察到结果。

与其他crates的比较和考虑

在编写此README时,Rust生态系统中只有另一个crate可以解析semver - steveklabnik/semver。虽然这个crate在cargo中使用,并且明显很好地完成了它的任务,但在比较来自多个NPM包的任意semver字符串时,我发现它无法解析很多。由于它的semver实现与NPM大不相同,我决定以NPM的包为基础实现这个crate,希望能更容易地跟上未来的任何更新。我尽量保持实现尽可能接近,因此代码结构和输入解析方式应该非常相似。

这种实现必须做出的权衡是略微牺牲了一些性能。由于解析主要依赖于正则表达式,所以它稍微慢一些。仍然有许多字符串分配可以被消除,特别是在解析带有预发布版本的版本和范围时。

┌─────────┬───────────────────────┬───────────┬───────────────┬────────┬─────────────────────┐
 (index)          name          │ satisfies │ not_satisfies │ errors │     average_us      │
├─────────┼───────────────────────┼───────────┼───────────────┼────────┼─────────────────────┤
    0    │     'semver_node'     │    14     │      451      │   1    │  32.68025751072961  │
    1    │      'semver_rs'      │    14     │      451      │   1    │  8.454935622317597  │
    2    │ 'steveklabnik/semver' │    11     │      445      │   10   │ 0.27682403433476394 │
└─────────┴───────────────────────┴───────────┴───────────────┴────────┴─────────────────────┘

总的来说,semver_rssemver_node快,但比steveklabnik/semver慢。它在解析上的准确性也和semver_node一样,而steveklabnik/semver无法处理9个范围。

依赖项

~2.5–4MB
~74K SLoC