Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document invariant on Ranges #277

Merged
merged 2 commits into from
Nov 11, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions version-ranges/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,25 @@ use proptest::prelude::*;
use smallvec::{smallvec, SmallVec};

/// Ranges represents multiple intervals of a continuous range of monotone increasing values.
///
/// Internally, [`Ranges`] are an ordered list of segments, where segment is a bounds pair.
///
/// Invariants:
/// 1. The segments are sorted, from lowest to highest (through `Ord`).
/// 2. Each segment contains at least one version (start < end).
/// 3. There is at least one version between two segments.
///
/// These ensure that equivalent instances have an identical representation, which is important
/// for `Eq` and `Hash`. Note that this representation cannot strictly guaranty equality of
/// [`Ranges`] with equality of its representation without also knowing the nature of the underlying
/// versions. In particular, if the version space is discrete, different representations, using
/// different types of bounds (exclusive/inclusive) may correspond to the same set of existing
/// versions. It is a tradeoff we acknowledge, but which makes representations of continuous version
/// sets more accessible, to better handle features like pre-releases and other types of version
/// modifiers. For example, `[(Included(3u32), Excluded(7u32))]` and
/// `[(Included(3u32), Included(6u32))]` refer to the same version set, since there is no version
/// between 6 and 7, which this crate doesn't know about.

#[derive(Debug, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
Expand Down Expand Up @@ -283,6 +302,7 @@ impl<V: Ord> Ranges<V> {
}
}

/// See [`Ranges`] for the invariants checked.
fn check_invariants(self) -> Self {
if cfg!(debug_assertions) {
for p in self.segments.as_slice().windows(2) {
Expand Down