#range #version #selector #pubgrub

version-ranges

Performance-optimized type for generic version ranges and operations on them

2 releases

0.1.1 Nov 14, 2024
0.1.0 Oct 29, 2024

#205 in Algorithms

Download history 3512/week @ 2024-11-17 3589/week @ 2024-11-24 3354/week @ 2024-12-01 3362/week @ 2024-12-08 2713/week @ 2024-12-15 1561/week @ 2024-12-22 2487/week @ 2024-12-29 4059/week @ 2025-01-05 3131/week @ 2025-01-12 2723/week @ 2025-01-19 2709/week @ 2025-01-26 14774/week @ 2025-02-02 28280/week @ 2025-02-09 25405/week @ 2025-02-16 26476/week @ 2025-02-23 25423/week @ 2025-03-02

109,143 downloads per month
Used in 12 crates (4 directly)

MPL-2.0 license

62KB
923 lines

Ranges

crates.io docs.rs

This crate contains a performance-optimized type for generic version ranges and operations on them.

Ranges can represent version selectors such as (>=1.5.1, <2) OR (==3.1) OR (>4). Internally, it is an ordered list of contiguous intervals (segments) with inclusive, exclusive or open-ended ends, similar to a Vec<(Bound<T>, Bound<T>)>.

You can construct a basic range from one of the following build blocks. All other ranges are concatenation, union, and complement of these basic ranges.

  • Ranges::empty(): No version
  • Ranges::full(): All versions
  • Ranges::singleton(v): Only the version v exactly
  • Ranges::higher_than(v): All versions v <= versions
  • Ranges::strictly_higher_than(v): All versions v < versions
  • Ranges::lower_than(v): All versions versions <= v
  • Ranges::strictly_lower_than(v): All versions versions < v
  • Ranges::between(v1, v2): All versions v1 <= versions < v2

The optimized operations include complement, contains, contains_many, intersection, is_disjoint, subset_of and union.

Ranges is generic over any type that implements Ord + Clone and can represent all kinds of slices with ordered coordinates, not just version ranges. While built as a performance-critical piece of pubgrub, it can be adopted for other domains, too.

A number line and a sample range on it

You can imagine a Ranges as slices over a number line.

Note that there are limitations to the equality implementation: Given a Ranges<u32>, the segments (Unbounded, Included(42u32)) and (Included(0), Included(42u32)) as well as (Included(1), Included(5)) and (Included(1), Included(3)) + (Included(4), Included(5)) are reported as unequal, even though the match the same versions: We can't tell that there isn't a version between 0 and -inf or 3 and 4 respectively.

Optional features

  • serde: serialization and deserialization for the version range, given that the version type also supports it.
  • proptest: Exports are proptest strategy for Ranges<u32>.

Dependencies

~41–680KB
~13K SLoC