Skip to content

Commit e2ab2e1

Browse files
committed
wip
1 parent f2e547d commit e2ab2e1

File tree

2 files changed

+34
-17
lines changed

2 files changed

+34
-17
lines changed

crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ use crate::{
3535
// struct S;
3636
//
3737
// impl Debug for S {
38-
// fn fmt(&self, f: &mut Formatter) -> Result<()> {
39-
// ${0:todo!()}
38+
// $0fn fmt(&self, f: &mut Formatter) -> Result<()> {
39+
// f.debug_struct(S)
4040
// }
4141
// }
4242
// ```
@@ -114,7 +114,7 @@ fn add_assist(
114114
|builder| {
115115
let insert_pos = adt.syntax().text_range().end();
116116
let impl_def_with_items =
117-
impl_def_from_trait(&ctx.sema, &annotated_name, trait_, trait_path);
117+
impl_def_from_trait(&ctx.sema, adt, &annotated_name, trait_, trait_path);
118118
update_attribute(builder, input, &trait_name, attr);
119119
let trait_path = format!("{}", trait_path);
120120
match (ctx.config.snippet_cap, impl_def_with_items) {
@@ -155,6 +155,7 @@ fn add_assist(
155155

156156
fn impl_def_from_trait(
157157
sema: &hir::Semantics<ide_db::RootDatabase>,
158+
adt: &ast::Adt,
158159
annotated_name: &ast::Name,
159160
trait_: Option<hir::Trait>,
160161
trait_path: &ast::Path,
@@ -169,25 +170,41 @@ fn impl_def_from_trait(
169170
make::impl_trait(trait_path.clone(), make::ext::ident_path(&annotated_name.text()));
170171
let (impl_def, first_assoc_item) =
171172
add_trait_assoc_items_to_impl(sema, trait_items, trait_, impl_def, target_scope);
173+
172174
if let ast::AssocItem::Fn(fn_) = &first_assoc_item {
173175
if trait_path.segment().unwrap().name_ref().unwrap().text() == "Debug" {
174-
let f_expr = make::expr_path(make::ext::ident_path("f"));
175-
let args = make::arg_list(Some(make::expr_path(make::ext::ident_path(
176-
annotated_name.text().as_str(),
177-
))));
178-
let body =
179-
make::block_expr(None, Some(make::expr_method_call(f_expr, "debug_struct", args)))
180-
.indent(ast::edit::IndentLevel(1));
181-
182-
ted::replace(
183-
fn_.body().unwrap().tail_expr().unwrap().syntax(),
184-
body.clone_for_update().syntax(),
185-
);
176+
gen_debug_impl(adt, fn_, annotated_name);
186177
}
187178
}
188179
Some((impl_def, first_assoc_item))
189180
}
190181

182+
fn gen_debug_impl(adt: &ast::Adt, fn_: &ast::Fn, annotated_name: &ast::Name) {
183+
match adt {
184+
ast::Adt::Union(_) => {} // `Debug` cannot be derived for unions, so no default impl can be provided.
185+
ast::Adt::Enum(_) => {} // TODO
186+
ast::Adt::Struct(strukt) => {
187+
match strukt.field_list() {
188+
Some(ast::FieldList::RecordFieldList(field_list)) => {
189+
let name = format!("\"{}\"", annotated_name);
190+
let args = make::arg_list(Some(make::expr_literal(&name).into()));
191+
let target = make::expr_path(make::ext::ident_path("f"));
192+
let mut expr = make::expr_method_call(target, "debug_struct", args);
193+
for field in field_list.fields() {
194+
let args = make::arg_list(Some(make::expr_path(&name).into()));
195+
expr = make::expr_method_call(expr, "field", args);
196+
}
197+
let expr = make::expr_method_call(expr, "finish", make::arg_list(None));
198+
let body = make::block_expr(None, Some(expr)).indent(ast::edit::IndentLevel(1));
199+
ted::replace(fn_.body().unwrap().syntax(), body.clone_for_update().syntax());
200+
}
201+
Some(ast::FieldList::TupleFieldList(field_list)) => {}
202+
None => {} // `Debug` cannot be implemented for an incomplete struct.
203+
}
204+
}
205+
}
206+
}
207+
191208
fn update_attribute(
192209
builder: &mut AssistBuilder,
193210
input: &ast::TokenTree,

crates/ide_assists/src/tests/generated.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,8 +1363,8 @@ trait Debug { fn fmt(&self, f: &mut Formatter) -> Result<()>; }
13631363
struct S;
13641364
13651365
impl Debug for S {
1366-
fn fmt(&self, f: &mut Formatter) -> Result<()> {
1367-
${0:todo!()}
1366+
$0fn fmt(&self, f: &mut Formatter) -> Result<()> {
1367+
f.debug_struct(S)
13681368
}
13691369
}
13701370
"#####,

0 commit comments

Comments
 (0)