@@ -120,159 +120,88 @@ impl TryFrom<&'_ PackageId> for Crate {
120120 pkgid. repr
121121 ) ,
122122 }
123- } else if pkgid. repr . contains ( "://" ) {
124- // Cargo Package Id Spec URL format
125- // <https://doc.rust-lang.org/cargo/reference/pkgid-spec.html>
126-
127- let pkg_url = url:: Url :: parse ( & pkgid. repr ) ?;
128-
129- let ( kind, proto) = if let Some ( ( kind, proto) ) = pkg_url. scheme ( ) . split_once ( '+' ) {
130- ( Some ( kind) , proto)
131- } else {
132- ( None , pkg_url. scheme ( ) )
133- } ;
134-
135- let anchor = pkg_url. fragment ( ) ;
136- let query = pkg_url. query ( ) ;
137-
138- match ( kind, proto) {
139- ( Some ( "path" ) | None , "file" ) => Ok ( Crate :: Path ( pkg_url. path ( ) . to_string ( ) ) ) ,
140- ( Some ( "registry" ) , _) => {
141- if let Some ( anchor) = anchor {
142- if let Some ( ( package_name, version) ) = anchor. split_once ( [ '@' , ':' ] ) {
143- Ok ( Crate :: Registry ( RegistryCrate {
144- name : package_name. to_string ( ) ,
145- version : version. to_string ( ) ,
146- } ) )
147- } else if !anchor
148- . contains ( |c : char | !c. is_ascii_alphanumeric ( ) && c != '_' && c != '-' )
149- {
150- // anchor appears to be a valid package name
151- Ok ( Crate :: Registry ( RegistryCrate {
152- name : anchor. to_string ( ) ,
153- version : "unknown" . to_string ( ) ,
123+ } else {
124+ use cargo_util_schemas:: core:: * ;
125+
126+ let package_id = PackageIdSpec :: parse ( & pkgid. repr ) ?;
127+
128+ match package_id. kind ( ) {
129+ Some ( SourceKind :: LocalRegistry ) => Ok ( Crate :: Local ( package_id. name ( ) . to_string ( ) ) ) ,
130+ Some ( SourceKind :: Git ( rev) ) => {
131+ if let Some ( url) = package_id. url ( ) {
132+ if url. domain ( ) == Some ( "github.com" ) {
133+ Ok ( Crate :: GitHub ( GitHubRepo {
134+ org : url
135+ . path_segments ( )
136+ . and_then ( |mut path| path. next ( ) )
137+ . unwrap_or_default ( )
138+ . to_string ( ) ,
139+ name : package_id. name ( ) . to_string ( ) ,
140+ sha : rev. pretty_ref ( false ) . map ( |rev| rev. to_string ( ) ) ,
154141 } ) )
155142 } else {
156- // as the anchor is not a valid package name check whether it can be a version
157- let Some ( minor_major_path) = anchor. split ( [ '-' , '+' ] ) . next ( ) else {
158- bail ! ( "split always returns at least one element" )
159- } ;
160-
161- if minor_major_path. split ( '.' ) . count ( ) > 3
162- || minor_major_path
163- . split ( '.' )
164- . any ( |part| part. contains ( |c : char | !c. is_ascii_digit ( ) ) )
165- {
166- bail ! (
167- "malformed pkgid format: {}\n maybe the representation has changed?" ,
168- pkgid. repr
169- )
170- }
171-
172- let Some ( package_name) =
173- pkg_url. path_segments ( ) . and_then ( |segments| segments. last ( ) )
174- else {
175- bail ! (
176- "malformed pkgid format: {}\n maybe the representation has changed?" ,
177- pkgid. repr
178- )
179- } ;
180-
181- Ok ( Crate :: Registry ( RegistryCrate {
182- name : package_name. to_string ( ) ,
183- version : anchor. to_string ( ) ,
143+ Ok ( Crate :: Git ( GitRepo {
144+ url : url. to_string ( ) ,
145+ sha : rev. pretty_ref ( false ) . map ( |rev| rev. to_string ( ) ) ,
184146 } ) )
185147 }
186148 } else {
187- bail ! (
188- "malformed pkgid format: {}\n maybe the representation has changed?" ,
189- pkgid. repr
190- )
149+ bail ! ( "Package Id with SourceKind Git should have a URL" )
191150 }
192151 }
193- ( Some ( "git" ) , _) | ( None , "ssh" | "git" | "http" | "https" ) => {
194- let sha = if let Some ( query) = query {
195- let Some ( ( query_kind, rev) ) = query. split_once ( '=' ) else {
196- bail ! (
197- "malformed pkgid format: {}\n maybe the representation has changed?" ,
198- pkgid. repr
199- )
200- } ;
201- match query_kind {
202- "branch" | "tag" | "rev" => Some ( rev. to_string ( ) ) ,
203- _ => {
204- bail ! (
205- "malformed pkgid format: {}\n maybe the representation has changed?" ,
206- pkgid. repr
207- )
208- }
209- }
210- } else {
211- None
212- } ;
213-
214- if pkg_url. domain ( ) == Some ( "github.com" ) {
215- let Some ( org) = pkg_url
216- . path_segments ( )
217- . and_then ( |mut segments| segments. next ( ) )
218- else {
219- bail ! (
220- "malformed pkgid format: {}\n maybe the representation has changed?" ,
221- pkgid. repr
222- )
223- } ;
224-
225- let name = if let Some ( ( package_name, _version) ) =
226- anchor. and_then ( |anchor| anchor. split_once ( [ '@' , ':' ] ) )
227- {
228- package_name
229- } else if let Some ( name) = pkg_url
230- . path_segments ( )
231- . and_then ( |mut segments| segments. nth ( 1 ) )
232- {
233- name
234- } else {
235- bail ! (
236- "malformed pkgid format: {}\n maybe the representation has changed?" ,
237- pkgid. repr
238- )
239- } ;
240-
241- Ok ( Crate :: GitHub ( GitHubRepo {
242- org : org. to_string ( ) ,
243- name : name. to_string ( ) ,
244- sha,
245- } ) )
152+ Some ( SourceKind :: Path ) => {
153+ if let Some ( url) = package_id. url ( ) {
154+ Ok ( Crate :: Path ( url. path ( ) . to_string ( ) ) )
246155 } else {
247- let mut repo_url = pkg_url. clone ( ) ;
248- repo_url. set_fragment ( None ) ;
249- repo_url. set_query ( None ) ;
250-
251- Ok ( Crate :: Git ( GitRepo {
252- url : repo_url. to_string ( ) ,
253- sha,
254- } ) )
156+ bail ! ( "Package Id with SourceKind Path should have a URL" )
255157 }
256158 }
257- _ => bail ! (
258- "malformed pkgid format: {}\n maybe the representation has changed?" ,
259- pkgid. repr
260- ) ,
159+ Some ( SourceKind :: Registry | SourceKind :: SparseRegistry ) => {
160+ Ok ( Crate :: Registry ( RegistryCrate {
161+ name : package_id. name ( ) . to_string ( ) ,
162+ version : package_id
163+ . version ( )
164+ . map ( |version| version. to_string ( ) )
165+ . unwrap_or_else ( || String :: from ( "unknown" ) ) ,
166+ } ) )
167+ }
168+ Some ( SourceKind :: Directory ) => {
169+ bail ! ( "Unsupported SourceKind Directory" )
170+ }
171+ None => match package_id. url ( ) {
172+ None => Ok ( Crate :: Registry ( RegistryCrate {
173+ name : package_id. name ( ) . to_string ( ) ,
174+ version : package_id
175+ . version ( )
176+ . map ( |version| version. to_string ( ) )
177+ . unwrap_or_else ( || String :: from ( "unknown" ) ) ,
178+ } ) ) ,
179+ Some ( url) => match url. scheme ( ) {
180+ "http" | "https" | "git" | "ssh" => {
181+ if url. domain ( ) == Some ( "github.com" ) {
182+ Ok ( Crate :: GitHub ( GitHubRepo {
183+ org : url
184+ . path_segments ( )
185+ . and_then ( |mut path| path. next ( ) )
186+ . unwrap_or_default ( )
187+ . to_string ( ) ,
188+ name : package_id. name ( ) . to_string ( ) ,
189+ sha : None ,
190+ } ) )
191+ } else {
192+ Ok ( Crate :: Git ( GitRepo {
193+ url : url. to_string ( ) ,
194+ sha : None ,
195+ } ) )
196+ }
197+ }
198+ "file" => Ok ( Crate :: Path ( url. path ( ) . to_string ( ) ) ) ,
199+ other => {
200+ bail ! ( format!( "Unsuported Protocol: {other}" ) )
201+ }
202+ } ,
203+ } ,
261204 }
262- } else if let Some ( ( package_name, version) ) = pkgid. repr . split_once ( [ '@' , ':' ] ) {
263- // Cargo Package Id Spec
264- // name ("@"|":") semver
265- Ok ( Crate :: Registry ( RegistryCrate {
266- name : package_name. to_string ( ) ,
267- version : version. to_string ( ) ,
268- } ) )
269- } else {
270- // Cargo Package Id Spec
271- // name only
272- Ok ( Crate :: Registry ( RegistryCrate {
273- name : pkgid. repr . clone ( ) ,
274- version : "unknown" . to_string ( ) ,
275- } ) )
276205 }
277206 }
278207}
@@ -414,6 +343,10 @@ mod tests {
414343 name: "cookie" . to_string( ) ,
415344 version: "0.15.0" . to_string( ) ,
416345 } ) ,
346+ "sparse+https://github.com/rust-lang/crates.io-index#[email protected] " =>
Crate :: Registry ( RegistryCrate { 347+ name: "cookie" . to_string( ) ,
348+ version: "0.15.0" . to_string( ) ,
349+ } ) ,
417350 "[email protected] " =>
Crate :: Registry ( RegistryCrate { 418351 name: "regex" . to_string( ) ,
419352 version: "1.4.3" . to_string( ) ,
@@ -442,13 +375,13 @@ mod tests {
442375 "git+ssh://[email protected] /rust-lang/regex.git?branch=dev#[email protected] " =>
Crate :: GitHub ( GitHubRepo { 443376 org: "rust-lang" . to_string( ) ,
444377 name: "regex" . to_string( ) ,
445- sha: Some ( "dev" . to_string( ) )
378+ sha: Some ( "branch= dev" . to_string( ) )
446379 } ) ,
447380
448381 "git+https://gitlab.com/dummy_org/dummy?rev=9823f01cf4948a41279f6a3febcf793130cab4f6" => Crate :: Git ( GitRepo {
449- url: "git+ https://gitlab.com/dummy_org/dummy"
382+ url: "https://gitlab.com/dummy_org/dummy"
450383 . to_string( ) ,
451- sha: Some ( "9823f01cf4948a41279f6a3febcf793130cab4f6" . to_string( ) )
384+ sha: Some ( "rev= 9823f01cf4948a41279f6a3febcf793130cab4f6" . to_string( ) )
452385 } ) ,
453386
454387 "file:///path/to/my/project/foo" => Crate :: Path ( "/path/to/my/project/foo" . to_string( ) ) ,
0 commit comments