@@ -46,6 +46,25 @@ use proptest::prelude::*;
46
46
use smallvec:: { smallvec, SmallVec } ;
47
47
48
48
/// Ranges represents multiple intervals of a continuous range of monotone increasing values.
49
+ ///
50
+ /// Internally, [`Ranges`] are an ordered list of segments, where segment is a bounds pair.
51
+ ///
52
+ /// Invariants:
53
+ /// 1. The segments are sorted, from lowest to highest (through `Ord`).
54
+ /// 2. Each segment contains at least one version (start < end).
55
+ /// 3. There is at least one version between two segments.
56
+ ///
57
+ /// These ensure that equivalent instances have an identical representation, which is important
58
+ /// for `Eq` and `Hash`. Note that this representation cannot strictly guaranty equality of
59
+ /// [`Ranges`] with equality of its representation without also knowing the nature of the underlying
60
+ /// versions. In particular, if the version space is discrete, different representations, using
61
+ /// different types of bounds (exclusive/inclusive) may correspond to the same set of existing
62
+ /// versions. It is a tradeoff we acknowledge, but which makes representations of continuous version
63
+ /// sets more accessible, to better handle features like pre-releases and other types of version
64
+ /// modifiers. For example, `[(Included(3u32), Excluded(7u32))]` and
65
+ /// `[(Included(3u32), Included(6u32))]` refer to the same version set, since there is no version
66
+ /// between 6 and 7, which this crate doesn't know about.
67
+
49
68
#[ derive( Debug , Clone , Eq , PartialEq , Hash ) ]
50
69
#[ cfg_attr( feature = "serde" , derive( serde:: Serialize ) ) ]
51
70
#[ cfg_attr( feature = "serde" , serde( transparent) ) ]
@@ -283,6 +302,7 @@ impl<V: Ord> Ranges<V> {
283
302
}
284
303
}
285
304
305
+ /// See [`Ranges`] for the invariants checked.
286
306
fn check_invariants ( self ) -> Self {
287
307
if cfg ! ( debug_assertions) {
288
308
for p in self . segments . as_slice ( ) . windows ( 2 ) {
0 commit comments