@@ -23,8 +23,8 @@ use crate::{
23
23
//
24
24
// impl Person {
25
25
// /// Get a reference to the person's name.
26
- // fn $0name(&self) -> &String {
27
- // & self.name
26
+ // fn $0name(&self) -> &str {
27
+ // self.name.as_str()
28
28
// }
29
29
// }
30
30
// ```
@@ -96,20 +96,27 @@ pub(crate) fn generate_getter_impl(
96
96
}
97
97
98
98
let vis = strukt. visibility ( ) . map_or ( String :: new ( ) , |v| format ! ( "{} " , v) ) ;
99
+ let ( ty, body) = if mutable {
100
+ ( format ! ( "&mut {}" , field_ty) , format ! ( "&mut self.{}" , field_name) )
101
+ } else {
102
+ useless_type_special_case ( & field_name. to_string ( ) , & field_ty)
103
+ . unwrap_or_else ( || ( format ! ( "&{}" , field_ty) , format ! ( "&self.{}" , field_name) ) )
104
+ } ;
105
+
99
106
format_to ! (
100
107
buf,
101
108
" /// Get a {}reference to the {}'s {}.
102
- {}fn {}(&{mut_ }self) -> &{mut_} {} {{
103
- &{mut_}self. {}
109
+ {}fn {}(&{}self) -> {} {{
110
+ {}
104
111
}}" ,
105
112
mutable. then( || "mutable " ) . unwrap_or_default( ) ,
106
113
to_lower_snake_case( & strukt_name. to_string( ) ) . replace( '_' , " " ) ,
107
114
fn_name. trim_end_matches( "_mut" ) . replace( '_' , " " ) ,
108
115
vis,
109
116
fn_name,
110
- field_ty ,
111
- field_name ,
112
- mut_ = mutable . then ( || "mut " ) . unwrap_or_default ( ) ,
117
+ mutable . then ( || "mut " ) . unwrap_or_default ( ) ,
118
+ ty ,
119
+ body ,
113
120
) ;
114
121
115
122
let start_offset = impl_def
@@ -129,6 +136,29 @@ pub(crate) fn generate_getter_impl(
129
136
)
130
137
}
131
138
139
+ fn useless_type_special_case ( field_name : & str , field_ty : & ast:: Type ) -> Option < ( String , String ) > {
140
+ if field_ty. to_string ( ) == "String" {
141
+ cov_mark:: hit!( useless_type_special_case) ;
142
+ return Some ( ( "&str" . to_string ( ) , format ! ( "self.{}.as_str()" , field_name) ) ) ;
143
+ }
144
+ if let Some ( arg) = ty_ctor ( field_ty, "Vec" ) {
145
+ return Some ( ( format ! ( "&[{}]" , arg) , format ! ( "self.{}.as_slice()" , field_name) ) ) ;
146
+ }
147
+ if let Some ( arg) = ty_ctor ( field_ty, "Box" ) {
148
+ return Some ( ( format ! ( "&{}" , arg) , format ! ( "self.{}.as_ref()" , field_name) ) ) ;
149
+ }
150
+ if let Some ( arg) = ty_ctor ( field_ty, "Option" ) {
151
+ return Some ( ( format ! ( "Option<&{}>" , arg) , format ! ( "self.{}.as_ref()" , field_name) ) ) ;
152
+ }
153
+ None
154
+ }
155
+
156
+ // FIXME: This should rely on semantic info.
157
+ fn ty_ctor ( ty : & ast:: Type , ctor : & str ) -> Option < String > {
158
+ let res = ty. to_string ( ) . strip_prefix ( ctor) ?. strip_prefix ( '<' ) ?. strip_suffix ( '>' ) ?. to_string ( ) ;
159
+ Some ( res)
160
+ }
161
+
132
162
#[ cfg( test) ]
133
163
mod tests {
134
164
use crate :: tests:: { check_assist, check_assist_not_applicable} ;
@@ -271,6 +301,75 @@ impl Context {
271
301
&self.count
272
302
}
273
303
}
304
+ "# ,
305
+ ) ;
306
+ }
307
+
308
+ #[ test]
309
+ fn test_special_cases ( ) {
310
+ cov_mark:: check!( useless_type_special_case) ;
311
+ check_assist (
312
+ generate_getter,
313
+ r#"
314
+ struct S { foo: $0String }
315
+ "# ,
316
+ r#"
317
+ struct S { foo: String }
318
+
319
+ impl S {
320
+ /// Get a reference to the s's foo.
321
+ fn $0foo(&self) -> &str {
322
+ self.foo.as_str()
323
+ }
324
+ }
325
+ "# ,
326
+ ) ;
327
+ check_assist (
328
+ generate_getter,
329
+ r#"
330
+ struct S { foo: $0Box<Sweets> }
331
+ "# ,
332
+ r#"
333
+ struct S { foo: Box<Sweets> }
334
+
335
+ impl S {
336
+ /// Get a reference to the s's foo.
337
+ fn $0foo(&self) -> &Sweets {
338
+ self.foo.as_ref()
339
+ }
340
+ }
341
+ "# ,
342
+ ) ;
343
+ check_assist (
344
+ generate_getter,
345
+ r#"
346
+ struct S { foo: $0Vec<()> }
347
+ "# ,
348
+ r#"
349
+ struct S { foo: Vec<()> }
350
+
351
+ impl S {
352
+ /// Get a reference to the s's foo.
353
+ fn $0foo(&self) -> &[()] {
354
+ self.foo.as_slice()
355
+ }
356
+ }
357
+ "# ,
358
+ ) ;
359
+ check_assist (
360
+ generate_getter,
361
+ r#"
362
+ struct S { foo: $0Option<Failure> }
363
+ "# ,
364
+ r#"
365
+ struct S { foo: Option<Failure> }
366
+
367
+ impl S {
368
+ /// Get a reference to the s's foo.
369
+ fn $0foo(&self) -> Option<&Failure> {
370
+ self.foo.as_ref()
371
+ }
372
+ }
274
373
"# ,
275
374
) ;
276
375
}
0 commit comments