@@ -23,12 +23,46 @@ use crate::{
2323//
2424// impl Person {
2525// /// Get a reference to the person's name.
26- // fn name (&self) -> &String {
26+ // fn $0name (&self) -> &String {
2727// &self.name
2828// }
2929// }
3030// ```
3131pub ( 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 < ( ) > {
3266 let strukt = ctx. find_node_at_offset :: < ast:: Struct > ( ) ?;
3367 let field = ctx. find_node_at_offset :: < ast:: RecordField > ( ) ?;
3468
@@ -37,39 +71,45 @@ pub(crate) fn generate_getter(acc: &mut Assists, ctx: &AssistContext) -> Option<
3771 let field_ty = field. ty ( ) ?;
3872
3973 // 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+ }
4178 let impl_def = find_struct_impl ( & ctx, & ast:: Adt :: Struct ( strukt. clone ( ) ) , fn_name. as_str ( ) ) ?;
4279
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+ } ;
4385 let target = field. syntax ( ) . text_range ( ) ;
4486 acc. add_group (
4587 & GroupLabel ( "Generate getter/setter" . to_owned ( ) ) ,
46- AssistId ( "generate_getter" , AssistKind :: Generate ) ,
47- "Generate a getter method" ,
88+ AssistId ( id , AssistKind :: Generate ) ,
89+ label ,
4890 target,
4991 |builder| {
5092 let mut buf = String :: with_capacity ( 512 ) ;
5193
52- let fn_name_spaced = fn_name. replace ( '_' , " " ) ;
53- let strukt_name_spaced =
54- to_lower_snake_case ( & strukt_name. to_string ( ) ) . replace ( '_' , " " ) ;
55-
5694 if impl_def. is_some ( ) {
5795 buf. push ( '\n' ) ;
5896 }
5997
6098 let vis = strukt. visibility ( ) . map_or ( String :: new ( ) , |v| format ! ( "{} " , v) ) ;
6199 format_to ! (
62100 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.{}
66104 }}" ,
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( '_' , " " ) ,
69108 vis,
70109 fn_name,
71110 field_ty,
72- fn_name,
111+ field_name,
112+ mut_ = mutable. then( || "mut " ) . unwrap_or_default( ) ,
73113 ) ;
74114
75115 let start_offset = impl_def
@@ -79,7 +119,12 @@ pub(crate) fn generate_getter(acc: &mut Assists, ctx: &AssistContext) -> Option<
79119 strukt. syntax ( ) . text_range ( ) . end ( )
80120 } ) ;
81121
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+ }
83128 } ,
84129 )
85130}
@@ -90,45 +135,81 @@ mod tests {
90135
91136 use super :: * ;
92137
93- fn check_not_applicable ( ra_fixture : & str ) {
94- check_assist_not_applicable ( generate_getter, ra_fixture)
95- }
96-
97138 #[ test]
98139 fn test_generate_getter_from_field ( ) {
99140 check_assist (
100141 generate_getter,
101142 r#"
102- struct Context<T: Clone> {
103- dat$0a: T,
104- }"# ,
143+ struct Context {
144+ dat$0a: Data,
145+ }
146+ "# ,
105147 r#"
106- struct Context<T: Clone> {
107- data: T ,
148+ struct Context {
149+ data: Data ,
108150}
109151
110- impl<T: Clone> Context<T> {
152+ impl Context {
111153 /// Get a reference to the context's data.
112- fn data (&self) -> &T {
154+ fn $0data (&self) -> &Data {
113155 &self.data
114156 }
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+ "# ,
116180 ) ;
117181 }
118182
119183 #[ test]
120184 fn test_generate_getter_already_implemented ( ) {
121- check_not_applicable (
185+ check_assist_not_applicable (
186+ generate_getter,
122187 r#"
123- struct Context<T: Clone> {
124- dat$0a: T ,
188+ struct Context {
189+ dat$0a: Data ,
125190}
126191
127- impl<T: Clone> Context<T> {
128- fn data(&self) -> &T {
192+ impl Context {
193+ fn data(&self) -> &Data {
129194 &self.data
130195 }
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+ "# ,
132213 ) ;
133214 }
134215
@@ -137,20 +218,22 @@ impl<T: Clone> Context<T> {
137218 check_assist (
138219 generate_getter,
139220 r#"
140- pub(crate) struct Context<T: Clone> {
141- dat$0a: T,
142- }"# ,
221+ pub(crate) struct Context {
222+ dat$0a: Data,
223+ }
224+ "# ,
143225 r#"
144- pub(crate) struct Context<T: Clone> {
145- data: T ,
226+ pub(crate) struct Context {
227+ data: Data ,
146228}
147229
148- impl<T: Clone> Context<T> {
230+ impl Context {
149231 /// Get a reference to the context's data.
150- pub(crate) fn data (&self) -> &T {
232+ pub(crate) fn $0data (&self) -> &Data {
151233 &self.data
152234 }
153- }"# ,
235+ }
236+ "# ,
154237 ) ;
155238 }
156239
@@ -159,34 +242,36 @@ impl<T: Clone> Context<T> {
159242 check_assist (
160243 generate_getter,
161244 r#"
162- struct Context<T: Clone> {
163- data: T ,
245+ struct Context {
246+ data: Data ,
164247 cou$0nt: usize,
165248}
166249
167- impl<T: Clone> Context<T> {
250+ impl Context {
168251 /// Get a reference to the context's data.
169- fn data(&self) -> &T {
252+ fn data(&self) -> &Data {
170253 &self.data
171254 }
172- }"# ,
255+ }
256+ "# ,
173257 r#"
174- struct Context<T: Clone> {
175- data: T ,
258+ struct Context {
259+ data: Data ,
176260 count: usize,
177261}
178262
179- impl<T: Clone> Context<T> {
263+ impl Context {
180264 /// Get a reference to the context's data.
181- fn data(&self) -> &T {
265+ fn data(&self) -> &Data {
182266 &self.data
183267 }
184268
185269 /// Get a reference to the context's count.
186- fn count (&self) -> &usize {
270+ fn $0count (&self) -> &usize {
187271 &self.count
188272 }
189- }"# ,
273+ }
274+ "# ,
190275 ) ;
191276 }
192277}
0 commit comments