@@ -23,12 +23,46 @@ use crate::{
23
23
//
24
24
// impl Person {
25
25
// /// Get a reference to the person's name.
26
- // fn name (&self) -> &String {
26
+ // fn $0name (&self) -> &String {
27
27
// &self.name
28
28
// }
29
29
// }
30
30
// ```
31
31
pub ( crate ) fn generate_getter ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
32
+ generate_getter_impl ( acc, ctx, false )
33
+ }
34
+
35
+ // Assist: generate_getter_mut
36
+ //
37
+ // Generate a mut getter method.
38
+ //
39
+ // ```
40
+ // struct Person {
41
+ // nam$0e: String,
42
+ // }
43
+ // ```
44
+ // ->
45
+ // ```
46
+ // struct Person {
47
+ // name: String,
48
+ // }
49
+ //
50
+ // impl Person {
51
+ // /// Get a mutable reference to the person's name.
52
+ // fn $0name_mut(&mut self) -> &mut String {
53
+ // &mut self.name
54
+ // }
55
+ // }
56
+ // ```
57
+ pub ( crate ) fn generate_getter_mut ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
58
+ generate_getter_impl ( acc, ctx, true )
59
+ }
60
+
61
+ pub ( crate ) fn generate_getter_impl (
62
+ acc : & mut Assists ,
63
+ ctx : & AssistContext ,
64
+ mutable : bool ,
65
+ ) -> Option < ( ) > {
32
66
let strukt = ctx. find_node_at_offset :: < ast:: Struct > ( ) ?;
33
67
let field = ctx. find_node_at_offset :: < ast:: RecordField > ( ) ?;
34
68
@@ -37,39 +71,45 @@ pub(crate) fn generate_getter(acc: &mut Assists, ctx: &AssistContext) -> Option<
37
71
let field_ty = field. ty ( ) ?;
38
72
39
73
// Return early if we've found an existing fn
40
- let fn_name = to_lower_snake_case ( & field_name. to_string ( ) ) ;
74
+ let mut fn_name = to_lower_snake_case ( & field_name. to_string ( ) ) ;
75
+ if mutable {
76
+ format_to ! ( fn_name, "_mut" ) ;
77
+ }
41
78
let impl_def = find_struct_impl ( & ctx, & ast:: Adt :: Struct ( strukt. clone ( ) ) , fn_name. as_str ( ) ) ?;
42
79
80
+ let ( id, label) = if mutable {
81
+ ( "generate_getter_mut" , "Generate a mut getter method" )
82
+ } else {
83
+ ( "generate_getter" , "Generate a getter method" )
84
+ } ;
43
85
let target = field. syntax ( ) . text_range ( ) ;
44
86
acc. add_group (
45
87
& GroupLabel ( "Generate getter/setter" . to_owned ( ) ) ,
46
- AssistId ( "generate_getter" , AssistKind :: Generate ) ,
47
- "Generate a getter method" ,
88
+ AssistId ( id , AssistKind :: Generate ) ,
89
+ label ,
48
90
target,
49
91
|builder| {
50
92
let mut buf = String :: with_capacity ( 512 ) ;
51
93
52
- let fn_name_spaced = fn_name. replace ( '_' , " " ) ;
53
- let strukt_name_spaced =
54
- to_lower_snake_case ( & strukt_name. to_string ( ) ) . replace ( '_' , " " ) ;
55
-
56
94
if impl_def. is_some ( ) {
57
95
buf. push ( '\n' ) ;
58
96
}
59
97
60
98
let vis = strukt. visibility ( ) . map_or ( String :: new ( ) , |v| format ! ( "{} " , v) ) ;
61
99
format_to ! (
62
100
buf,
63
- " /// Get a reference to the {}'s {}.
64
- {}fn {}(&self) -> &{} {{
65
- &self.{}
101
+ " /// Get a {} reference to the {}'s {}.
102
+ {}fn {}(&{mut_} self) -> &{mut_} {} {{
103
+ &{mut_} self.{}
66
104
}}" ,
67
- strukt_name_spaced,
68
- fn_name_spaced,
105
+ mutable. then( || "mutable " ) . unwrap_or_default( ) ,
106
+ to_lower_snake_case( & strukt_name. to_string( ) ) . replace( '_' , " " ) ,
107
+ fn_name. trim_end_matches( "_mut" ) . replace( '_' , " " ) ,
69
108
vis,
70
109
fn_name,
71
110
field_ty,
72
- fn_name,
111
+ field_name,
112
+ mut_ = mutable. then( || "mut " ) . unwrap_or_default( ) ,
73
113
) ;
74
114
75
115
let start_offset = impl_def
@@ -79,7 +119,12 @@ pub(crate) fn generate_getter(acc: &mut Assists, ctx: &AssistContext) -> Option<
79
119
strukt. syntax ( ) . text_range ( ) . end ( )
80
120
} ) ;
81
121
82
- builder. insert ( start_offset, buf) ;
122
+ match ctx. config . snippet_cap {
123
+ Some ( cap) => {
124
+ builder. insert_snippet ( cap, start_offset, buf. replacen ( "fn " , "fn $0" , 1 ) )
125
+ }
126
+ None => builder. insert ( start_offset, buf) ,
127
+ }
83
128
} ,
84
129
)
85
130
}
@@ -90,45 +135,81 @@ mod tests {
90
135
91
136
use super :: * ;
92
137
93
- fn check_not_applicable ( ra_fixture : & str ) {
94
- check_assist_not_applicable ( generate_getter, ra_fixture)
95
- }
96
-
97
138
#[ test]
98
139
fn test_generate_getter_from_field ( ) {
99
140
check_assist (
100
141
generate_getter,
101
142
r#"
102
- struct Context<T: Clone> {
103
- dat$0a: T,
104
- }"# ,
143
+ struct Context {
144
+ dat$0a: Data,
145
+ }
146
+ "# ,
105
147
r#"
106
- struct Context<T: Clone> {
107
- data: T ,
148
+ struct Context {
149
+ data: Data ,
108
150
}
109
151
110
- impl<T: Clone> Context<T> {
152
+ impl Context {
111
153
/// Get a reference to the context's data.
112
- fn data (&self) -> &T {
154
+ fn $0data (&self) -> &Data {
113
155
&self.data
114
156
}
115
- }"# ,
157
+ }
158
+ "# ,
159
+ ) ;
160
+
161
+ check_assist (
162
+ generate_getter_mut,
163
+ r#"
164
+ struct Context {
165
+ dat$0a: Data,
166
+ }
167
+ "# ,
168
+ r#"
169
+ struct Context {
170
+ data: Data,
171
+ }
172
+
173
+ impl Context {
174
+ /// Get a mutable reference to the context's data.
175
+ fn $0data_mut(&mut self) -> &mut Data {
176
+ &mut self.data
177
+ }
178
+ }
179
+ "# ,
116
180
) ;
117
181
}
118
182
119
183
#[ test]
120
184
fn test_generate_getter_already_implemented ( ) {
121
- check_not_applicable (
185
+ check_assist_not_applicable (
186
+ generate_getter,
122
187
r#"
123
- struct Context<T: Clone> {
124
- dat$0a: T ,
188
+ struct Context {
189
+ dat$0a: Data ,
125
190
}
126
191
127
- impl<T: Clone> Context<T> {
128
- fn data(&self) -> &T {
192
+ impl Context {
193
+ fn data(&self) -> &Data {
129
194
&self.data
130
195
}
131
- }"# ,
196
+ }
197
+ "# ,
198
+ ) ;
199
+
200
+ check_assist_not_applicable (
201
+ generate_getter_mut,
202
+ r#"
203
+ struct Context {
204
+ dat$0a: Data,
205
+ }
206
+
207
+ impl Context {
208
+ fn data_mut(&mut self) -> &mut Data {
209
+ &mut self.data
210
+ }
211
+ }
212
+ "# ,
132
213
) ;
133
214
}
134
215
@@ -137,20 +218,22 @@ impl<T: Clone> Context<T> {
137
218
check_assist (
138
219
generate_getter,
139
220
r#"
140
- pub(crate) struct Context<T: Clone> {
141
- dat$0a: T,
142
- }"# ,
221
+ pub(crate) struct Context {
222
+ dat$0a: Data,
223
+ }
224
+ "# ,
143
225
r#"
144
- pub(crate) struct Context<T: Clone> {
145
- data: T ,
226
+ pub(crate) struct Context {
227
+ data: Data ,
146
228
}
147
229
148
- impl<T: Clone> Context<T> {
230
+ impl Context {
149
231
/// Get a reference to the context's data.
150
- pub(crate) fn data (&self) -> &T {
232
+ pub(crate) fn $0data (&self) -> &Data {
151
233
&self.data
152
234
}
153
- }"# ,
235
+ }
236
+ "# ,
154
237
) ;
155
238
}
156
239
@@ -159,34 +242,36 @@ impl<T: Clone> Context<T> {
159
242
check_assist (
160
243
generate_getter,
161
244
r#"
162
- struct Context<T: Clone> {
163
- data: T ,
245
+ struct Context {
246
+ data: Data ,
164
247
cou$0nt: usize,
165
248
}
166
249
167
- impl<T: Clone> Context<T> {
250
+ impl Context {
168
251
/// Get a reference to the context's data.
169
- fn data(&self) -> &T {
252
+ fn data(&self) -> &Data {
170
253
&self.data
171
254
}
172
- }"# ,
255
+ }
256
+ "# ,
173
257
r#"
174
- struct Context<T: Clone> {
175
- data: T ,
258
+ struct Context {
259
+ data: Data ,
176
260
count: usize,
177
261
}
178
262
179
- impl<T: Clone> Context<T> {
263
+ impl Context {
180
264
/// Get a reference to the context's data.
181
- fn data(&self) -> &T {
265
+ fn data(&self) -> &Data {
182
266
&self.data
183
267
}
184
268
185
269
/// Get a reference to the context's count.
186
- fn count (&self) -> &usize {
270
+ fn $0count (&self) -> &usize {
187
271
&self.count
188
272
}
189
- }"# ,
273
+ }
274
+ "# ,
190
275
) ;
191
276
}
192
277
}
0 commit comments