@@ -81,6 +81,9 @@ impl SourceId {
8181 ///
8282 /// The canonical url will be calculated, but the precise field will not
8383 fn new ( kind : SourceKind , url : Url , name : Option < & str > ) -> CargoResult < SourceId > {
84+ if kind == SourceKind :: SparseRegistry {
85+ assert ! ( url. as_str( ) . starts_with( "sparse+" ) ) ;
86+ }
8487 let source_id = SourceId :: wrap ( SourceIdInner {
8588 kind,
8689 canonical_url : CanonicalUrl :: new ( & url) ?,
@@ -152,7 +155,7 @@ impl SourceId {
152155 . with_precise ( Some ( "locked" . to_string ( ) ) ) )
153156 }
154157 "sparse" => {
155- let url = url . into_url ( ) ?;
158+ let url = string . into_url ( ) ?;
156159 Ok ( SourceId :: new ( SourceKind :: SparseRegistry , url, None ) ?
157160 . with_precise ( Some ( "locked" . to_string ( ) ) ) )
158161 }
@@ -721,6 +724,7 @@ impl<'a> fmt::Display for SourceIdAsUrl<'a> {
721724 ref url,
722725 ..
723726 } => {
727+ // Sparse registry URL already includes the `sparse+` prefix
724728 write ! ( f, "{url}" )
725729 }
726730 SourceIdInner {
@@ -864,4 +868,14 @@ mod tests {
864868 assert_eq ! ( gen_hash( source_id) , 17459999773908528552 ) ;
865869 assert_eq ! ( crate :: util:: hex:: short_hash( & source_id) , "6568fe2c2fab5bfe" ) ;
866870 }
871+
872+ #[ test]
873+ fn serde_roundtrip ( ) {
874+ let url = "sparse+https://my-crates.io/" . into_url ( ) . unwrap ( ) ;
875+ let source_id = SourceId :: for_registry ( & url) . unwrap ( ) ;
876+ let formatted = format ! ( "{}" , source_id. as_url( ) ) ;
877+ let deserialized = SourceId :: from_url ( & formatted) . unwrap ( ) ;
878+ assert_eq ! ( formatted, "sparse+https://my-crates.io/" ) ;
879+ assert_eq ! ( source_id, deserialized) ;
880+ }
867881}
0 commit comments