Use `HashMap<ProjectEntryId, Entry>` instead of `HashSet<Entry>` in outline_panel (#20780)

Michael Sloan created

Came across this because I noticed that `Entry` implements `Hash`, which
was surprising to me. I believe that `ProjectEntryId` should be unique
and so it seems better to dedupe based on this.

Release Notes:

- N/A

Change summary

crates/outline_panel/src/outline_panel.rs | 16 ++++++++++------
crates/worktree/src/worktree.rs           |  4 ++--
2 files changed, 12 insertions(+), 8 deletions(-)

Detailed changes

crates/outline_panel/src/outline_panel.rs 🔗

@@ -2178,8 +2178,10 @@ impl OutlinePanel {
                 .background_executor()
                 .spawn(async move {
                     let mut processed_external_buffers = HashSet::default();
-                    let mut new_worktree_entries =
-                        HashMap::<WorktreeId, (worktree::Snapshot, HashSet<Entry>)>::default();
+                    let mut new_worktree_entries = HashMap::<
+                        WorktreeId,
+                        (worktree::Snapshot, HashMap<ProjectEntryId, Entry>),
+                    >::default();
                     let mut worktree_excerpts = HashMap::<
                         WorktreeId,
                         HashMap<ProjectEntryId, (BufferId, Vec<ExcerptId>)>,
@@ -2213,7 +2215,7 @@ impl OutlinePanel {
                                         entry.path.as_ref(),
                                     );
 
-                                    let mut entries_to_add = HashSet::default();
+                                    let mut entries_to_add = HashMap::default();
                                     worktree_excerpts
                                         .entry(worktree_id)
                                         .or_default()
@@ -2238,7 +2240,9 @@ impl OutlinePanel {
                                             }
                                         }
 
-                                        let new_entry_added = entries_to_add.insert(current_entry);
+                                        let new_entry_added = entries_to_add
+                                            .insert(current_entry.id, current_entry)
+                                            .is_none();
                                         if new_entry_added && traversal.back_to_parent() {
                                             if let Some(parent_entry) = traversal.entry() {
                                                 current_entry = parent_entry.clone();
@@ -2249,7 +2253,7 @@ impl OutlinePanel {
                                     }
                                     new_worktree_entries
                                         .entry(worktree_id)
-                                        .or_insert_with(|| (worktree.clone(), HashSet::default()))
+                                        .or_insert_with(|| (worktree.clone(), HashMap::default()))
                                         .1
                                         .extend(entries_to_add);
                                 }
@@ -2276,7 +2280,7 @@ impl OutlinePanel {
                     let worktree_entries = new_worktree_entries
                         .into_iter()
                         .map(|(worktree_id, (worktree_snapshot, entries))| {
-                            let mut entries = entries.into_iter().collect::<Vec<_>>();
+                            let mut entries = entries.into_values().collect::<Vec<_>>();
                             // For a proper git status propagation, we have to keep the entries sorted lexicographically.
                             entries.sort_by(|a, b| a.path.as_ref().cmp(b.path.as_ref()));
                             worktree_snapshot.propagate_git_statuses(&mut entries);

crates/worktree/src/worktree.rs 🔗

@@ -3344,7 +3344,7 @@ impl File {
     }
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct Entry {
     pub id: ProjectEntryId,
     pub kind: EntryKind,
@@ -3376,7 +3376,7 @@ pub struct Entry {
     pub is_fifo: bool,
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum EntryKind {
     UnloadedDir,
     PendingDir,