1
- use std:: fmt:: Display ;
2
-
3
- use is_macro:: Is ;
4
1
use serde:: { Deserialize , Serialize } ;
5
2
6
3
use crate :: Span ;
7
4
5
+ use super :: { LintKind , Suggestion } ;
6
+
8
7
#[ derive( Debug , Clone , Serialize , Deserialize ) ]
9
8
pub struct Lint {
10
9
pub span : Span ,
@@ -27,144 +26,3 @@ impl Default for Lint {
27
26
}
28
27
}
29
28
}
30
-
31
- #[ derive( Debug , Clone , Copy , Serialize , Deserialize , Is , Default ) ]
32
- pub enum LintKind {
33
- Spelling ,
34
- Capitalization ,
35
- Style ,
36
- Formatting ,
37
- Repetition ,
38
- Enhancement ,
39
- Readability ,
40
- WordChoice ,
41
- #[ default]
42
- Miscellaneous ,
43
- }
44
-
45
- impl Display for LintKind {
46
- fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
47
- let s = match self {
48
- LintKind :: Spelling => "Spelling" ,
49
- LintKind :: Capitalization => "Capitalization" ,
50
- LintKind :: Formatting => "Formatting" ,
51
- LintKind :: Repetition => "Repetition" ,
52
- LintKind :: Readability => "Readability" ,
53
- LintKind :: Miscellaneous => "Miscellaneous" ,
54
- LintKind :: Enhancement => "Enhancement" ,
55
- LintKind :: WordChoice => "Word Choice" ,
56
- LintKind :: Style => "Style" ,
57
- } ;
58
-
59
- write ! ( f, "{}" , s)
60
- }
61
- }
62
-
63
- #[ derive( Debug , Clone , Serialize , Deserialize , Is , PartialEq , Eq ) ]
64
- pub enum Suggestion {
65
- ReplaceWith ( Vec < char > ) ,
66
- /// Insert the provided characters _after_ the offending text.
67
- InsertAfter ( Vec < char > ) ,
68
- Remove ,
69
- }
70
-
71
- impl Suggestion {
72
- /// Variant of [`Self::replace_with_match_case`] that accepts a static string.
73
- pub fn replace_with_match_case_str ( value : & ' static str , template : & [ char ] ) -> Self {
74
- Self :: replace_with_match_case ( value. chars ( ) . collect ( ) , template)
75
- }
76
-
77
- /// Construct an instance of [`Self::ReplaceWith`], but make the content match the case of the
78
- /// provided template.
79
- ///
80
- /// For example, if we want to replace "You're" with "You are", we can provide "you are" and
81
- /// "You're".
82
- pub fn replace_with_match_case ( mut value : Vec < char > , template : & [ char ] ) -> Self {
83
- for ( v, t) in value. iter_mut ( ) . zip ( template. iter ( ) ) {
84
- if v. is_ascii_uppercase ( ) != t. is_ascii_uppercase ( ) {
85
- if t. is_uppercase ( ) {
86
- * v = v. to_ascii_uppercase ( ) ;
87
- } else {
88
- * v = v. to_ascii_lowercase ( ) ;
89
- }
90
- }
91
- }
92
-
93
- Self :: ReplaceWith ( value)
94
- }
95
-
96
- /// Apply a suggestion to a given text.
97
- pub fn apply ( & self , span : Span , source : & mut Vec < char > ) {
98
- match self {
99
- Self :: ReplaceWith ( chars) => {
100
- // Avoid allocation if possible
101
- if chars. len ( ) == span. len ( ) {
102
- for ( index, c) in chars. iter ( ) . enumerate ( ) {
103
- source[ index + span. start ] = * c
104
- }
105
- } else {
106
- let popped = source. split_off ( span. start ) ;
107
-
108
- source. extend ( chars) ;
109
- source. extend ( popped. into_iter ( ) . skip ( span. len ( ) ) ) ;
110
- }
111
- }
112
- Self :: Remove => {
113
- for i in span. end ..source. len ( ) {
114
- source[ i - span. len ( ) ] = source[ i] ;
115
- }
116
-
117
- source. truncate ( source. len ( ) - span. len ( ) ) ;
118
- }
119
- Self :: InsertAfter ( chars) => {
120
- let popped = source. split_off ( span. end ) ;
121
- source. extend ( chars) ;
122
- source. extend ( popped) ;
123
- }
124
- }
125
- }
126
- }
127
-
128
- impl Display for Suggestion {
129
- fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
130
- match self {
131
- Suggestion :: ReplaceWith ( with) => {
132
- write ! ( f, "Replace with: “{}”" , with. iter( ) . collect:: <String >( ) )
133
- }
134
- Suggestion :: InsertAfter ( with) => {
135
- write ! ( f, "Insert “{}”" , with. iter( ) . collect:: <String >( ) )
136
- }
137
- Suggestion :: Remove => write ! ( f, "Remove error" ) ,
138
- }
139
- }
140
- }
141
-
142
- #[ cfg( test) ]
143
- mod tests {
144
- use crate :: Span ;
145
-
146
- use super :: Suggestion ;
147
-
148
- #[ test]
149
- fn insert_comma_after ( ) {
150
- let source = "This is a test" ;
151
- let mut source_chars = source. chars ( ) . collect ( ) ;
152
- let sug = Suggestion :: InsertAfter ( vec ! [ ',' ] ) ;
153
- sug. apply ( Span :: new ( 0 , 4 ) , & mut source_chars) ;
154
-
155
- assert_eq ! ( source_chars, "This, is a test" . chars( ) . collect:: <Vec <_>>( ) ) ;
156
- }
157
-
158
- #[ test]
159
- fn suggestion_your_match_case ( ) {
160
- let template: Vec < _ > = "You're" . chars ( ) . collect ( ) ;
161
- let value: Vec < _ > = "you are" . chars ( ) . collect ( ) ;
162
-
163
- let correct = "You are" . chars ( ) . collect ( ) ;
164
-
165
- assert_eq ! (
166
- Suggestion :: replace_with_match_case( value, & template) ,
167
- Suggestion :: ReplaceWith ( correct)
168
- )
169
- }
170
- }
0 commit comments