Skip to content

Commit 741e27b

Browse files
committed
dedup PartialEq for Record enums
1 parent fc17eb4 commit 741e27b

File tree

1 file changed

+38
-37
lines changed

1 file changed

+38
-37
lines changed

crates/ide_assists/src/utils/gen_trait_fn_body.rs

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,34 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
339339
fn_name
340340
}
341341

342+
fn gen_eq_chain(expr: Option<ast::Expr>, cmp: ast::Expr) -> Option<ast::Expr> {
343+
match expr {
344+
Some(expr) => Some(make::expr_op(ast::BinOp::BooleanAnd, expr, cmp)),
345+
None => Some(cmp),
346+
}
347+
}
348+
349+
fn gen_record_pat_field(field_name: &str, pat_name: &str) -> ast::RecordPatField {
350+
let pat = make::ext::simple_ident_pat(make::name(&pat_name));
351+
let name_ref = make::name_ref(field_name);
352+
let field = make::record_pat_field(name_ref, pat.into());
353+
field
354+
}
355+
356+
fn gen_record_pat(
357+
record_name: ast::Path,
358+
r_fields: Vec<ast::RecordPatField>,
359+
) -> ast::RecordPat {
360+
let list = make::record_pat_field_list(r_fields);
361+
make::record_pat_with_fields(record_name, list)
362+
}
363+
364+
fn gen_variant_path(variant: &ast::Variant) -> Option<ast::Path> {
365+
let first = make::ext::ident_path("Self");
366+
let second = make::path_from_text(&variant.name()?.to_string());
367+
let record_name = make::path_concat(first, second);
368+
Some(record_name)
369+
}
342370
// FIXME: return `None` if the trait carries a generic type; we can only
343371
// generate this code `Self` for the time being.
344372

@@ -364,52 +392,31 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
364392
let mut expr = None;
365393
let mut l_fields = vec![];
366394
let mut r_fields = vec![];
367-
// let mut fields = vec![];
368-
369-
// !! make::record_pat_field{list, etc};
370395

371396
for field in list.fields() {
372397
let field_name = field.name()?.to_string();
373398

374399
let l_name = &format!("l_{}", field_name);
375-
let pat = make::ext::simple_ident_pat(make::name(&l_name));
376-
let name_ref = make::name_ref(&field_name);
377-
let field = make::record_pat_field(name_ref, pat.into());
378-
l_fields.push(field);
400+
l_fields.push(gen_record_pat_field(&field_name, &l_name));
379401

380-
let r_name = &format!("r_{}", field_name);
381-
let pat = make::ext::simple_ident_pat(make::name(&r_name));
382-
let name_ref = make::name_ref(&field_name);
383-
let field = make::record_pat_field(name_ref, pat.into());
384-
r_fields.push(field);
402+
let r_name = &format!("l_{}", field_name);
403+
r_fields.push(gen_record_pat_field(&field_name, &r_name));
385404

386405
let lhs = make::expr_path(make::ext::ident_path(l_name));
387406
let rhs = make::expr_path(make::ext::ident_path(r_name));
388407
let cmp = make::expr_op(ast::BinOp::EqualityTest, lhs, rhs);
389-
expr = match expr {
390-
Some(expr) => {
391-
Some(make::expr_op(ast::BinOp::BooleanAnd, expr, cmp))
392-
}
393-
None => Some(cmp),
394-
};
408+
expr = gen_eq_chain(expr, cmp);
395409
}
396-
let first = make::ext::ident_path("Self");
397-
let second = make::path_from_text(&variant.name()?.to_string());
398-
let record_name = make::path_concat(first, second);
399-
let list = make::record_pat_field_list(l_fields);
400-
let l_record = make::record_pat_with_fields(record_name, list);
401-
402-
let first = make::ext::ident_path("Self");
403-
let second = make::path_from_text(&variant.name()?.to_string());
404-
let record_name = make::path_concat(first, second);
405-
let list = make::record_pat_field_list(r_fields);
406-
let r_record = make::record_pat_with_fields(record_name, list);
407410

411+
let l_record = gen_record_pat(gen_variant_path(&variant)?, l_fields);
412+
let r_record = gen_record_pat(gen_variant_path(&variant)?, r_fields);
408413
let tuple = make::tuple_pat(vec![l_record.into(), r_record.into()]);
414+
409415
if let Some(expr) = expr {
410416
arms.push(make::match_arm(Some(tuple.into()), None, expr));
411417
}
412418
}
419+
413420
// todo!("implement tuple record iteration")
414421
Some(ast::FieldList::TupleFieldList(list)) => {
415422
todo!("implement tuple enum iteration")
@@ -453,10 +460,7 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
453460
let rhs = make::expr_path(make::ext::ident_path("other"));
454461
let rhs = make::expr_field(rhs, &field.name()?.to_string());
455462
let cmp = make::expr_op(ast::BinOp::EqualityTest, lhs, rhs);
456-
expr = match expr {
457-
Some(expr) => Some(make::expr_op(ast::BinOp::BooleanAnd, expr, cmp)),
458-
None => Some(cmp),
459-
};
463+
expr = gen_eq_chain(expr, cmp);
460464
}
461465
make::block_expr(None, expr).indent(ast::edit::IndentLevel(1))
462466
}
@@ -470,10 +474,7 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
470474
let rhs = make::expr_path(make::ext::ident_path("other"));
471475
let rhs = make::expr_field(rhs, &idx);
472476
let cmp = make::expr_op(ast::BinOp::EqualityTest, lhs, rhs);
473-
expr = match expr {
474-
Some(expr) => Some(make::expr_op(ast::BinOp::BooleanAnd, expr, cmp)),
475-
None => Some(cmp),
476-
};
477+
expr = gen_eq_chain(expr, cmp);
477478
}
478479
make::block_expr(None, expr).indent(ast::edit::IndentLevel(1))
479480
}

0 commit comments

Comments
 (0)