From 2a5167bf526d16679c3e97a0257413fceacff5bb Mon Sep 17 00:00:00 2001 From: 2Shirt <2xShirt@gmail.com> Date: Mon, 11 Nov 2024 00:03:49 -0800 Subject: [PATCH] Refactor PostClone sections Added a new Mode to handle an error last screen instead of complete. This avoids running commands with unexpected arguments --- config/config.json5 | 7 +++++++ src/app.rs | 44 ++++++++++++++++++++-------------------- src/components/footer.rs | 2 +- src/components/left.rs | 10 ++++++--- src/components/right.rs | 1 - src/system/disk.rs | 12 +++++++++++ src/system/diskpart.rs | 3 --- 7 files changed, 49 insertions(+), 30 deletions(-) diff --git a/config/config.json5 b/config/config.json5 index 2b4db0e..064e12a 100644 --- a/config/config.json5 +++ b/config/config.json5 @@ -83,5 +83,12 @@ "": "Quit", // Yet another way to quit "": "Suspend" // Suspend the application }, + "Failed": { + "": "Quit", + "": "Quit", // Quit the application + "": "Quit", // Another way to quit + "": "Quit", // Yet another way to quit + "": "Suspend" // Suspend the application + }, } } diff --git a/src/app.rs b/src/app.rs index d888099..9650dd2 100644 --- a/src/app.rs +++ b/src/app.rs @@ -84,6 +84,7 @@ pub enum Mode { SelectParts, PostClone, Done, + Failed, } impl App { @@ -140,6 +141,7 @@ impl App { (Mode::SelectParts, Mode::Confirm) => Mode::PostClone, (_, Mode::PostClone) => Mode::Done, (_, Mode::Done) => Mode::Done, + (_, Mode::Failed) => Mode::Failed, // Invalid states (_, Mode::Confirm) => panic!("This shouldn't happen."), }; @@ -326,6 +328,7 @@ impl App { self.selections[1] = two; } Action::SetMode(new_mode) => { + info!("Setting mode to {new_mode:?}"); self.cur_mode = new_mode; match new_mode { Mode::ScanDisks => { @@ -364,7 +367,6 @@ impl App { ))?; } Mode::PostClone => { - // TODO: FIXME self.action_tx.send(Action::DisplayPopup( popup::Type::Info, String::from("Updating boot configuration"), @@ -374,7 +376,14 @@ impl App { let system32 = if cfg!(windows) { match env::var("SYSTEMROOT") { Ok(path) => path, - Err(_) => panic!("Failed to find SYSTEMROOT"), + Err(_) => { + self.action_tx.send(Action::DisplayPopup( + popup::Type::Error, + String::from("ERROR\n\n\nFailed to find SYSTEMROOT"), + ))?; + self.action_tx.send(Action::SetMode(Mode::Failed))?; + return Ok(()); + } } } else { String::from(".") @@ -385,29 +394,20 @@ impl App { if let Some(disk_index) = self.disk_index_dest { if let Some(disk) = disk_list.get(disk_index) { let table_type = self.table_type.clone().unwrap(); - let letter_boot: String; - let letter_os: String; - if let Some(part) = - disk.parts.get(self.part_index_boot.unwrap()) - { - letter_boot = if part.letter.is_empty() { - String::from("??") - } else { - part.letter.clone() - }; - letter_os = if part.letter.is_empty() { - String::from("??") - } else { - part.letter.clone() - }; - } else { + let letter_boot = + disk.get_part_letter(self.part_index_boot.unwrap()); + let letter_os = + disk.get_part_letter(self.part_index_os.unwrap()); + + // Safety check + if letter_boot.is_empty() || letter_os.is_empty() { self.action_tx.send(Action::DisplayPopup( popup::Type::Error, String::from( - "Failed to get drive letters for destination", + "ERROR\n\n\nFailed to get drive letters for the destination", ), ))?; - self.action_tx.send(Action::SetMode(Mode::Done))?; + self.action_tx.send(Action::SetMode(Mode::Failed))?; return Ok(()); } @@ -443,10 +443,10 @@ impl App { // Lock in safe mode let bcd_path = match table_type { PartitionTableType::Guid => { - format!("{letter_boot}\\EFI\\Microsoft\\Boot\\BCD") + format!("{letter_boot}:\\EFI\\Microsoft\\Boot\\BCD") } PartitionTableType::Legacy => { - format!("{letter_boot}\\Boot\\BCD") + format!("{letter_boot}:\\Boot\\BCD") } }; self.action_tx.send(Action::Command( diff --git a/src/components/footer.rs b/src/components/footer.rs index fc2ac3c..f12c876 100644 --- a/src/components/footer.rs +++ b/src/components/footer.rs @@ -74,7 +74,7 @@ impl Component for Footer { Mode::Confirm => { String::from("(Enter) to confirm / (b) to go back / (q) to quit") } - Mode::Done => String::from("(Enter) or (q) to quit"), + Mode::Done | Mode::Failed => String::from("(Enter) or (q) to quit"), } } _ => {} diff --git a/src/components/left.rs b/src/components/left.rs index e57a34e..b4dedd9 100644 --- a/src/components/left.rs +++ b/src/components/left.rs @@ -56,7 +56,6 @@ impl Left { impl Component for Left { fn handle_key_event(&mut self, key: KeyEvent) -> Result> { - // TODO let _ = key; // to appease clippy Ok(None) } @@ -249,7 +248,7 @@ impl Component for Left { (Mode::SelectTableType, Mode::Confirm) => { self.title_text = String::from("Confirm Selections (Again)") } - (_, Mode::Done) => self.title_text = String::from("Done"), + (_, Mode::Done | Mode::Failed) => self.title_text = String::from("Done"), // Invalid states (_, Mode::Confirm) => panic!("This shouldn't happen."), } @@ -274,7 +273,12 @@ impl Component for Left { // Body match self.mode { - Mode::ScanDisks | Mode::PreClone | Mode::Clone | Mode::PostClone | Mode::Done => { + Mode::ScanDisks + | Mode::PreClone + | Mode::Clone + | Mode::PostClone + | Mode::Done + | Mode::Failed => { // Leave blank let paragraph = Paragraph::new(String::new()).block( Block::default() diff --git a/src/components/right.rs b/src/components/right.rs index c0e9945..ad9f43b 100644 --- a/src/components/right.rs +++ b/src/components/right.rs @@ -43,7 +43,6 @@ impl Right { impl Component for Right { fn handle_key_event(&mut self, key: KeyEvent) -> Result> { - // TODO ?? let _ = key; // to appease clippy Ok(None) } diff --git a/src/system/disk.rs b/src/system/disk.rs index be6c3c3..213dfa9 100644 --- a/src/system/disk.rs +++ b/src/system/disk.rs @@ -65,9 +65,19 @@ impl Disk { } } + pub fn get_part_letter(&self, part_index: usize) -> String { + // Used to get Boot and OS letters + if let Some(part) = self.parts.get(part_index) { + part.letter.clone() + } else { + String::new() + } + } + pub fn get_parts(&self) -> Vec { self.parts.clone() } + pub fn num_parts(&self) -> usize { self.parts.len() } @@ -223,6 +233,7 @@ pub fn get_fake_disks() -> Vec { id: 1, fs_type: String::from("FAT32"), label: String::from("ESP"), + letter: String::from("S"), part_type: String::from("EFI"), size: 272_629_760, ..Default::default() @@ -237,6 +248,7 @@ pub fn get_fake_disks() -> Vec { id: 4, fs_type: String::from("NTFS"), label: String::from("Win10"), + letter: String::from("W"), part_type: String::from("MS Basic Data"), size: 824_340_119_552, ..Default::default() diff --git a/src/system/diskpart.rs b/src/system/diskpart.rs index 8e5bade..79fcc36 100644 --- a/src/system/diskpart.rs +++ b/src/system/diskpart.rs @@ -287,8 +287,6 @@ pub fn parse_disk_numbers(contents: &str) -> Vec<&str> { } pub fn parse_partition_details(parts: &mut Vec, contents: &str) { - // TODO: Update multiple fields at once? - // https://stackoverflow.com/a/52905826 static RE_PAR: Lazy = Lazy::new(|| { Regex::new( r"Partition (\d+)\r?\nType\s*: (\S+)(\r?\n.*){5}\s*(Volume.*\r?\n.*\r?\n|There is no volume)(.*)", @@ -324,7 +322,6 @@ pub fn parse_partition_details(parts: &mut Vec, contents: &str) { } pub fn refresh_disk_info(disk: &Disk) { - // TODO: Needs refactor - assuming add_ functions are replaced with get_ variants info!("Refresh disk info"); let mut disk = get_disk_details(disk.id, disk.size, None); disk.parts = get_partition_details(disk.id, None, None);