1
- use semver:: { Comparator , Op , Version , VersionReq } ;
2
- use serde_untagged:: UntaggedEnumVisitor ;
3
1
use std:: fmt:: { self , Display } ;
4
2
3
+ use semver:: { Op , Version , VersionReq } ;
4
+ use serde_untagged:: UntaggedEnumVisitor ;
5
+
6
+ use crate :: util_semver:: PartialVersion ;
7
+ use crate :: util_semver:: VersionExt as _;
8
+
5
9
#[ derive( PartialEq , Eq , Hash , Clone , Debug ) ]
6
10
pub enum OptVersionReq {
7
11
Any ,
@@ -12,30 +16,6 @@ pub enum OptVersionReq {
12
16
UpdatePrecise ( Version , VersionReq ) ,
13
17
}
14
18
15
- pub trait VersionExt {
16
- fn is_prerelease ( & self ) -> bool ;
17
-
18
- fn to_exact_req ( & self ) -> VersionReq ;
19
- }
20
-
21
- impl VersionExt for Version {
22
- fn is_prerelease ( & self ) -> bool {
23
- !self . pre . is_empty ( )
24
- }
25
-
26
- fn to_exact_req ( & self ) -> VersionReq {
27
- VersionReq {
28
- comparators : vec ! [ Comparator {
29
- op: Op :: Exact ,
30
- major: self . major,
31
- minor: Some ( self . minor) ,
32
- patch: Some ( self . patch) ,
33
- pre: self . pre. clone( ) ,
34
- } ] ,
35
- }
36
- }
37
- }
38
-
39
19
impl OptVersionReq {
40
20
pub fn exact ( version : & Version ) -> Self {
41
21
OptVersionReq :: Req ( version. to_exact_req ( ) )
@@ -190,170 +170,3 @@ impl Display for RustVersion {
190
170
self . 0 . fmt ( f)
191
171
}
192
172
}
193
-
194
- #[ derive( PartialEq , Eq , PartialOrd , Ord , Hash , Clone , Debug ) ]
195
- pub struct PartialVersion {
196
- pub major : u64 ,
197
- pub minor : Option < u64 > ,
198
- pub patch : Option < u64 > ,
199
- pub pre : Option < semver:: Prerelease > ,
200
- pub build : Option < semver:: BuildMetadata > ,
201
- }
202
-
203
- impl PartialVersion {
204
- pub fn to_version ( & self ) -> Option < Version > {
205
- Some ( Version {
206
- major : self . major ,
207
- minor : self . minor ?,
208
- patch : self . patch ?,
209
- pre : self . pre . clone ( ) . unwrap_or_default ( ) ,
210
- build : self . build . clone ( ) . unwrap_or_default ( ) ,
211
- } )
212
- }
213
-
214
- pub fn to_caret_req ( & self ) -> VersionReq {
215
- VersionReq {
216
- comparators : vec ! [ Comparator {
217
- op: semver:: Op :: Caret ,
218
- major: self . major,
219
- minor: self . minor,
220
- patch: self . patch,
221
- pre: self . pre. as_ref( ) . cloned( ) . unwrap_or_default( ) ,
222
- } ] ,
223
- }
224
- }
225
-
226
- /// Check if this matches a version, including build metadata
227
- ///
228
- /// Build metadata does not affect version precedence but may be necessary for uniquely
229
- /// identifying a package.
230
- pub fn matches ( & self , version : & Version ) -> bool {
231
- if !version. pre . is_empty ( ) && self . pre . is_none ( ) {
232
- // Pre-release versions must be explicitly opted into, if for no other reason than to
233
- // give us room to figure out and define the semantics
234
- return false ;
235
- }
236
- self . major == version. major
237
- && self . minor . map ( |f| f == version. minor ) . unwrap_or ( true )
238
- && self . patch . map ( |f| f == version. patch ) . unwrap_or ( true )
239
- && self . pre . as_ref ( ) . map ( |f| f == & version. pre ) . unwrap_or ( true )
240
- && self
241
- . build
242
- . as_ref ( )
243
- . map ( |f| f == & version. build )
244
- . unwrap_or ( true )
245
- }
246
- }
247
-
248
- impl From < semver:: Version > for PartialVersion {
249
- fn from ( ver : semver:: Version ) -> Self {
250
- let pre = if ver. pre . is_empty ( ) {
251
- None
252
- } else {
253
- Some ( ver. pre )
254
- } ;
255
- let build = if ver. build . is_empty ( ) {
256
- None
257
- } else {
258
- Some ( ver. build )
259
- } ;
260
- Self {
261
- major : ver. major ,
262
- minor : Some ( ver. minor ) ,
263
- patch : Some ( ver. patch ) ,
264
- pre,
265
- build,
266
- }
267
- }
268
- }
269
-
270
- impl std:: str:: FromStr for PartialVersion {
271
- type Err = anyhow:: Error ;
272
-
273
- fn from_str ( value : & str ) -> Result < Self , Self :: Err > {
274
- if is_req ( value) {
275
- anyhow:: bail!( "unexpected version requirement, expected a version like \" 1.32\" " )
276
- }
277
- match semver:: Version :: parse ( value) {
278
- Ok ( ver) => Ok ( ver. into ( ) ) ,
279
- Err ( _) => {
280
- // HACK: Leverage `VersionReq` for partial version parsing
281
- let mut version_req = match semver:: VersionReq :: parse ( value) {
282
- Ok ( req) => req,
283
- Err ( _) if value. contains ( '-' ) => {
284
- anyhow:: bail!(
285
- "unexpected prerelease field, expected a version like \" 1.32\" "
286
- )
287
- }
288
- Err ( _) if value. contains ( '+' ) => {
289
- anyhow:: bail!( "unexpected build field, expected a version like \" 1.32\" " )
290
- }
291
- Err ( _) => anyhow:: bail!( "expected a version like \" 1.32\" " ) ,
292
- } ;
293
- assert_eq ! ( version_req. comparators. len( ) , 1 , "guaranteed by is_req" ) ;
294
- let comp = version_req. comparators . pop ( ) . unwrap ( ) ;
295
- assert_eq ! ( comp. op, semver:: Op :: Caret , "guaranteed by is_req" ) ;
296
- let pre = if comp. pre . is_empty ( ) {
297
- None
298
- } else {
299
- Some ( comp. pre )
300
- } ;
301
- Ok ( Self {
302
- major : comp. major ,
303
- minor : comp. minor ,
304
- patch : comp. patch ,
305
- pre,
306
- build : None ,
307
- } )
308
- }
309
- }
310
- }
311
- }
312
-
313
- impl Display for PartialVersion {
314
- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
315
- let major = self . major ;
316
- write ! ( f, "{major}" ) ?;
317
- if let Some ( minor) = self . minor {
318
- write ! ( f, ".{minor}" ) ?;
319
- }
320
- if let Some ( patch) = self . patch {
321
- write ! ( f, ".{patch}" ) ?;
322
- }
323
- if let Some ( pre) = self . pre . as_ref ( ) {
324
- write ! ( f, "-{pre}" ) ?;
325
- }
326
- if let Some ( build) = self . build . as_ref ( ) {
327
- write ! ( f, "+{build}" ) ?;
328
- }
329
- Ok ( ( ) )
330
- }
331
- }
332
-
333
- impl serde:: Serialize for PartialVersion {
334
- fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
335
- where
336
- S : serde:: Serializer ,
337
- {
338
- serializer. collect_str ( self )
339
- }
340
- }
341
-
342
- impl < ' de > serde:: Deserialize < ' de > for PartialVersion {
343
- fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
344
- where
345
- D : serde:: Deserializer < ' de > ,
346
- {
347
- UntaggedEnumVisitor :: new ( )
348
- . expecting ( "SemVer version" )
349
- . string ( |value| value. parse ( ) . map_err ( serde:: de:: Error :: custom) )
350
- . deserialize ( deserializer)
351
- }
352
- }
353
-
354
- fn is_req ( value : & str ) -> bool {
355
- let Some ( first) = value. chars ( ) . next ( ) else {
356
- return false ;
357
- } ;
358
- "<>=^~" . contains ( first) || value. contains ( '*' ) || value. contains ( ',' )
359
- }
0 commit comments