@@ -390,7 +390,7 @@ impl Version {
390
390
#[ inline]
391
391
pub fn local ( & self ) -> LocalVersionSlice {
392
392
match * self . inner {
393
- VersionInner :: Small { ref small } => small. local ( ) ,
393
+ VersionInner :: Small { ref small } => small. local_slice ( ) ,
394
394
VersionInner :: Full { ref full } => full. local . as_slice ( ) ,
395
395
}
396
396
}
@@ -546,6 +546,11 @@ impl Version {
546
546
match value {
547
547
LocalVersion :: Segments ( segments) => self . with_local_segments ( segments) ,
548
548
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
+ }
549
554
self . make_full ( ) . local = value;
550
555
self
551
556
}
@@ -559,12 +564,12 @@ impl Version {
559
564
#[ inline]
560
565
#[ must_use]
561
566
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
+ }
567
571
}
572
+ self . make_full ( ) . local = LocalVersion :: empty ( ) ;
568
573
self
569
574
}
570
575
@@ -628,7 +633,7 @@ impl Version {
628
633
pre : small. pre ( ) ,
629
634
post : small. post ( ) ,
630
635
dev : small. dev ( ) ,
631
- local : LocalVersion :: Segments ( vec ! [ ] ) ,
636
+ local : small . local ( ) ,
632
637
} ;
633
638
* self = Self {
634
639
inner : Arc :: new ( VersionInner :: Full { full } ) ,
@@ -846,16 +851,16 @@ impl FromStr for Version {
846
851
/// * Bytes 5, 4 and 3 correspond to the second, third and fourth release
847
852
/// segments, respectively.
848
853
/// * 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`.
850
855
/// 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,
853
858
/// pre-rc, no-suffix, post or max releases, respectively. `min` is a
854
859
/// special version that does not exist in PEP 440, but is used here to
855
860
/// represent the smallest possible version, preceding any `dev`, `pre`,
856
861
/// `post` or releases. `max` is an analogous concept for the largest
857
862
/// 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
859
864
/// to the release number of the suffix, if one exists. If there is no
860
865
/// suffix, then these bits are always 0.
861
866
///
@@ -933,8 +938,9 @@ impl VersionSmall {
933
938
const SUFFIX_PRE_BETA : u64 = 3 ;
934
939
const SUFFIX_PRE_RC : u64 = 4 ;
935
940
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 ;
938
944
939
945
// The mask to get only the release segment bits.
940
946
//
@@ -943,16 +949,16 @@ impl VersionSmall {
943
949
// `Parser::parse_fast`.
944
950
const SUFFIX_RELEASE_MASK : u64 = 0xFFFF_FFFF_FF00_0000 ;
945
951
// The mask to get the version suffix.
946
- const SUFFIX_VERSION_MASK : u64 = 0x001F_FFFF ;
952
+ const SUFFIX_VERSION_MASK : u64 = 0x000F_FFFF ;
947
953
// The number of bits used by the version suffix. Shifting the `repr`
948
954
// right by this number of bits should put the suffix kind in the least
949
955
// significant bits.
950
- const SUFFIX_VERSION_BIT_LEN : u64 = 21 ;
956
+ const SUFFIX_VERSION_BIT_LEN : u64 = 20 ;
951
957
// The mask to get only the suffix kind, after shifting right by the
952
958
// version bits. If you need to add a bit here, then you'll probably need
953
959
// to take a bit from the suffix version. (Which requires a change to both
954
960
// the mask and the bit length above.)
955
- const SUFFIX_KIND_MASK : u64 = 0b111 ;
961
+ const SUFFIX_KIND_MASK : u64 = 0b1111 ;
956
962
957
963
#[ inline]
958
964
fn new ( ) -> Self {
@@ -1026,11 +1032,8 @@ impl VersionSmall {
1026
1032
1027
1033
#[ inline]
1028
1034
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 ) {
1034
1037
return value. is_none ( ) ;
1035
1038
}
1036
1039
match value {
@@ -1073,10 +1076,11 @@ impl VersionSmall {
1073
1076
1074
1077
#[ inline]
1075
1078
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 )
1080
1084
{
1081
1085
return value. is_none ( ) ;
1082
1086
}
@@ -1116,11 +1120,8 @@ impl VersionSmall {
1116
1120
1117
1121
#[ inline]
1118
1122
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 ) {
1124
1125
return value. is_none ( ) ;
1125
1126
}
1126
1127
match value {
@@ -1149,11 +1150,8 @@ impl VersionSmall {
1149
1150
1150
1151
#[ inline]
1151
1152
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 ) {
1157
1155
return value. is_none ( ) ;
1158
1156
}
1159
1157
match value {
@@ -1182,11 +1180,8 @@ impl VersionSmall {
1182
1180
1183
1181
#[ inline]
1184
1182
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 ) {
1190
1185
return value. is_none ( ) ;
1191
1186
}
1192
1187
match value {
@@ -1205,11 +1200,40 @@ impl VersionSmall {
1205
1200
}
1206
1201
1207
1202
#[ 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
+ }
1213
1237
}
1214
1238
1215
1239
#[ inline]
@@ -1224,7 +1248,7 @@ impl VersionSmall {
1224
1248
debug_assert ! ( kind <= Self :: SUFFIX_MAX ) ;
1225
1249
self . repr &= !( Self :: SUFFIX_KIND_MASK << Self :: SUFFIX_VERSION_BIT_LEN ) ;
1226
1250
self . repr |= kind << Self :: SUFFIX_VERSION_BIT_LEN ;
1227
- if kind == Self :: SUFFIX_NONE {
1251
+ if kind == Self :: SUFFIX_NONE || kind == Self :: SUFFIX_LOCAL {
1228
1252
self . set_suffix_version ( 0 ) ;
1229
1253
}
1230
1254
}
@@ -1450,6 +1474,19 @@ pub enum LocalVersionSlice<'a> {
1450
1474
}
1451
1475
1452
1476
impl 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
+
1453
1490
/// Convert the local version segments into a slice.
1454
1491
pub fn as_slice ( & self ) -> LocalVersionSlice < ' _ > {
1455
1492
match self {
@@ -1506,7 +1543,12 @@ impl Ord for LocalVersionSlice<'_> {
1506
1543
}
1507
1544
1508
1545
impl 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.
1510
1552
pub fn is_empty ( & self ) -> bool {
1511
1553
matches ! ( self , Self :: Segments ( & [ ] ) )
1512
1554
}
0 commit comments