Refactor PostClone sections

Added a new Mode to handle an error last screen instead of complete.

This avoids running commands with unexpected arguments
This commit is contained in:
2Shirt 2024-11-11 00:03:49 -08:00
parent dd03962c84
commit 2a5167bf52
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
7 changed files with 49 additions and 30 deletions

View file

@ -83,5 +83,12 @@
"<Ctrl-c>": "Quit", // Yet another way to quit
"<Ctrl-z>": "Suspend" // Suspend the application
},
"Failed": {
"<Enter>": "Quit",
"<q>": "Quit", // Quit the application
"<Ctrl-d>": "Quit", // Another way to quit
"<Ctrl-c>": "Quit", // Yet another way to quit
"<Ctrl-z>": "Suspend" // Suspend the application
},
}
}

View file

@ -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(

View file

@ -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"),
}
}
_ => {}

View file

@ -56,7 +56,6 @@ impl Left {
impl Component for Left {
fn handle_key_event(&mut self, key: KeyEvent) -> Result<Option<Action>> {
// 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()

View file

@ -43,7 +43,6 @@ impl Right {
impl Component for Right {
fn handle_key_event(&mut self, key: KeyEvent) -> Result<Option<Action>> {
// TODO ??
let _ = key; // to appease clippy
Ok(None)
}

View file

@ -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<Partition> {
self.parts.clone()
}
pub fn num_parts(&self) -> usize {
self.parts.len()
}
@ -223,6 +233,7 @@ pub fn get_fake_disks() -> Vec<Disk> {
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<Disk> {
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()

View file

@ -287,8 +287,6 @@ pub fn parse_disk_numbers(contents: &str) -> Vec<&str> {
}
pub fn parse_partition_details(parts: &mut Vec<Partition>, contents: &str) {
// TODO: Update multiple fields at once?
// https://stackoverflow.com/a/52905826
static RE_PAR: Lazy<Regex> = 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<Partition>, 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);