File tree Expand file tree Collapse file tree 3 files changed +20
-12
lines changed Expand file tree Collapse file tree 3 files changed +20
-12
lines changed Original file line number Diff line number Diff line change @@ -269,26 +269,31 @@ impl Crate {
269269 . unwrap_or ( false )
270270 }
271271
272+ /// Validates the THIS parts of `features = ["THIS", "and/THIS"]`.
272273 pub fn valid_feature_name ( name : & str ) -> bool {
273274 !name. is_empty ( )
274275 && name
275276 . chars ( )
276- . all ( |c| c. is_alphanumeric ( ) || c == '_' || c == '-' )
277- && name. chars ( ) . all ( |c| c. is_ascii ( ) )
277+ . all ( |c| c. is_ascii_alphanumeric ( ) || c == '_' || c == '-' || c == '+' )
278278 }
279279
280+ /// Validates the prefix in front of the slash: `features = ["THIS/feature"]`.
281+ /// Normally this corresponds to the crate name of a dependency.
282+ fn valid_feature_prefix ( name : & str ) -> bool {
283+ !name. is_empty ( )
284+ && name
285+ . chars ( )
286+ . all ( |c| c. is_ascii_alphanumeric ( ) || c == '_' || c == '-' )
287+ }
288+
289+ /// Validates a whole feature string, `features = ["THIS", "ALL/THIS"]`.
280290 pub fn valid_feature ( name : & str ) -> bool {
281291 let mut parts = name. split ( '/' ) ;
282- match parts. next ( ) {
283- Some ( part) if !Crate :: valid_feature_name ( part) => return false ,
284- None => return false ,
285- _ => { }
286- }
287- match parts. next ( ) {
288- Some ( part) if !Crate :: valid_feature_name ( part) => return false ,
289- _ => { }
290- }
292+ let name_part = parts. next_back ( ) ; // required
293+ let prefix_part = parts. next_back ( ) ; // optional
291294 parts. next ( ) . is_none ( )
295+ && name_part. map_or ( false , Crate :: valid_feature_name)
296+ && prefix_part. map_or ( true , Crate :: valid_feature_prefix)
292297 }
293298
294299 pub fn minimal_encodable (
Original file line number Diff line number Diff line change @@ -983,6 +983,9 @@ fn valid_feature_names() {
983983 assert ! ( !Crate :: valid_feature( "%/%" ) ) ;
984984 assert ! ( Crate :: valid_feature( "a/a" ) ) ;
985985 assert ! ( Crate :: valid_feature( "32-column-tables" ) ) ;
986+ assert ! ( Crate :: valid_feature( "c++20" ) ) ;
987+ assert ! ( Crate :: valid_feature( "krate/c++20" ) ) ;
988+ assert ! ( !Crate :: valid_feature( "c++20/wow" ) ) ;
986989}
987990
988991#[ test]
Original file line number Diff line number Diff line change @@ -113,7 +113,7 @@ impl<'de> Deserialize<'de> for EncodableFeatureName {
113113 if !Crate :: valid_feature_name ( & s) {
114114 let value = de:: Unexpected :: Str ( & s) ;
115115 let expected = "a valid feature name containing only letters, \
116- numbers, hyphens, or underscores ";
116+ numbers, '-', '+', or '_' ";
117117 Err ( de:: Error :: invalid_value ( value, & expected) )
118118 } else {
119119 Ok ( EncodableFeatureName ( s) )
You can’t perform that action at this time.
0 commit comments