@@ -10,7 +10,8 @@ use crate::core::PackageId;
10
10
use crate :: util:: edit_distance;
11
11
use crate :: util:: errors:: CargoResult ;
12
12
use crate :: util:: interning:: InternedString ;
13
- use crate :: util:: { validate_package_name, IntoUrl , ToSemver } ;
13
+ use crate :: util:: PartialVersion ;
14
+ use crate :: util:: { validate_package_name, IntoUrl } ;
14
15
15
16
/// Some or all of the data required to identify a package:
16
17
///
@@ -24,7 +25,7 @@ use crate::util::{validate_package_name, IntoUrl, ToSemver};
24
25
#[ derive( Clone , PartialEq , Eq , Debug , Hash , Ord , PartialOrd ) ]
25
26
pub struct PackageIdSpec {
26
27
name : InternedString ,
27
- version : Option < Version > ,
28
+ version : Option < PartialVersion > ,
28
29
url : Option < Url > ,
29
30
}
30
31
@@ -70,7 +71,7 @@ impl PackageIdSpec {
70
71
let mut parts = spec. splitn ( 2 , [ ':' , '@' ] ) ;
71
72
let name = parts. next ( ) . unwrap ( ) ;
72
73
let version = match parts. next ( ) {
73
- Some ( version) => Some ( version. to_semver ( ) ?) ,
74
+ Some ( version) => Some ( version. parse :: < PartialVersion > ( ) ?) ,
74
75
None => None ,
75
76
} ;
76
77
validate_package_name ( name, "pkgid" , "" ) ?;
@@ -94,12 +95,12 @@ impl PackageIdSpec {
94
95
spec. query ( i)
95
96
}
96
97
97
- /// Convert a `PackageId` to a `PackageIdSpec`, which will have both the `Version ` and `Url`
98
+ /// Convert a `PackageId` to a `PackageIdSpec`, which will have both the `PartialVersion ` and `Url`
98
99
/// fields filled in.
99
100
pub fn from_package_id ( package_id : PackageId ) -> PackageIdSpec {
100
101
PackageIdSpec {
101
102
name : package_id. name ( ) ,
102
- version : Some ( package_id. version ( ) . clone ( ) ) ,
103
+ version : Some ( package_id. version ( ) . clone ( ) . into ( ) ) ,
103
104
url : Some ( package_id. source_id ( ) . url ( ) . clone ( ) ) ,
104
105
}
105
106
}
@@ -128,14 +129,14 @@ impl PackageIdSpec {
128
129
let name_or_version = parts. next ( ) . unwrap ( ) ;
129
130
match parts. next ( ) {
130
131
Some ( part) => {
131
- let version = part. to_semver ( ) ?;
132
+ let version = part. parse :: < PartialVersion > ( ) ?;
132
133
( InternedString :: new ( name_or_version) , Some ( version) )
133
134
}
134
135
None => {
135
136
if name_or_version. chars ( ) . next ( ) . unwrap ( ) . is_alphabetic ( ) {
136
137
( InternedString :: new ( name_or_version) , None )
137
138
} else {
138
- let version = name_or_version. to_semver ( ) ?;
139
+ let version = name_or_version. parse :: < PartialVersion > ( ) ?;
139
140
( InternedString :: new ( path_name) , Some ( version) )
140
141
}
141
142
}
@@ -155,8 +156,9 @@ impl PackageIdSpec {
155
156
self . name
156
157
}
157
158
158
- pub fn version ( & self ) -> Option < & Version > {
159
- self . version . as_ref ( )
159
+ /// Full `semver::Version`, if present
160
+ pub fn version ( & self ) -> Option < Version > {
161
+ self . version . as_ref ( ) . and_then ( |v| v. version ( ) )
160
162
}
161
163
162
164
pub fn url ( & self ) -> Option < & Url > {
@@ -174,7 +176,8 @@ impl PackageIdSpec {
174
176
}
175
177
176
178
if let Some ( ref v) = self . version {
177
- if v != package_id. version ( ) {
179
+ let req = v. exact_req ( ) ;
180
+ if !req. matches ( package_id. version ( ) ) {
178
181
return false ;
179
182
}
180
183
}
@@ -326,7 +329,6 @@ mod tests {
326
329
use super :: PackageIdSpec ;
327
330
use crate :: core:: { PackageId , SourceId } ;
328
331
use crate :: util:: interning:: InternedString ;
329
- use crate :: util:: ToSemver ;
330
332
use url:: Url ;
331
333
332
334
#[ test]
@@ -351,16 +353,25 @@ mod tests {
351
353
"https://crates.io/foo#1.2.3" ,
352
354
PackageIdSpec {
353
355
name : InternedString :: new ( "foo" ) ,
354
- version : Some ( "1.2.3" . to_semver ( ) . unwrap ( ) ) ,
356
+ version : Some ( "1.2.3" . parse ( ) . unwrap ( ) ) ,
355
357
url : Some ( Url :: parse ( "https://crates.io/foo" ) . unwrap ( ) ) ,
356
358
} ,
357
359
"https://crates.io/foo#1.2.3" ,
358
360
) ;
361
+ ok (
362
+ "https://crates.io/foo#1.2" ,
363
+ PackageIdSpec {
364
+ name : InternedString :: new ( "foo" ) ,
365
+ version : Some ( "1.2" . parse ( ) . unwrap ( ) ) ,
366
+ url : Some ( Url :: parse ( "https://crates.io/foo" ) . unwrap ( ) ) ,
367
+ } ,
368
+ "https://crates.io/foo#1.2" ,
369
+ ) ;
359
370
ok (
360
371
"https://crates.io/foo#bar:1.2.3" ,
361
372
PackageIdSpec {
362
373
name : InternedString :: new ( "bar" ) ,
363
- version : Some ( "1.2.3" . to_semver ( ) . unwrap ( ) ) ,
374
+ version : Some ( "1.2.3" . parse ( ) . unwrap ( ) ) ,
364
375
url : Some ( Url :: parse ( "https://crates.io/foo" ) . unwrap ( ) ) ,
365
376
} ,
366
377
"https://crates.io/foo#[email protected] " ,
@@ -369,11 +380,20 @@ mod tests {
369
380
"https://crates.io/foo#[email protected] " ,
370
381
PackageIdSpec {
371
382
name : InternedString :: new ( "bar" ) ,
372
- version : Some ( "1.2.3" . to_semver ( ) . unwrap ( ) ) ,
383
+ version : Some ( "1.2.3" . parse ( ) . unwrap ( ) ) ,
373
384
url : Some ( Url :: parse ( "https://crates.io/foo" ) . unwrap ( ) ) ,
374
385
} ,
375
386
"https://crates.io/foo#[email protected] " ,
376
387
) ;
388
+ ok (
389
+ "https://crates.io/foo#[email protected] " ,
390
+ PackageIdSpec {
391
+ name : InternedString :: new ( "bar" ) ,
392
+ version : Some ( "1.2" . parse ( ) . unwrap ( ) ) ,
393
+ url : Some ( Url :: parse ( "https://crates.io/foo" ) . unwrap ( ) ) ,
394
+ } ,
395
+ "https://crates.io/foo#[email protected] " ,
396
+ ) ;
377
397
ok (
378
398
"foo" ,
379
399
PackageIdSpec {
@@ -387,7 +407,7 @@ mod tests {
387
407
"foo:1.2.3" ,
388
408
PackageIdSpec {
389
409
name : InternedString :: new ( "foo" ) ,
390
- version : Some ( "1.2.3" . to_semver ( ) . unwrap ( ) ) ,
410
+ version : Some ( "1.2.3" . parse ( ) . unwrap ( ) ) ,
391
411
url : None ,
392
412
} ,
393
413
@@ -396,21 +416,29 @@ mod tests {
396
416
397
417
PackageIdSpec {
398
418
name : InternedString :: new ( "foo" ) ,
399
- version : Some ( "1.2.3" . to_semver ( ) . unwrap ( ) ) ,
419
+ version : Some ( "1.2.3" . parse ( ) . unwrap ( ) ) ,
400
420
url : None ,
401
421
} ,
402
422
403
423
) ;
424
+ ok (
425
+
426
+ PackageIdSpec {
427
+ name : InternedString :: new ( "foo" ) ,
428
+ version : Some ( "1.2" . parse ( ) . unwrap ( ) ) ,
429
+ url : None ,
430
+ } ,
431
+
432
+ ) ;
404
433
}
405
434
406
435
#[ test]
407
436
fn bad_parsing ( ) {
408
437
assert ! ( PackageIdSpec :: parse( "baz:" ) . is_err( ) ) ;
409
438
assert ! ( PackageIdSpec :: parse( "baz:*" ) . is_err( ) ) ;
410
- assert ! ( PackageIdSpec :: parse( "baz:1.0" ) . is_err( ) ) ;
411
439
assert ! ( PackageIdSpec :: parse( "baz@" ) . is_err( ) ) ;
412
440
assert ! ( PackageIdSpec :: parse( "baz@*" ) . is_err( ) ) ;
413
- assert ! ( PackageIdSpec :: parse
( "[email protected] " ) . is_err
( ) ) ;
441
+ assert ! ( PackageIdSpec :: parse( "baz@^ 1.0" ) . is_err( ) ) ;
414
442
assert ! ( PackageIdSpec :: parse( "https://baz:1.0" ) . is_err( ) ) ;
415
443
assert ! ( PackageIdSpec :: parse( "https://#baz:1.0" ) . is_err( ) ) ;
416
444
}
@@ -428,5 +456,6 @@ mod tests {
428
456
assert ! ( !PackageIdSpec :: parse( "foo:1.2.2" ) . unwrap( ) . matches( foo) ) ;
429
457
assert ! ( PackageIdSpec :: parse
( "[email protected] " ) . unwrap
( ) . matches
( foo
) ) ;
430
458
assert ! ( !
PackageIdSpec :: parse
( "[email protected] " ) . unwrap
( ) . matches
( foo
) ) ;
459
+ assert ! ( PackageIdSpec :: parse
( "[email protected] " ) . unwrap
( ) . matches
( foo
) ) ;
431
460
}
432
461
}
0 commit comments