@@ -192,35 +192,55 @@ impl Crate {
192
192
} )
193
193
}
194
194
195
- pub fn validate_crate_name ( name : & str ) -> Result < ( ) , InvalidCrateName > {
195
+ // Validates the name is a valid crate name.
196
+ // This is also used for validating the name of dependencies.
197
+ // So the `for_what` parameter is used to indicate what the name is used for.
198
+ // It can be "crate" or "dependency".
199
+ pub fn validate_crate_name ( for_what : & str , name : & str ) -> Result < ( ) , InvalidCrateName > {
196
200
if name. chars ( ) . count ( ) > MAX_NAME_LENGTH {
197
- return Err ( InvalidCrateName :: TooLong ( name. into ( ) ) ) ;
201
+ return Err ( InvalidCrateName :: TooLong {
202
+ what : for_what. into ( ) ,
203
+ name : name. into ( ) ,
204
+ } ) ;
198
205
}
199
- Crate :: validate_create_ident ( name)
206
+ Crate :: validate_create_ident ( for_what , name)
200
207
}
201
208
202
209
// Checks that the name is a valid crate name.
203
210
// 1. The name must be non-empty.
204
211
// 2. The first character must be an ASCII character.
205
212
// 3. The remaining characters must be ASCII alphanumerics or `-` or `_`.
206
213
// Note: This differs from `valid_dependency_name`, which allows `_` as the first character.
207
- fn validate_create_ident ( name : & str ) -> Result < ( ) , InvalidCrateName > {
214
+ fn validate_create_ident ( for_what : & str , name : & str ) -> Result < ( ) , InvalidCrateName > {
208
215
if name. is_empty ( ) {
209
- return Err ( InvalidCrateName :: Empty ) ;
216
+ return Err ( InvalidCrateName :: Empty {
217
+ what : for_what. into ( ) ,
218
+ } ) ;
210
219
}
211
220
let mut chars = name. chars ( ) ;
212
221
if let Some ( ch) = chars. next ( ) {
213
222
if ch. is_ascii_digit ( ) {
214
- return Err ( InvalidCrateName :: StartWithDigit ( name. into ( ) ) ) ;
223
+ return Err ( InvalidCrateName :: StartWithDigit {
224
+ what : for_what. into ( ) ,
225
+ name : name. into ( ) ,
226
+ } ) ;
215
227
}
216
228
if !ch. is_ascii_alphabetic ( ) {
217
- return Err ( InvalidCrateName :: Start ( ch, name. into ( ) ) ) ;
229
+ return Err ( InvalidCrateName :: Start {
230
+ first_char : ch,
231
+ what : for_what. into ( ) ,
232
+ name : name. into ( ) ,
233
+ } ) ;
218
234
}
219
235
}
220
236
221
237
for ch in chars {
222
238
if !( ch. is_ascii_alphanumeric ( ) || ch == '-' || ch == '_' ) {
223
- return Err ( InvalidCrateName :: Char ( ch, name. into ( ) ) ) ;
239
+ return Err ( InvalidCrateName :: Char {
240
+ ch,
241
+ what : for_what. into ( ) ,
242
+ name : name. into ( ) ,
243
+ } ) ;
224
244
}
225
245
}
226
246
@@ -559,25 +579,33 @@ pub enum InvalidFeature {
559
579
560
580
#[ derive( Debug , Eq , PartialEq , thiserror:: Error ) ]
561
581
pub enum InvalidCrateName {
562
- #[ error( "the crate name `{0 }` is too long (max {MAX_NAME_LENGTH} characters)" ) ]
563
- TooLong ( String ) ,
564
- #[ error( "crate name cannot be empty" ) ]
565
- Empty ,
582
+ #[ error( "the {what} name `{name }` is too long (max {MAX_NAME_LENGTH} characters)" ) ]
583
+ TooLong { what : String , name : String } ,
584
+ #[ error( "{what} name cannot be empty" ) ]
585
+ Empty { what : String } ,
566
586
#[ error(
567
- "the name `{0 }` cannot be used as a crate name, \
587
+ "the name `{name }` cannot be used as a {what} name, \
568
588
the name cannot start with a digit"
569
589
) ]
570
- StartWithDigit ( String ) ,
590
+ StartWithDigit { what : String , name : String } ,
571
591
#[ error(
572
- "invalid character `{0 }` in crate name: `{1 }`, \
592
+ "invalid character `{first_char }` in {what} name: `{name }`, \
573
593
the first character must be an ASCII character"
574
594
) ]
575
- Start ( char , String ) ,
595
+ Start {
596
+ first_char : char ,
597
+ what : String ,
598
+ name : String ,
599
+ } ,
576
600
#[ error(
577
- "invalid character `{0 }` in crate name: `{1 }`, \
601
+ "invalid character `{ch }` in {what} name: `{name }`, \
578
602
characters must be an ASCII alphanumeric characters, `-`, or `_`"
579
603
) ]
580
- Char ( char , String ) ,
604
+ Char {
605
+ ch : char ,
606
+ what : String ,
607
+ name : String ,
608
+ } ,
581
609
}
582
610
583
611
#[ derive( Debug , Eq , PartialEq , thiserror:: Error ) ]
@@ -611,38 +639,68 @@ mod tests {
611
639
fn validate_crate_name ( ) {
612
640
use super :: { InvalidCrateName , MAX_NAME_LENGTH } ;
613
641
614
- assert_ok ! ( Crate :: validate_crate_name( "foo" ) ) ;
642
+ assert_ok ! ( Crate :: validate_crate_name( "crate" , " foo") ) ;
615
643
assert_err_eq ! (
616
- Crate :: validate_crate_name( "京" ) ,
617
- InvalidCrateName :: Start ( '京' , "京" . into( ) )
644
+ Crate :: validate_crate_name( "crate" , "京" ) ,
645
+ InvalidCrateName :: Start {
646
+ first_char: '京' ,
647
+ what: "crate" . into( ) ,
648
+ name: "京" . into( )
649
+ }
618
650
) ;
619
- assert_err_eq ! ( Crate :: validate_crate_name( "" ) , InvalidCrateName :: Empty ) ;
620
651
assert_err_eq ! (
621
- Crate :: validate_crate_name( "💝" ) ,
622
- InvalidCrateName :: Start ( '💝' , "💝" . into( ) )
652
+ Crate :: validate_crate_name( "crate" , "" ) ,
653
+ InvalidCrateName :: Empty {
654
+ what: "crate" . into( )
655
+ }
623
656
) ;
624
- assert_ok ! ( Crate :: validate_crate_name( "foo_underscore" ) ) ;
625
- assert_ok ! ( Crate :: validate_crate_name( "foo-dash" ) ) ;
626
657
assert_err_eq ! (
627
- Crate :: validate_crate_name( "foo+plus" ) ,
628
- InvalidCrateName :: Char ( '+' , "foo+plus" . into( ) )
658
+ Crate :: validate_crate_name( "crate" , "💝" ) ,
659
+ InvalidCrateName :: Start {
660
+ first_char: '💝' ,
661
+ what: "crate" . into( ) ,
662
+ name: "💝" . into( )
663
+ }
629
664
) ;
630
- // Crate names cannot start with an underscore on crates.io.
665
+ assert_ok ! ( Crate :: validate_crate_name( "crate" , "foo_underscore" ) ) ;
666
+ assert_ok ! ( Crate :: validate_crate_name( "crate" , "foo-dash" ) ) ;
631
667
assert_err_eq ! (
632
- Crate :: validate_crate_name( "_foo" ) ,
633
- InvalidCrateName :: Start ( '_' , "_foo" . into( ) )
668
+ Crate :: validate_crate_name( "crate" , "foo+plus" ) ,
669
+ InvalidCrateName :: Char {
670
+ ch: '+' ,
671
+ what: "crate" . into( ) ,
672
+ name: "foo+plus" . into( )
673
+ }
634
674
) ;
635
675
assert_err_eq ! (
636
- Crate :: validate_crate_name( "-foo" ) ,
637
- InvalidCrateName :: Start ( '-' , "-foo" . into( ) )
676
+ Crate :: validate_crate_name( "crate" , "_foo" ) ,
677
+ InvalidCrateName :: Start {
678
+ first_char: '_' ,
679
+ what: "crate" . into( ) ,
680
+ name: "_foo" . into( )
681
+ }
638
682
) ;
639
683
assert_err_eq ! (
640
- Crate :: validate_crate_name( "123" ) ,
641
- InvalidCrateName :: StartWithDigit ( "123" . into( ) )
684
+ Crate :: validate_crate_name( "crate" , "-foo" ) ,
685
+ InvalidCrateName :: Start {
686
+ first_char: '-' ,
687
+ what: "crate" . into( ) ,
688
+ name: "-foo" . into( )
689
+ }
642
690
) ;
643
691
assert_err_eq ! (
644
- Crate :: validate_crate_name( "o" . repeat( MAX_NAME_LENGTH + 1 ) . as_str( ) ) ,
645
- InvalidCrateName :: TooLong ( "o" . repeat( MAX_NAME_LENGTH + 1 ) . as_str( ) . into( ) )
692
+ Crate :: validate_crate_name( "crate" , "123" ) ,
693
+ InvalidCrateName :: StartWithDigit {
694
+ what: "crate" . into( ) ,
695
+ name: "123" . into( )
696
+ }
697
+ ) ;
698
+ assert_err_eq ! (
699
+ Crate :: validate_crate_name( "crate" , "o" . repeat( MAX_NAME_LENGTH + 1 ) . as_str( ) ) ,
700
+ InvalidCrateName :: TooLong {
701
+ what: "crate" . into( ) ,
702
+ name: "o" . repeat( MAX_NAME_LENGTH + 1 ) . as_str( ) . into( )
703
+ }
646
704
) ;
647
705
}
648
706
0 commit comments