@@ -167,6 +167,8 @@ where
167167 fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
168168 // This mostly follows the procedure documented in the PURL spec.
169169 // https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst#how-to-parse-a-purl-string-in-its-components
170+
171+ // Check for `pkg:` first to quickly reject non-PURLs.
170172 let s = s. strip_prefix ( "pkg:" ) . ok_or ( ParseError :: UnsupportedUrlScheme ) ?;
171173
172174 // PURLs are not supposed to have any leading slashes, but the spec says that
@@ -177,15 +179,15 @@ where
177179
178180 // Remove subpath and qualifiers from the end now because they have higher
179181 // precedence than the path separater.
180- let s = match s. split_once ( '#' ) {
182+ let s = match s. rsplit_once ( '#' ) {
181183 Some ( ( s, subpath) ) => {
182184 parts. subpath = decode_subpath ( subpath) ?;
183185 s
184186 } ,
185187 None => s,
186188 } ;
187189
188- let s = match s. split_once ( '?' ) {
190+ let s = match s. rsplit_once ( '?' ) {
189191 Some ( ( s, qualifiers) ) => {
190192 decode_qualifiers ( qualifiers, & mut parts) ?;
191193 s
@@ -206,24 +208,24 @@ where
206208
207209 let package_type = T :: from_str ( package_type) ?;
208210
211+ let s = match s. rsplit_once ( '@' ) {
212+ Some ( ( s, version) ) => {
213+ parts. version = decode ( version) ?. into ( ) ;
214+ s
215+ } ,
216+ None => s,
217+ } ;
218+
209219 // The namespace is optional so we may not have any more slashes.
210- let name_and_version = match s. rsplit_once ( '/' ) {
220+ let name = match s. rsplit_once ( '/' ) {
211221 Some ( ( namespace, s) ) => {
212222 parts. namespace = decode_namespace ( namespace) ?;
213223 s
214224 } ,
215225 None => s,
216226 } ;
217227
218- match name_and_version. rsplit_once ( '@' ) {
219- Some ( ( name, version) ) => {
220- parts. name = decode ( name) ?. into ( ) ;
221- parts. version = decode ( version) ?. into ( ) ;
222- } ,
223- None => {
224- parts. name = decode ( name_and_version) ?. into ( ) ;
225- } ,
226- } ;
228+ parts. name = decode ( name) ?. into ( ) ;
227229
228230 GenericPurlBuilder { package_type, parts } . build ( )
229231 }
0 commit comments