@@ -109,9 +109,13 @@ impl TomlLockfileSourceId {
109
109
EncodableSourceIdError ( EncodableSourceIdErrorKind :: InvalidSource ( source. clone ( ) ) . into ( ) )
110
110
} ) ?;
111
111
112
- let url = Url :: parse ( url) . map_err ( |msg| EncodableSourceIdErrorKind :: InvalidUrl {
113
- url : url. to_string ( ) ,
114
- msg : msg. to_string ( ) ,
112
+ // Sparse URLs store the kind prefix (sparse+) in the URL. Therefore, for sparse kinds, we
113
+ // want to use the raw `source` instead of the splitted `url`.
114
+ let url = Url :: parse ( if kind == "sparse" { & source } else { url } ) . map_err ( |msg| {
115
+ EncodableSourceIdErrorKind :: InvalidUrl {
116
+ url : url. to_string ( ) ,
117
+ msg : msg. to_string ( ) ,
118
+ }
115
119
} ) ?;
116
120
117
121
let kind = match kind {
@@ -317,3 +321,83 @@ fn dump_lockfile_schema() {
317
321
let dump = serde_json:: to_string_pretty ( & schema) . unwrap ( ) ;
318
322
snapbox:: assert_data_eq!( dump, snapbox:: file!( "../lockfile.schema.json" ) . raw( ) ) ;
319
323
}
324
+
325
+ #[ cfg( test) ]
326
+ mod tests {
327
+ use crate :: core:: { GitReference , SourceKind } ;
328
+ use crate :: lockfile:: { EncodableSourceIdErrorKind , TomlLockfileSourceId } ;
329
+
330
+ #[ track_caller]
331
+ fn ok ( source_str : & str , source_kind : SourceKind , url : & str ) {
332
+ let source_str = source_str. to_owned ( ) ;
333
+ let source_id = TomlLockfileSourceId :: new ( source_str) . unwrap ( ) ;
334
+ assert_eq ! ( source_id. kind, source_kind) ;
335
+ assert_eq ! ( source_id. url( ) . to_string( ) , url) ;
336
+ }
337
+
338
+ macro_rules! err {
339
+ ( $src: expr, $expected: pat) => {
340
+ let kind = TomlLockfileSourceId :: new( $src. to_owned( ) ) . unwrap_err( ) . 0 ;
341
+ assert!(
342
+ matches!( kind, $expected) ,
343
+ "`{}` parse error mismatch, got {kind:?}" ,
344
+ $src,
345
+ ) ;
346
+ } ;
347
+ }
348
+
349
+ #[ test]
350
+ fn good_sources ( ) {
351
+ ok (
352
+ "sparse+https://my-crates.io" ,
353
+ SourceKind :: SparseRegistry ,
354
+ "sparse+https://my-crates.io" ,
355
+ ) ;
356
+ ok (
357
+ "registry+https://github.com/rust-lang/crates.io-index" ,
358
+ SourceKind :: Registry ,
359
+ "https://github.com/rust-lang/crates.io-index" ,
360
+ ) ;
361
+ ok (
362
+ "git+https://github.com/rust-lang/cargo" ,
363
+ SourceKind :: Git ( GitReference :: DefaultBranch ) ,
364
+ "https://github.com/rust-lang/cargo" ,
365
+ ) ;
366
+ ok (
367
+ "git+https://github.com/rust-lang/cargo?branch=dev" ,
368
+ SourceKind :: Git ( GitReference :: Branch ( "dev" . to_owned ( ) ) ) ,
369
+ "https://github.com/rust-lang/cargo?branch=dev" ,
370
+ ) ;
371
+ ok (
372
+ "git+https://github.com/rust-lang/cargo?tag=v1.0" ,
373
+ SourceKind :: Git ( GitReference :: Tag ( "v1.0" . to_owned ( ) ) ) ,
374
+ "https://github.com/rust-lang/cargo?tag=v1.0" ,
375
+ ) ;
376
+ ok (
377
+ "git+https://github.com/rust-lang/cargo?rev=refs/pull/493/head" ,
378
+ SourceKind :: Git ( GitReference :: Rev ( "refs/pull/493/head" . to_owned ( ) ) ) ,
379
+ "https://github.com/rust-lang/cargo?rev=refs/pull/493/head" ,
380
+ ) ;
381
+ ok (
382
+ "path+file:///path/to/root" ,
383
+ SourceKind :: Path ,
384
+ "file:///path/to/root" ,
385
+ ) ;
386
+ }
387
+
388
+ #[ test]
389
+ fn bad_sources ( ) {
390
+ err ! (
391
+ "unknown+https://my-crates.io" ,
392
+ EncodableSourceIdErrorKind :: UnsupportedSource ( ..)
393
+ ) ;
394
+ err ! (
395
+ "registry+https//github.com/rust-lang/crates.io-index" ,
396
+ EncodableSourceIdErrorKind :: InvalidUrl { .. }
397
+ ) ;
398
+ err ! (
399
+ "https//github.com/rust-lang/crates.io-index" ,
400
+ EncodableSourceIdErrorKind :: InvalidSource ( ..)
401
+ ) ;
402
+ }
403
+ }
0 commit comments