@@ -15,19 +15,21 @@ use rustc_span::{sym, Span};
15
15
declare_clippy_lint ! {
16
16
/// ### What it does
17
17
/// Suggests to use dedicated built-in methods,
18
- /// `is_ascii_(lowercase|uppercase|digit)` for checking on corresponding ascii range
18
+ /// `is_ascii_(lowercase|uppercase|digit|hexdigit)` for checking on corresponding
19
+ /// ascii range
19
20
///
20
21
/// ### Why is this bad?
21
22
/// Using the built-in functions is more readable and makes it
22
23
/// clear that it's not a specific subset of characters, but all
23
- /// ASCII (lowercase|uppercase|digit) characters.
24
+ /// ASCII (lowercase|uppercase|digit|hexdigit ) characters.
24
25
/// ### Example
25
26
/// ```rust
26
27
/// fn main() {
27
28
/// assert!(matches!('x', 'a'..='z'));
28
29
/// assert!(matches!(b'X', b'A'..=b'Z'));
29
30
/// assert!(matches!('2', '0'..='9'));
30
31
/// assert!(matches!('x', 'A'..='Z' | 'a'..='z'));
32
+ /// assert!(matches!('C', '0'..='9' | 'a'..='f' | 'A'..='F'));
31
33
///
32
34
/// ('0'..='9').contains(&'0');
33
35
/// ('a'..='z').contains(&'a');
@@ -41,6 +43,7 @@ declare_clippy_lint! {
41
43
/// assert!(b'X'.is_ascii_uppercase());
42
44
/// assert!('2'.is_ascii_digit());
43
45
/// assert!('x'.is_ascii_alphabetic());
46
+ /// assert!('C'.is_ascii_hexdigit());
44
47
///
45
48
/// '0'.is_ascii_digit();
46
49
/// 'a'.is_ascii_lowercase();
@@ -75,6 +78,12 @@ enum CharRange {
75
78
FullChar ,
76
79
/// '0..=9'
77
80
Digit ,
81
+ /// 'a..=f'
82
+ LowerHexLetter ,
83
+ /// 'A..=F'
84
+ UpperHexLetter ,
85
+ /// '0..=9' | 'a..=f' | 'A..=F'
86
+ HexDigit ,
78
87
Otherwise ,
79
88
}
80
89
@@ -116,7 +125,8 @@ fn check_is_ascii(cx: &LateContext<'_>, span: Span, recv: &Expr<'_>, range: &Cha
116
125
CharRange :: LowerChar => Some ( "is_ascii_lowercase" ) ,
117
126
CharRange :: FullChar => Some ( "is_ascii_alphabetic" ) ,
118
127
CharRange :: Digit => Some ( "is_ascii_digit" ) ,
119
- CharRange :: Otherwise => None ,
128
+ CharRange :: HexDigit => Some ( "is_ascii_hexdigit" ) ,
129
+ CharRange :: Otherwise | CharRange :: LowerHexLetter | CharRange :: UpperHexLetter => None ,
120
130
} {
121
131
let default_snip = ".." ;
122
132
let mut app = Applicability :: MachineApplicable ;
@@ -141,6 +151,12 @@ fn check_pat(pat_kind: &PatKind<'_>) -> CharRange {
141
151
142
152
if ranges. len ( ) == 2 && ranges. contains ( & CharRange :: UpperChar ) && ranges. contains ( & CharRange :: LowerChar ) {
143
153
CharRange :: FullChar
154
+ } else if ranges. len ( ) == 3
155
+ && ranges. contains ( & CharRange :: Digit )
156
+ && ranges. contains ( & CharRange :: LowerHexLetter )
157
+ && ranges. contains ( & CharRange :: UpperHexLetter )
158
+ {
159
+ CharRange :: HexDigit
144
160
} else {
145
161
CharRange :: Otherwise
146
162
}
@@ -156,6 +172,8 @@ fn check_range(start: &Expr<'_>, end: &Expr<'_>) -> CharRange {
156
172
match ( & start_lit. node , & end_lit. node ) {
157
173
( Char ( 'a' ) , Char ( 'z' ) ) | ( Byte ( b'a' ) , Byte ( b'z' ) ) => CharRange :: LowerChar ,
158
174
( Char ( 'A' ) , Char ( 'Z' ) ) | ( Byte ( b'A' ) , Byte ( b'Z' ) ) => CharRange :: UpperChar ,
175
+ ( Char ( 'a' ) , Char ( 'f' ) ) | ( Byte ( b'a' ) , Byte ( b'f' ) ) => CharRange :: LowerHexLetter ,
176
+ ( Char ( 'A' ) , Char ( 'F' ) ) | ( Byte ( b'A' ) , Byte ( b'F' ) ) => CharRange :: UpperHexLetter ,
159
177
( Char ( '0' ) , Char ( '9' ) ) | ( Byte ( b'0' ) , Byte ( b'9' ) ) => CharRange :: Digit ,
160
178
_ => CharRange :: Otherwise ,
161
179
}
0 commit comments