@@ -181,7 +181,37 @@ fn impl_def_from_trait(
181
181
fn gen_debug_impl ( adt : & ast:: Adt , func : & ast:: Fn , annotated_name : & ast:: Name ) {
182
182
match adt {
183
183
ast:: Adt :: Union ( _) => { } // `Debug` cannot be derived for unions, so no default impl can be provided.
184
- ast:: Adt :: Enum ( enum_) => { } // TODO
184
+ ast:: Adt :: Enum ( enum_) => {
185
+ if let Some ( list) = enum_. variant_list ( ) {
186
+ let mut arms = vec ! [ ] ;
187
+ for variant in list. variants ( ) {
188
+ let name = variant. name ( ) . unwrap ( ) ;
189
+
190
+ // => Self::<Variant>
191
+ let first = make:: ext:: ident_path ( "Self" ) ;
192
+ let second = make:: ext:: ident_path ( & format ! ( "{}" , name) ) ;
193
+ let pat = make:: path_pat ( make:: path_concat ( first, second) ) ;
194
+
195
+ // => write!(f, "<Variant>")
196
+ let target = make:: expr_path ( make:: ext:: ident_path ( "f" ) . into ( ) ) ;
197
+ let fmt_string = make:: expr_literal ( & ( format ! ( "\" {}\" " , name) ) ) . into ( ) ;
198
+ let args = make:: arg_list ( vec ! [ target, fmt_string] ) ;
199
+ let target = make:: expr_path ( make:: ext:: ident_path ( "write" ) ) ;
200
+ let expr = make:: expr_macro_call ( target, args) ;
201
+
202
+ // => Self::<Variant> => write!(f, "<Variant>"),
203
+ arms. push ( make:: match_arm ( Some ( pat. into ( ) ) , None , expr. into ( ) ) ) ;
204
+ }
205
+
206
+ // => match self { ... }
207
+ let f_path = make:: expr_path ( make:: ext:: ident_path ( "self" ) ) ;
208
+ let list = make:: match_arm_list ( arms) ;
209
+ let expr = make:: expr_match ( f_path, list) ;
210
+
211
+ let body = make:: block_expr ( None , Some ( expr) ) . indent ( ast:: edit:: IndentLevel ( 1 ) ) ;
212
+ ted:: replace ( func. body ( ) . unwrap ( ) . syntax ( ) , body. clone_for_update ( ) . syntax ( ) ) ;
213
+ }
214
+ }
185
215
ast:: Adt :: Struct ( strukt) => match strukt. field_list ( ) {
186
216
Some ( ast:: FieldList :: RecordFieldList ( field_list) ) => {
187
217
let name = format ! ( "\" {}\" " , annotated_name) ;
@@ -383,6 +413,52 @@ impl fmt::Debug for Foo {
383
413
f.debug_struct("Foo").finish()
384
414
}
385
415
}
416
+ "# ,
417
+ )
418
+ }
419
+ #[ test]
420
+ fn add_custom_impl_debug_enum ( ) {
421
+ check_assist (
422
+ replace_derive_with_manual_impl,
423
+ r#"
424
+ mod fmt {
425
+ pub struct Error;
426
+ pub type Result = Result<(), Error>;
427
+ pub struct Formatter<'a>;
428
+ pub trait Debug {
429
+ fn fmt(&self, f: &mut Formatter<'_>) -> Result;
430
+ }
431
+ }
432
+
433
+ #[derive(Debu$0g)]
434
+ enum Foo {
435
+ Bar,
436
+ Baz,
437
+ }
438
+ "# ,
439
+ r#"
440
+ mod fmt {
441
+ pub struct Error;
442
+ pub type Result = Result<(), Error>;
443
+ pub struct Formatter<'a>;
444
+ pub trait Debug {
445
+ fn fmt(&self, f: &mut Formatter<'_>) -> Result;
446
+ }
447
+ }
448
+
449
+ enum Foo {
450
+ Bar,
451
+ Baz,
452
+ }
453
+
454
+ impl fmt::Debug for Foo {
455
+ $0fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
456
+ match self {
457
+ Self::Bar => write!(f, "Bar"),
458
+ Self::Baz => write!(f, "Baz"),
459
+ }
460
+ }
461
+ }
386
462
"# ,
387
463
)
388
464
}
0 commit comments