]> git.proxmox.com Git - pve-installer.git/commitdiff
tui: simplify duplicate disk checking logic
authorChristoph Heiss <c.heiss@proxmox.com>
Mon, 24 Jul 2023 10:14:45 +0000 (12:14 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Tue, 25 Jul 2023 09:19:31 +0000 (11:19 +0200)
This reduces the logic from O(n^2) to O(n), which is always a good
thing.

Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
proxmox-tui-installer/src/views/bootdisk.rs

index 6ef814f6062375406a0ee953126dac2bf9984fd8..b0557a6314631fa8db7c35ec7a3a2f830af69cd5 100644 (file)
@@ -1,4 +1,4 @@
-use std::{cell::RefCell, marker::PhantomData, rc::Rc};
+use std::{cell::RefCell, collections::HashSet, marker::PhantomData, rc::Rc};
 
 use cursive::{
     view::{Nameable, Resizable, ViewWrapper},
@@ -536,21 +536,11 @@ fn advanced_options_view(disks: &[Disk], options: Rc<RefCell<BootdiskOptions>>)
                 })
                 .flatten();
 
-            if let Some(disks) = options.as_ref().map(|opts| &opts.disks) {
-                if disks.len() > 1 {
-                    for i in 0..(disks.len() - 1) {
-                        let check_disk = &disks[i];
-                        for disk in &disks[(i + 1)..] {
-                            if disk.index == check_disk.index {
-                                siv.add_layer(Dialog::info(format!(
-                                    "cannot select same disk ({}) twice",
-                                    disk.path
-                                )));
-                                return;
-                            }
-                        }
-                    }
-                }
+            if let Err(duplicate) = check_for_duplicate_disks(&options.disks) {
+                siv.add_layer(Dialog::info(format!(
+                    "Cannot select same disk twice: {duplicate}"
+                )));
+                return;
             }
 
             siv.pop_layer();
@@ -562,3 +552,20 @@ fn advanced_options_view(disks: &[Disk], options: Rc<RefCell<BootdiskOptions>>)
     .with_name("advanced-bootdisk-options-dialog")
     .max_size((120, 40))
 }
+
+/// Checks a list of disks for duplicate entries, using their index as key.
+///
+/// # Arguments
+///
+/// * `disks` - A list of disks to check for duplicates.
+fn check_for_duplicate_disks(disks: &[Disk]) -> Result<(), &Disk> {
+    let mut set = HashSet::new();
+
+    for disk in disks {
+        if !set.insert(&disk.index) {
+            return Err(disk);
+        }
+    }
+
+    Ok(())
+}