@@ -168,36 +168,54 @@ pub struct Manifest {
168
168
package_registry_data : HashMap < String , IndexMap < String , PackageInformation > > ,
169
169
}
170
170
171
- pub fn parse_bare_identifier ( specifier : & str ) -> Result < ( String , Option < String > ) , Error > {
172
- let mut segments = specifier . splitn ( 3 , '/' ) ;
173
- let mut ident_option : Option < String > = None ;
171
+ fn parse_scoped_package_name ( specifier : & str ) -> Option < ( String , Option < String > ) > {
172
+ let mut segments
173
+ = specifier . splitn ( 3 , '/' ) ;
174
174
175
- if let Some ( first) = segments. next ( ) {
176
- if first. starts_with ( '@' ) {
177
- if let Some ( second) = segments. next ( ) {
178
- ident_option = Some ( format ! ( "{}/{}" , first, second) ) ;
179
- }
180
- } else {
181
- ident_option = Some ( first. to_string ( ) ) ;
182
- }
183
- }
175
+ let Some ( scope) = segments. next ( ) else {
176
+ return None ;
177
+ } ;
184
178
185
- if let Some ( ident) = ident_option {
186
- let rests = segments. collect :: < Vec < _ > > ( ) ;
179
+ let Some ( name) = segments. next ( ) else {
180
+ return None ;
181
+ } ;
187
182
188
- let subpath = if rests. len ( ) == 0 {
189
- None
190
- } else {
191
- Some ( rests. join ( "/" ) )
192
- } ;
183
+ let package_name
184
+ = specifier[ ..scope. len ( ) + name. len ( ) + 1 ] . to_string ( ) ;
193
185
194
- Ok ( ( ident, subpath) )
195
- } else {
196
- Err ( Error :: BadSpecifier {
197
- message : String :: from ( "Invalid specifier" ) ,
198
- specifier : specifier. to_string ( ) ,
199
- } )
200
- }
186
+ let subpath
187
+ = segments. next ( ) . map ( |v| v. to_string ( ) ) ;
188
+
189
+ Some ( ( package_name, subpath) )
190
+ }
191
+
192
+ fn parse_global_package_name ( specifier : & str ) -> Option < ( String , Option < String > ) > {
193
+ let mut segments
194
+ = specifier. splitn ( 2 , '/' ) ;
195
+
196
+ let Some ( name) = segments. next ( ) else {
197
+ return None ;
198
+ } ;
199
+
200
+ let package_name
201
+ = name. to_string ( ) ;
202
+
203
+ let subpath
204
+ = segments. next ( ) . map ( |v| v. to_string ( ) ) ;
205
+
206
+ Some ( ( package_name, subpath) )
207
+ }
208
+
209
+ pub fn parse_bare_identifier ( specifier : & str ) -> Result < ( String , Option < String > ) , Error > {
210
+ let name = match specifier. starts_with ( "@" ) {
211
+ true => parse_scoped_package_name ( specifier) ,
212
+ false => parse_global_package_name ( specifier) ,
213
+ } ;
214
+
215
+ name. ok_or_else ( || Error :: BadSpecifier {
216
+ message : String :: from ( "Invalid specifier" ) ,
217
+ specifier : specifier. to_string ( ) ,
218
+ } )
201
219
}
202
220
203
221
pub fn find_closest_pnp_manifest_path < P : AsRef < Path > > ( p : P ) -> Option < PathBuf > {
0 commit comments