{"id":20673497,"url":"https://github.com/gngeorgiev/semver_rs","last_synced_at":"2025-09-03T13:40:20.817Z","repository":{"id":46035727,"uuid":"182459007","full_name":"gngeorgiev/semver_rs","owner":"gngeorgiev","description":":memo: Semantic version parsing and comparison for Rust, based on the node-semver package.","archived":false,"fork":false,"pushed_at":"2021-11-22T18:07:44.000Z","size":462,"stargazers_count":9,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-29T12:35:02.793Z","etag":null,"topics":["rust","semver-parser"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gngeorgiev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-04-20T22:10:14.000Z","updated_at":"2024-11-21T01:54:17.000Z","dependencies_parsed_at":"2022-09-26T20:31:51.588Z","dependency_job_id":null,"html_url":"https://github.com/gngeorgiev/semver_rs","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gngeorgiev%2Fsemver_rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gngeorgiev%2Fsemver_rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gngeorgiev%2Fsemver_rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gngeorgiev%2Fsemver_rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gngeorgiev","download_url":"https://codeload.github.com/gngeorgiev/semver_rs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249786953,"owners_count":21325568,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["rust","semver-parser"],"created_at":"2024-11-16T20:41:40.275Z","updated_at":"2025-04-19T19:55:34.391Z","avatar_url":"https://github.com/gngeorgiev.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SemVer\n\n![CI](https://github.com/gngeorgiev/semver_rs/actions/workflows/ci.yaml/badge.svg) [![semver_rs](https://docs.rs/semver_rs/badge.svg)](https://docs.rs/semver_rs) [![semver_rs](https://img.shields.io/crates/v/semver_rs.svg)](https://crates.io/crates/semver_rs)\n\nSemantic version parsing and comparison ([semver](https://semver.org/)). The implementation of this crate is based on the\n[node-semver](https://github.com/npm/node-semver#readme) npm package. The tests are taken directly\nfrom node-semver's repo. This should make this crate as good at parsing semver expressions as the\nnode package manager.\n\n## Installation\n\nAdd this to your `[dependencies]` section in `Cargo.toml`:\n\n```toml\nsemver_rs = \"0.2\"\n```\n\n## Usage\n\n### Comparing two versions\n\n```rust\nuse semver_rs::Version;\n\n// by constructing version instances manually\nlet ver1 = Version::new(\"2.0.0\").parse()?;\nlet ver2 = Version::new(\"1.2.3\").parse()?;\n\nassert!(ver1 \u003e ver2);\n\n// by using the exported helper function\nuse semver_rs::compare;\nuse std::cmp::Ordering;\n\nassert!(compare(\"2.0.0\", \"1.2.3\", None)? == Ordering::Greater);\n```\n\n### Checking whether a version is in a range\n\n```rust\nuse semver_rs::{Range, Version};\n\n// by constructing version instances manually\nlet range = Range::new(\"\u003e=1.2.3\").parse()?;\nlet ver = Version::new(\"1.2.4\").parse()?;\n\nassert!(range.test(\u0026ver));\n\n// by using the exported helper function\nuse semver_rs::satisfies;\n\nassert!(satisfies(\"1.2.4\", \"\u003e=1.2.4\", None)?);\n```\n\n### Parsing with specific options\n\n```rust\nuse semver_rs::{Version, Range, Options};\n\nlet opts = Options::builder().loose(true).include_prerelease(true).build();\nlet range = Range::new(\"\u003e=1.2.3\").with_options(opts).parse()?;\nlet ver = Version::new(\"1.2.4-pre1\").with_options(opts).parse()?;\n\nassert!(range.test(\u0026ver));\n```\n\n### Serializing\n\nIn order to allow serializing the semver structs allow the `serde` feature:\n\n```toml\nsemver_rs = { version = \"0.2\", features = [\"serde\"] }\n```\n\n```rust\nuse semver_rs::{Range, Options};\n\nlet opts = Options::builder().loose(true).include_prerelease(true).build();\nlet range = Range::new(\"\u003e=1.2.3\").with_options(opts).parse().unwrap();\nlet _ = serde_json::to_string(\u0026opts).unwrap();\n```\n\n## Development\n\nInstall [just](https://github.com/casey/just) and run the setup:\n\n```shell\ncargo install just \u0026\u0026 just setup\n```\n\n## Run bench\n\nTo run the benchmarks populating the next point run:\n\n```shell\njust bench\n```\n\nThis shell script collects some ranges from random npm packages and compares the results for the three implementations -\n`semver_node`, `semver_rs` and `steveklabnik/semver`. From the table bellow the results can be observed.\n\n## Comparisons and considerations with other crates\n\nAt the time of writing this README there's only one other crate in the Rust ecosystem capable of parsing semver - [steveklabnik/semver](https://github.com/steveklabnik/semver).\nWhile this crate is being used in cargo and is clearly doing its job there very well, while comparing arbitrary semver\nstrings from a number of NPM packages I found it unable to parse a lot of them. Since its implementation of semver was vastly different\nfrom NPM's I decided to base this crate on NPM's package in the hopes of making it easier to keep up with any updates in the future.\nI kept the implementation as close as possible so the code structure and the way input is parsed should be very similar.\n\nOne trade-off this implementation had to make was a tiny bit of performance. Since the parsing is based heavily on Regex it's a little bit slower.\nThere are still a lot of string allocations that can be eliminated, especially in parsing Ranges and Versions with prereleases.\n\n```shell\n┌─────────┬───────────────────────┬───────────┬───────────────┬────────┬─────────────────────┐\n│ (index) │         name          │ satisfies │ not_satisfies │ errors │     average_us      │\n├─────────┼───────────────────────┼───────────┼───────────────┼────────┼─────────────────────┤\n│    0    │     'semver_node'     │    14     │      451      │   1    │  32.68025751072961  │\n│    1    │      'semver_rs'      │    14     │      451      │   1    │  8.454935622317597  │\n│    2    │ 'steveklabnik/semver' │    11     │      445      │   10   │ 0.27682403433476394 │\n└─────────┴───────────────────────┴───────────┴───────────────┴────────┴─────────────────────┘\n```\n\nIn conclussion `semver_rs` is faster than `semver_node` and slower than `steveklabnik/semver`. It's also as accurate\nin parsing as `semver_node`, while `steveklabnik/semver` couldn't handle 9 of the ranges.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgngeorgiev%2Fsemver_rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgngeorgiev%2Fsemver_rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgngeorgiev%2Fsemver_rs/lists"}