pubsat 0.1.0

Building blocks for SAT-based dependency resolvers: a node-semver-compatible range parser, an ecosystem-independent constraint vocabulary, and a backend-agnostic SAT problem/solver abstraction with a Varisat backend.
Documentation
//! Throughput of [`VersionSet::parse`] on a corpus of npm-style
//! range strings, broken out by syntax shape so regressions can
//! be attributed to a specific parser path.

use criterion::{Criterion, black_box, criterion_group, criterion_main};
use pubsat::version::VersionSet;

fn parse_corpus(c: &mut Criterion) {
    // Each entry is `(label, corpus)`. The labels show up in the
    // criterion report so regressions point at a specific shape.
    let cases: &[(&str, &[&str])] = &[
        (
            "caret",
            &[
                "^1.0.0",
                "^2.5.3",
                "^0.2.3",
                "^0.0.5",
                "^10.20.30",
                "^1.0.0-alpha.1",
            ],
        ),
        ("tilde", &["~1.0.0", "~2.5.3", "~0.2.3", "~10.20.30"]),
        (
            "exact_and_comparator",
            &[
                "1.2.3", "=1.2.3", ">=1.0.0", "<=2.0.0", ">1.0.0", "<2.0.0", ">= 1.2.0",
            ],
        ),
        (
            "hyphen",
            &[
                "1.2.3 - 2.3.4",
                "1.0.0 - 2.0.0",
                "0.5.0 - 1.0.0",
                "1.0 - 2.0",
            ],
        ),
        (
            "x_range",
            &["1.x", "1.2.x", "1.x.x", "*", "x", "1.X", "1.*.*"],
        ),
        (
            "union",
            &[
                "1.x || >=2.5.0",
                "^1.0.0 || ^2.0.0",
                "1.2.3 || 1.3.0 || 1.4.0",
            ],
        ),
        (
            "complex",
            &[
                ">= 1.2.0 < 2.0.0",
                ">=1.0.0 <2.0.0 || >=3.0.0",
                "1.0.0-alpha <2.0.0",
            ],
        ),
    ];

    for (label, corpus) in cases {
        c.bench_function(&format!("parse/{}", label), |b| {
            b.iter(|| {
                for s in corpus.iter() {
                    let _ = VersionSet::parse(black_box(s));
                }
            });
        });
    }
}

criterion_group!(benches, parse_corpus);
criterion_main!(benches);