]> git.lizzy.rs Git - rust.git/commitdiff
dedup PartialEq for Record enums
authorYoshua Wuyts <yoshuawuyts@gmail.com>
Wed, 11 Aug 2021 17:40:47 +0000 (19:40 +0200)
committerYoshua Wuyts <yoshuawuyts@gmail.com>
Wed, 11 Aug 2021 17:40:47 +0000 (19:40 +0200)
crates/ide_assists/src/utils/gen_trait_fn_body.rs

index 814a6ab02bf637f4fab37fe691ae77a384126c66..0db2aa320857b8cdd828878d26f702215ff056be 100644 (file)
@@ -339,6 +339,34 @@ fn gen_discriminant() -> ast::Expr {
         fn_name
     }
 
+    fn gen_eq_chain(expr: Option<ast::Expr>, cmp: ast::Expr) -> Option<ast::Expr> {
+        match expr {
+            Some(expr) => Some(make::expr_op(ast::BinOp::BooleanAnd, expr, cmp)),
+            None => Some(cmp),
+        }
+    }
+
+    fn gen_record_pat_field(field_name: &str, pat_name: &str) -> ast::RecordPatField {
+        let pat = make::ext::simple_ident_pat(make::name(&pat_name));
+        let name_ref = make::name_ref(field_name);
+        let field = make::record_pat_field(name_ref, pat.into());
+        field
+    }
+
+    fn gen_record_pat(
+        record_name: ast::Path,
+        r_fields: Vec<ast::RecordPatField>,
+    ) -> ast::RecordPat {
+        let list = make::record_pat_field_list(r_fields);
+        make::record_pat_with_fields(record_name, list)
+    }
+
+    fn gen_variant_path(variant: &ast::Variant) -> Option<ast::Path> {
+        let first = make::ext::ident_path("Self");
+        let second = make::path_from_text(&variant.name()?.to_string());
+        let record_name = make::path_concat(first, second);
+        Some(record_name)
+    }
     // FIXME: return `None` if the trait carries a generic type; we can only
     // generate this code `Self` for the time being.
 
@@ -364,52 +392,31 @@ fn gen_discriminant() -> ast::Expr {
                         let mut expr = None;
                         let mut l_fields = vec![];
                         let mut r_fields = vec![];
-                        // let mut fields = vec![];
-
-                        // !! make::record_pat_field{list, etc};
 
                         for field in list.fields() {
                             let field_name = field.name()?.to_string();
 
                             let l_name = &format!("l_{}", field_name);
-                            let pat = make::ext::simple_ident_pat(make::name(&l_name));
-                            let name_ref = make::name_ref(&field_name);
-                            let field = make::record_pat_field(name_ref, pat.into());
-                            l_fields.push(field);
+                            l_fields.push(gen_record_pat_field(&field_name, &l_name));
 
-                            let r_name = &format!("r_{}", field_name);
-                            let pat = make::ext::simple_ident_pat(make::name(&r_name));
-                            let name_ref = make::name_ref(&field_name);
-                            let field = make::record_pat_field(name_ref, pat.into());
-                            r_fields.push(field);
+                            let r_name = &format!("l_{}", field_name);
+                            r_fields.push(gen_record_pat_field(&field_name, &r_name));
 
                             let lhs = make::expr_path(make::ext::ident_path(l_name));
                             let rhs = make::expr_path(make::ext::ident_path(r_name));
                             let cmp = make::expr_op(ast::BinOp::EqualityTest, lhs, rhs);
-                            expr = match expr {
-                                Some(expr) => {
-                                    Some(make::expr_op(ast::BinOp::BooleanAnd, expr, cmp))
-                                }
-                                None => Some(cmp),
-                            };
+                            expr = gen_eq_chain(expr, cmp);
                         }
-                        let first = make::ext::ident_path("Self");
-                        let second = make::path_from_text(&variant.name()?.to_string());
-                        let record_name = make::path_concat(first, second);
-                        let list = make::record_pat_field_list(l_fields);
-                        let l_record = make::record_pat_with_fields(record_name, list);
-
-                        let first = make::ext::ident_path("Self");
-                        let second = make::path_from_text(&variant.name()?.to_string());
-                        let record_name = make::path_concat(first, second);
-                        let list = make::record_pat_field_list(r_fields);
-                        let r_record = make::record_pat_with_fields(record_name, list);
 
+                        let l_record = gen_record_pat(gen_variant_path(&variant)?, l_fields);
+                        let r_record = gen_record_pat(gen_variant_path(&variant)?, r_fields);
                         let tuple = make::tuple_pat(vec![l_record.into(), r_record.into()]);
+
                         if let Some(expr) = expr {
                             arms.push(make::match_arm(Some(tuple.into()), None, expr));
                         }
                     }
+
                     // todo!("implement tuple record iteration")
                     Some(ast::FieldList::TupleFieldList(list)) => {
                         todo!("implement tuple enum iteration")
@@ -453,10 +460,7 @@ fn gen_discriminant() -> ast::Expr {
                     let rhs = make::expr_path(make::ext::ident_path("other"));
                     let rhs = make::expr_field(rhs, &field.name()?.to_string());
                     let cmp = make::expr_op(ast::BinOp::EqualityTest, lhs, rhs);
-                    expr = match expr {
-                        Some(expr) => Some(make::expr_op(ast::BinOp::BooleanAnd, expr, cmp)),
-                        None => Some(cmp),
-                    };
+                    expr = gen_eq_chain(expr, cmp);
                 }
                 make::block_expr(None, expr).indent(ast::edit::IndentLevel(1))
             }
@@ -470,10 +474,7 @@ fn gen_discriminant() -> ast::Expr {
                     let rhs = make::expr_path(make::ext::ident_path("other"));
                     let rhs = make::expr_field(rhs, &idx);
                     let cmp = make::expr_op(ast::BinOp::EqualityTest, lhs, rhs);
-                    expr = match expr {
-                        Some(expr) => Some(make::expr_op(ast::BinOp::BooleanAnd, expr, cmp)),
-                        None => Some(cmp),
-                    };
+                    expr = gen_eq_chain(expr, cmp);
                 }
                 make::block_expr(None, expr).indent(ast::edit::IndentLevel(1))
             }