@@ -168,36 +168,54 @@ pub struct Manifest {
168168 package_registry_data : HashMap < String , IndexMap < String , PackageInformation > > ,
169169}
170170
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 , '/' ) ;
174174
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+ } ;
184178
185- if let Some ( ident) = ident_option {
186- let rests = segments. collect :: < Vec < _ > > ( ) ;
179+ let Some ( name) = segments. next ( ) else {
180+ return None ;
181+ } ;
187182
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 ( ) ;
193185
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+ } )
201219}
202220
203221pub fn find_closest_pnp_manifest_path < P : AsRef < Path > > ( p : P ) -> Option < PathBuf > {
0 commit comments