]> git.lizzy.rs Git - rust.git/commitdiff
gen PartialEq for Record enums
authorYoshua Wuyts <yoshuawuyts@gmail.com>
Wed, 11 Aug 2021 15:15:12 +0000 (17:15 +0200)
committerYoshua Wuyts <yoshuawuyts@gmail.com>
Wed, 11 Aug 2021 15:15:12 +0000 (17:15 +0200)
Co-Authored-By: Ryan Levick <rylev@users.noreply.github.com>
crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs
crates/ide_assists/src/utils/gen_trait_fn_body.rs

index 7aa99bb937e9e7108b3233fd0e51a55c29feb0d7..30d291bff9b764c964ac4a86fddf54bef37b08d6 100644 (file)
@@ -752,9 +752,11 @@ enum Foo {
         bin: String,
     },
     Baz {
-        quz: String,
+        qux: String,
         fez: String,
     },
+    Qux {},
+    Bin,
 }
 "#,
             r#"
@@ -763,9 +765,11 @@ enum Foo {
         bin: String,
     },
     Baz {
-        quz: String,
+        qux: String,
         fez: String,
     },
+    Qux {},
+    Bin,
 }
 
 impl PartialEq for Foo {
@@ -773,7 +777,7 @@ impl PartialEq for Foo {
         if core::mem::discriminant(self) == core::mem::discriminant(other) {
             match (self, other) {
                 (Self::Bar { bin: l_bin }, Self::Bar { bin: r_bin }) => l_bin == r_bin,
-                (Self::Baz { qux: l_qux, fez: l_fez }, Self::Bar { qux: r_qux, fez: r_fez }) => l_qux == r_qux && l_fez == r_fez,
+                (Self::Baz { qux: l_qux, fez: l_fez }, Self::Baz { qux: r_qux, fez: r_fez }) => l_qux == r_qux && l_fez == r_fez,
                 _ => true,
             }
         } else {
index 782bc56ab32777be50dfffefe3894fa195caab1b..814a6ab02bf637f4fab37fe691ae77a384126c66 100644 (file)
@@ -361,26 +361,56 @@ fn gen_discriminant() -> ast::Expr {
                 match variant.field_list() {
                     // => (Self::Bar { bin: l_bin }, Self::Bar { bin: r_bin }) => l_bin == r_bin,
                     Some(ast::FieldList::RecordFieldList(list)) => {
-                        // let mut pats = vec![];
+                        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()?;
-                            // let pat = make::record_pat(path, pats);
-                            // let pat = make::ident_pat(false, false, field_name.clone());
-                            // pats.push(pat.into());
-
-                            // let path = make::ext::ident_path(&field_name.to_string());
-                            // let method_call = gen_clone_call(make::expr_path(path));
-                            // let name_ref = make::name_ref(&field_name.to_string());
-                            // let field = make::record_expr_field(name_ref, Some(method_call));
-                            // fields.push(field);
+                            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);
+
+                            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 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),
+                            };
+                        }
+                        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 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));
                         }
-                        // let pat = make::record_pat(variant_name.clone(), pats.into_iter());
-                        // let fields = make::record_expr_field_list(fields);
-                        // let record_expr = make::record_expr(variant_name, fields).into();
-                        // arms.push(make::match_arm(Some(pat.into()), None, record_expr));
-                        todo!("implement tuple record iteration")
                     }
+                    // todo!("implement tuple record iteration")
                     Some(ast::FieldList::TupleFieldList(list)) => {
                         todo!("implement tuple enum iteration")
                     }