@@ -390,7 +390,7 @@ impl Version {
390390 #[ inline]
391391 pub fn local ( & self ) -> LocalVersionSlice {
392392 match * self . inner {
393- VersionInner :: Small { ref small } => small. local ( ) ,
393+ VersionInner :: Small { ref small } => small. local_slice ( ) ,
394394 VersionInner :: Full { ref full } => full. local . as_slice ( ) ,
395395 }
396396 }
@@ -546,6 +546,11 @@ impl Version {
546546 match value {
547547 LocalVersion :: Segments ( segments) => self . with_local_segments ( segments) ,
548548 LocalVersion :: Max => {
549+ if let VersionInner :: Small { ref mut small } = Arc :: make_mut ( & mut self . inner ) {
550+ if small. set_local ( LocalVersion :: Max ) {
551+ return self ;
552+ }
553+ }
549554 self . make_full ( ) . local = value;
550555 self
551556 }
@@ -559,12 +564,12 @@ impl Version {
559564 #[ inline]
560565 #[ must_use]
561566 pub fn without_local ( mut self ) -> Self {
562- // A "small" version is already guaranteed not to have a local
563- // component, so we only need to do anything if we have a "full"
564- // version.
565- if let VersionInner :: Full { ref mut full } = Arc :: make_mut ( & mut self . inner ) {
566- full. local . clear ( ) ;
567+ if let VersionInner :: Small { ref mut small } = Arc :: make_mut ( & mut self . inner ) {
568+ if small. set_local ( LocalVersion :: empty ( ) ) {
569+ return self ;
570+ }
567571 }
572+ self . make_full ( ) . local = LocalVersion :: empty ( ) ;
568573 self
569574 }
570575
@@ -628,7 +633,7 @@ impl Version {
628633 pre : small. pre ( ) ,
629634 post : small. post ( ) ,
630635 dev : small. dev ( ) ,
631- local : LocalVersion :: Segments ( vec ! [ ] ) ,
636+ local : small . local ( ) ,
632637 } ;
633638 * self = Self {
634639 inner : Arc :: new ( VersionInner :: Full { full } ) ,
@@ -846,16 +851,16 @@ impl FromStr for Version {
846851/// * Bytes 5, 4 and 3 correspond to the second, third and fourth release
847852/// segments, respectively.
848853/// * Bytes 2, 1 and 0 represent *one* of the following:
849- /// `min, .devN, aN, bN, rcN, <no suffix>, .postN, max`.
854+ /// `min, .devN, aN, bN, rcN, <no suffix>, local, .postN, max`.
850855/// Its representation is thus:
851- /// * The most significant 3 bits of Byte 2 corresponds to a value in
852- /// the range 0-7 inclusive, corresponding to min, dev, pre-a, pre-b,
856+ /// * The most significant 4 bits of Byte 2 corresponds to a value in
857+ /// the range 0-8 inclusive, corresponding to min, dev, pre-a, pre-b,
853858/// pre-rc, no-suffix, post or max releases, respectively. `min` is a
854859/// special version that does not exist in PEP 440, but is used here to
855860/// represent the smallest possible version, preceding any `dev`, `pre`,
856861/// `post` or releases. `max` is an analogous concept for the largest
857862/// possible version, following any `post` or local releases.
858- /// * The low 5 bits combined with the bits in bytes 1 and 0 correspond
863+ /// * The low 4 bits combined with the bits in bytes 1 and 0 correspond
859864/// to the release number of the suffix, if one exists. If there is no
860865/// suffix, then these bits are always 0.
861866///
@@ -933,8 +938,9 @@ impl VersionSmall {
933938 const SUFFIX_PRE_BETA : u64 = 3 ;
934939 const SUFFIX_PRE_RC : u64 = 4 ;
935940 const SUFFIX_NONE : u64 = 5 ;
936- const SUFFIX_POST : u64 = 6 ;
937- const SUFFIX_MAX : u64 = 7 ;
941+ const SUFFIX_LOCAL : u64 = 6 ;
942+ const SUFFIX_POST : u64 = 7 ;
943+ const SUFFIX_MAX : u64 = 8 ;
938944
939945 // The mask to get only the release segment bits.
940946 //
@@ -943,16 +949,16 @@ impl VersionSmall {
943949 // `Parser::parse_fast`.
944950 const SUFFIX_RELEASE_MASK : u64 = 0xFFFF_FFFF_FF00_0000 ;
945951 // The mask to get the version suffix.
946- const SUFFIX_VERSION_MASK : u64 = 0x001F_FFFF ;
952+ const SUFFIX_VERSION_MASK : u64 = 0x000F_FFFF ;
947953 // The number of bits used by the version suffix. Shifting the `repr`
948954 // right by this number of bits should put the suffix kind in the least
949955 // significant bits.
950- const SUFFIX_VERSION_BIT_LEN : u64 = 21 ;
956+ const SUFFIX_VERSION_BIT_LEN : u64 = 20 ;
951957 // The mask to get only the suffix kind, after shifting right by the
952958 // version bits. If you need to add a bit here, then you'll probably need
953959 // to take a bit from the suffix version. (Which requires a change to both
954960 // the mask and the bit length above.)
955- const SUFFIX_KIND_MASK : u64 = 0b111 ;
961+ const SUFFIX_KIND_MASK : u64 = 0b1111 ;
956962
957963 #[ inline]
958964 fn new ( ) -> Self {
@@ -1026,11 +1032,8 @@ impl VersionSmall {
10261032
10271033 #[ inline]
10281034 fn set_post ( & mut self , value : Option < u64 > ) -> bool {
1029- if self . min ( ) . is_some ( )
1030- || self . pre ( ) . is_some ( )
1031- || self . dev ( ) . is_some ( )
1032- || self . max ( ) . is_some ( )
1033- {
1035+ let suffix_kind = self . suffix_kind ( ) ;
1036+ if !( suffix_kind == Self :: SUFFIX_NONE || suffix_kind == Self :: SUFFIX_POST ) {
10341037 return value. is_none ( ) ;
10351038 }
10361039 match value {
@@ -1073,10 +1076,11 @@ impl VersionSmall {
10731076
10741077 #[ inline]
10751078 fn set_pre ( & mut self , value : Option < Prerelease > ) -> bool {
1076- if self . min ( ) . is_some ( )
1077- || self . dev ( ) . is_some ( )
1078- || self . post ( ) . is_some ( )
1079- || self . max ( ) . is_some ( )
1079+ let suffix_kind = self . suffix_kind ( ) ;
1080+ if !( suffix_kind == Self :: SUFFIX_NONE
1081+ || suffix_kind == Self :: SUFFIX_PRE_ALPHA
1082+ || suffix_kind == Self :: SUFFIX_PRE_BETA
1083+ || suffix_kind == Self :: SUFFIX_PRE_RC )
10801084 {
10811085 return value. is_none ( ) ;
10821086 }
@@ -1116,11 +1120,8 @@ impl VersionSmall {
11161120
11171121 #[ inline]
11181122 fn set_dev ( & mut self , value : Option < u64 > ) -> bool {
1119- if self . min ( ) . is_some ( )
1120- || self . pre ( ) . is_some ( )
1121- || self . post ( ) . is_some ( )
1122- || self . max ( ) . is_some ( )
1123- {
1123+ let suffix_kind = self . suffix_kind ( ) ;
1124+ if !( suffix_kind == Self :: SUFFIX_NONE || suffix_kind == Self :: SUFFIX_DEV ) {
11241125 return value. is_none ( ) ;
11251126 }
11261127 match value {
@@ -1149,11 +1150,8 @@ impl VersionSmall {
11491150
11501151 #[ inline]
11511152 fn set_min ( & mut self , value : Option < u64 > ) -> bool {
1152- if self . dev ( ) . is_some ( )
1153- || self . pre ( ) . is_some ( )
1154- || self . post ( ) . is_some ( )
1155- || self . max ( ) . is_some ( )
1156- {
1153+ let suffix_kind = self . suffix_kind ( ) ;
1154+ if !( suffix_kind == Self :: SUFFIX_NONE || suffix_kind == Self :: SUFFIX_MIN ) {
11571155 return value. is_none ( ) ;
11581156 }
11591157 match value {
@@ -1182,11 +1180,8 @@ impl VersionSmall {
11821180
11831181 #[ inline]
11841182 fn set_max ( & mut self , value : Option < u64 > ) -> bool {
1185- if self . dev ( ) . is_some ( )
1186- || self . pre ( ) . is_some ( )
1187- || self . post ( ) . is_some ( )
1188- || self . min ( ) . is_some ( )
1189- {
1183+ let suffix_kind = self . suffix_kind ( ) ;
1184+ if !( suffix_kind == Self :: SUFFIX_NONE || suffix_kind == Self :: SUFFIX_MAX ) {
11901185 return value. is_none ( ) ;
11911186 }
11921187 match value {
@@ -1205,11 +1200,40 @@ impl VersionSmall {
12051200 }
12061201
12071202 #[ inline]
1208- #[ allow( clippy:: unused_self) ]
1209- fn local ( & self ) -> LocalVersionSlice {
1210- // A "small" version is never used if the version has a non-zero number
1211- // of local segments.
1212- LocalVersionSlice :: Segments ( & [ ] )
1203+ fn local ( & self ) -> LocalVersion {
1204+ if self . suffix_kind ( ) == Self :: SUFFIX_LOCAL {
1205+ LocalVersion :: Max
1206+ } else {
1207+ LocalVersion :: empty ( )
1208+ }
1209+ }
1210+
1211+ #[ inline]
1212+ fn local_slice ( & self ) -> LocalVersionSlice {
1213+ if self . suffix_kind ( ) == Self :: SUFFIX_LOCAL {
1214+ LocalVersionSlice :: Max
1215+ } else {
1216+ LocalVersionSlice :: empty ( )
1217+ }
1218+ }
1219+
1220+ #[ inline]
1221+ fn set_local ( & mut self , value : LocalVersion ) -> bool {
1222+ let suffix_kind = self . suffix_kind ( ) ;
1223+ if !( suffix_kind == Self :: SUFFIX_NONE || suffix_kind == Self :: SUFFIX_LOCAL ) {
1224+ return value. is_empty ( ) ;
1225+ }
1226+ match value {
1227+ LocalVersion :: Max => {
1228+ self . set_suffix_kind ( Self :: SUFFIX_LOCAL ) ;
1229+ true
1230+ }
1231+ LocalVersion :: Segments ( segments) if segments. is_empty ( ) => {
1232+ self . set_suffix_kind ( Self :: SUFFIX_NONE ) ;
1233+ true
1234+ }
1235+ LocalVersion :: Segments ( _) => false ,
1236+ }
12131237 }
12141238
12151239 #[ inline]
@@ -1224,7 +1248,7 @@ impl VersionSmall {
12241248 debug_assert ! ( kind <= Self :: SUFFIX_MAX ) ;
12251249 self . repr &= !( Self :: SUFFIX_KIND_MASK << Self :: SUFFIX_VERSION_BIT_LEN ) ;
12261250 self . repr |= kind << Self :: SUFFIX_VERSION_BIT_LEN ;
1227- if kind == Self :: SUFFIX_NONE {
1251+ if kind == Self :: SUFFIX_NONE || kind == Self :: SUFFIX_LOCAL {
12281252 self . set_suffix_version ( 0 ) ;
12291253 }
12301254 }
@@ -1450,6 +1474,19 @@ pub enum LocalVersionSlice<'a> {
14501474}
14511475
14521476impl LocalVersion {
1477+ /// Return an empty local version.
1478+ pub fn empty ( ) -> Self {
1479+ Self :: Segments ( Vec :: new ( ) )
1480+ }
1481+
1482+ /// Returns `true` if the local version is empty.
1483+ pub fn is_empty ( & self ) -> bool {
1484+ match self {
1485+ Self :: Segments ( segments) => segments. is_empty ( ) ,
1486+ Self :: Max => false ,
1487+ }
1488+ }
1489+
14531490 /// Convert the local version segments into a slice.
14541491 pub fn as_slice ( & self ) -> LocalVersionSlice < ' _ > {
14551492 match self {
@@ -1506,7 +1543,12 @@ impl Ord for LocalVersionSlice<'_> {
15061543}
15071544
15081545impl LocalVersionSlice < ' _ > {
1509- /// Whether the local version is absent
1546+ /// Return an empty local version.
1547+ pub const fn empty ( ) -> Self {
1548+ Self :: Segments ( & [ ] )
1549+ }
1550+
1551+ /// Returns `true` if the local version is empty.
15101552 pub fn is_empty ( & self ) -> bool {
15111553 matches ! ( self , Self :: Segments ( & [ ] ) )
15121554 }
0 commit comments