@@ -61,30 +61,7 @@ impl fmt::Display for Version {
6161
6262impl PartialOrd for Version {
6363 fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
64- if Self :: error_if_comparator_operator_not_supported ( & self . req ) . is_err ( ) {
65- return None ;
66- }
67- // Wildcard and multiple version requirements not yet implemented - `new()` should not yet
68- // let them be created
69- debug_assert ! ( self . req. comparators. len( ) == 1 && other. req. comparators. len( ) == 1 ) ;
70-
71- let range = self . range ( ) ;
72- let other_range = other. range ( ) ;
73- if range == other_range {
74- Some ( Ordering :: Equal )
75- } else if range. end <= other_range. start
76- || ( range. start < other_range. start && range. end == other_range. end )
77- || ( range. start == other_range. start && range. end < other_range. end )
78- {
79- Some ( Ordering :: Less )
80- } else if range. start >= other_range. end
81- || ( range. start > other_range. start && range. end == other_range. end )
82- || ( range. start == other_range. start && range. end > other_range. end )
83- {
84- Some ( Ordering :: Greater )
85- } else {
86- None
87- }
64+ Version :: range_compare ( & self . comparator_ranges ( ) , & other. comparator_ranges ( ) )
8865 }
8966}
9067
@@ -100,11 +77,29 @@ impl Version {
10077 pub fn new ( version_number : & str ) -> Result < Self , String > {
10178 let req = VersionReq :: parse ( version_number) . map_err ( |error| format ! ( "{error}" ) ) ?;
10279
103- let ( ) = Self :: error_if_comparator_operator_not_supported ( & req) ?;
80+ // let () = Self::error_if_comparator_operator_not_supported(&req)?;
10481
10582 Ok ( Self { req } )
10683 }
10784
85+ fn range_compare ( a : & Range < semver:: Version > , b : & Range < semver:: Version > ) -> Option < Ordering > {
86+ if a == b {
87+ Some ( Ordering :: Equal )
88+ } else if a. end <= b. start
89+ || ( a. start < b. start && a. end == b. end )
90+ || ( a. start == b. start && a. end < b. end )
91+ {
92+ Some ( Ordering :: Less )
93+ } else if a. start >= b. end
94+ || ( a. start > b. start && a. end == b. end )
95+ || ( a. start == b. start && a. end > b. end )
96+ {
97+ Some ( Ordering :: Greater )
98+ } else {
99+ None
100+ }
101+ }
102+
108103 fn version_with_bumped_major ( major : u64 ) -> semver:: Version {
109104 semver:: Version {
110105 major : major
@@ -311,7 +306,7 @@ impl Version {
311306 // <I.J.K
312307 Range {
313308 start,
314- end : Self :: version_with_bumped_patch ( major, minor_version, patch_version) ,
309+ end : semver :: Version :: new ( major, minor_version, patch_version) ,
315310 }
316311 } else {
317312 // <I.J
@@ -404,30 +399,60 @@ impl Version {
404399 }
405400 }
406401
407- fn range ( & self ) -> Range < semver:: Version > {
408- let first_comparator = self . req . comparators . first ( ) . unwrap ( ) ;
402+ /// Returns a vector containing the ranges for each comparator. Collapses all ranges into a
403+ /// single one if possible. If collapsing to a single range is not possible, no attempt is
404+ /// made to collapse any pairs of elements, which could feasibly be collapsed. Result is
405+ /// sorted by increasing range starts.
406+ fn comparator_ranges ( & self ) -> Range < semver:: Version > {
407+ debug_assert ! ( !self . req. comparators. is_empty( ) ) ;
408+
409+ let mut start = semver:: Version :: new ( 0 , 0 , 0 ) ;
410+ let mut end = semver:: Version :: new ( u64:: MAX , u64:: MAX , u64:: MAX ) ;
411+ for comparator in & self . req . comparators {
412+ let Comparator {
413+ op,
414+ major,
415+ minor,
416+ patch,
417+ ..
418+ } = comparator;
419+ let range = match op {
420+ Op :: Exact => Self :: exact_range ( * major, * minor, * patch) ,
421+ Op :: Greater => Self :: greater_range ( * major, * minor, * patch) ,
422+ Op :: GreaterEq => Self :: greater_or_equal_range ( * major, * minor, * patch) ,
423+ Op :: Less => Self :: less_range ( * major, * minor, * patch) ,
424+ Op :: LessEq => Self :: less_or_equal_range ( * major, * minor, * patch) ,
425+ Op :: Tilde => Self :: tilde_range ( * major, * minor, * patch) ,
426+ Op :: Caret => Self :: caret_range ( * major, * minor, * patch) ,
427+ Op :: Wildcard => Self :: wildcard_range ( * major, * minor, * patch) ,
428+ _ => unimplemented ! ( ) ,
429+ } ;
430+
431+ match op {
432+ Op :: Exact | Op :: Tilde | Op :: Caret | Op :: Wildcard | Op :: Greater | Op :: GreaterEq => {
433+ if range. start > start {
434+ start = range. start ;
435+ }
436+ }
437+ _ => { }
438+ }
439+ match op {
440+ Op :: Exact | Op :: Tilde | Op :: Caret | Op :: Wildcard | Op :: Less | Op :: LessEq => {
441+ if range. end < end {
442+ end = range. end ;
443+ }
444+ }
445+ _ => { }
446+ }
447+ }
409448
410- let Comparator {
411- op,
412- major,
413- minor,
414- patch,
415- ..
416- } = first_comparator;
417- match op {
418- Op :: Caret => Self :: caret_range ( * major, * minor, * patch) ,
419- Op :: Exact => Self :: exact_range ( * major, * minor, * patch) ,
420- Op :: Greater => Self :: greater_range ( * major, * minor, * patch) ,
421- Op :: GreaterEq => Self :: greater_or_equal_range ( * major, * minor, * patch) ,
422- Op :: Less => Self :: less_range ( * major, * minor, * patch) ,
423- Op :: LessEq => Self :: less_or_equal_range ( * major, * minor, * patch) ,
424- Op :: Tilde => Self :: tilde_range ( * major, * minor, * patch) ,
425- Op :: Wildcard => Self :: wildcard_range ( * major, * minor, * patch) ,
426- _ => unimplemented ! (
427- "Ranges only implemented for caret, exact, greater than, greater than or equal, \
428- less than, less than or equal, tilde and wildcard requirements."
429- ) ,
449+ if end < start {
450+ log:: error!(
451+ "Unexpected invalid range requirement: {:?}" ,
452+ self . req. comparators,
453+ ) ;
430454 }
455+ Range { start, end }
431456 }
432457
433458 pub fn change_type ( & self , other : & Self ) -> Change {
@@ -476,28 +501,6 @@ impl Version {
476501 Change :: Unknown
477502 }
478503
479- fn error_if_comparator_operator_not_supported ( req : & VersionReq ) -> Result < ( ) , String > {
480- if req. comparators . len ( ) != 1 {
481- return Err ( String :: from (
482- "Multiple version requirement comparison is not yet implemented" ,
483- ) ) ;
484- }
485- let Comparator { op, .. } = req. comparators . first ( ) . expect ( "Index should be valid" ) ;
486- match op {
487- Op :: Caret
488- | Op :: Exact
489- | Op :: Greater
490- | Op :: GreaterEq
491- | Op :: Less
492- | Op :: LessEq
493- | Op :: Tilde
494- | Op :: Wildcard => Ok ( ( ) ) ,
495- _ => Err ( String :: from (
496- "Unexpected version requirement. Requirement type is not yet implemented" ,
497- ) ) ,
498- }
499- }
500-
501504 fn fmt_comparator_version (
502505 comparator : & Comparator ,
503506 formatter : & mut fmt:: Formatter ,
0 commit comments