@@ -23,8 +23,8 @@ use crate::{
2323//
2424// impl Person {
2525// /// 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()
2828// }
2929// }
3030// ```
@@ -96,20 +96,27 @@ pub(crate) fn generate_getter_impl(
9696 }
9797
9898 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+
99106 format_to ! (
100107 buf,
101108 " /// Get a {}reference to the {}'s {}.
102- {}fn {}(&{mut_ }self) -> &{mut_} {} {{
103- &{mut_}self. {}
109+ {}fn {}(&{}self) -> {} {{
110+ {}
104111 }}" ,
105112 mutable. then( || "mutable " ) . unwrap_or_default( ) ,
106113 to_lower_snake_case( & strukt_name. to_string( ) ) . replace( '_' , " " ) ,
107114 fn_name. trim_end_matches( "_mut" ) . replace( '_' , " " ) ,
108115 vis,
109116 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 ,
113120 ) ;
114121
115122 let start_offset = impl_def
@@ -129,6 +136,29 @@ pub(crate) fn generate_getter_impl(
129136 )
130137}
131138
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+
132162#[ cfg( test) ]
133163mod tests {
134164 use crate :: tests:: { check_assist, check_assist_not_applicable} ;
@@ -271,6 +301,75 @@ impl Context {
271301 &self.count
272302 }
273303}
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+ }
274373"# ,
275374 ) ;
276375 }
0 commit comments