1 use stdx::{format_to, to_lower_snake_case};
2 use syntax::ast::{self, AstNode, HasName, HasVisibility};
5 utils::{find_impl_block_end, find_struct_impl, generate_impl_text},
6 AssistContext, AssistId, AssistKind, Assists, GroupLabel,
9 // Assist: generate_setter
11 // Generate a setter method.
25 // fn set_name(&mut self, name: String) {
30 pub(crate) fn generate_setter(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
31 let strukt = ctx.find_node_at_offset::<ast::Struct>()?;
32 let field = ctx.find_node_at_offset::<ast::RecordField>()?;
34 let field_name = field.name()?;
35 let field_ty = field.ty()?;
37 // Return early if we've found an existing fn
38 let fn_name = to_lower_snake_case(&field_name.to_string());
39 let impl_def = find_struct_impl(
41 &ast::Adt::Struct(strukt.clone()),
42 format!("set_{}", fn_name).as_str(),
45 let target = field.syntax().text_range();
47 &GroupLabel("Generate getter/setter".to_owned()),
48 AssistId("generate_setter", AssistKind::Generate),
49 "Generate a setter method",
52 let mut buf = String::with_capacity(512);
54 if impl_def.is_some() {
58 let vis = strukt.visibility().map_or(String::new(), |v| format!("{} ", v));
61 " {}fn set_{}(&mut self, {}: {}) {{
72 let start_offset = impl_def
73 .and_then(|impl_def| find_impl_block_end(impl_def, &mut buf))
75 buf = generate_impl_text(&ast::Adt::Struct(strukt.clone()), &buf);
76 strukt.syntax().text_range().end()
79 builder.insert(start_offset, buf);
86 use crate::tests::{check_assist, check_assist_not_applicable};
90 fn check_not_applicable(ra_fixture: &str) {
91 check_assist_not_applicable(generate_setter, ra_fixture)
95 fn test_generate_setter_from_field() {
99 struct Person<T: Clone> {
103 struct Person<T: Clone> {
107 impl<T: Clone> Person<T> {
108 fn set_data(&mut self, data: T) {
116 fn test_generate_setter_already_implemented() {
117 check_not_applicable(
119 struct Person<T: Clone> {
123 impl<T: Clone> Person<T> {
124 fn set_data(&mut self, data: T) {
132 fn test_generate_setter_from_field_with_visibility_marker() {
136 pub(crate) struct Person<T: Clone> {
140 pub(crate) struct Person<T: Clone> {
144 impl<T: Clone> Person<T> {
145 pub(crate) fn set_data(&mut self, data: T) {
153 fn test_multiple_generate_setter() {
157 struct Context<T: Clone> {
162 impl<T: Clone> Context<T> {
163 fn set_data(&mut self, data: T) {
168 struct Context<T: Clone> {
173 impl<T: Clone> Context<T> {
174 fn set_data(&mut self, data: T) {
178 fn set_count(&mut self, count: usize) {