Compare commits

..

No commits in common. "9d6fa954b26055996930fce9e454ffbcf695b20b" and "81aa7a8984e7fd24f7a5bd4b88d8add7cc058410" have entirely different histories.

9 changed files with 69 additions and 108 deletions

View file

@ -17,8 +17,8 @@ use serde::{Deserialize, Serialize};
use strum::Display;
use crate::{
app::Mode,
components::popup::Type,
state::Mode,
system::{
disk::{Disk, PartitionTableType},
drivers::Driver,

View file

@ -26,6 +26,7 @@ use ratatui::{
layout::{Constraint, Direction, Layout},
prelude::Rect,
};
use serde::{Deserialize, Serialize};
use tokio::sync::mpsc;
use tracing::{debug, info};
@ -35,11 +36,11 @@ use crate::{
footer::Footer, fps::FpsCounter, left::Left, popup, right::Right, title::Title, Component,
},
config::Config,
state::{CloneSettings, Mode},
system::{
boot,
disk::{Disk, PartitionTableType},
diskpart::build_dest_format_script,
drivers::{self},
drivers::{self, Driver},
},
tasks::{Task, Tasks},
tui::{Event, Tui},
@ -57,13 +58,35 @@ pub struct App {
should_suspend: bool,
tick_rate: f64,
// App
clone: CloneSettings,
cur_mode: Mode,
disk_index_dest: Option<usize>,
disk_index_source: Option<usize>,
disk_list: Arc<Mutex<Vec<Disk>>>,
part_index_boot: Option<usize>,
part_index_os: Option<usize>,
driver: Option<Driver>,
prev_mode: Mode,
selections: Vec<Option<usize>>,
table_type: Option<PartitionTableType>,
tasks: Tasks,
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Mode {
#[default]
ScanDisks,
InstallDrivers,
SelectDisks,
SelectTableType,
Confirm,
PreClone,
Clone,
SelectParts,
PostClone,
Done,
Failed,
}
impl App {
pub fn new(tick_rate: f64, frame_rate: f64) -> Result<Self> {
let (action_tx, action_rx) = mpsc::unbounded_channel();
@ -89,15 +112,21 @@ impl App {
should_suspend: false,
tick_rate,
// App
clone: CloneSettings::new(disk_list_arc),
cur_mode: Mode::ScanDisks,
disk_index_dest: None,
disk_index_source: None,
disk_list: disk_list_arc,
driver: None,
part_index_boot: None,
part_index_os: None,
prev_mode: Mode::ScanDisks,
selections: vec![None, None],
table_type: None,
tasks,
})
}
pub fn next_mode(&mut self) -> (Option<Mode>, Option<Mode>) {
pub fn next_mode(&mut self) -> Option<Mode> {
let new_mode = match (self.prev_mode, self.cur_mode) {
(_, Mode::InstallDrivers) => Mode::ScanDisks,
(_, Mode::ScanDisks) => Mode::SelectDisks,
@ -119,22 +148,19 @@ impl App {
(_, Mode::Confirm) => panic!("This shouldn't happen."),
};
let prev_mode = {
if new_mode == self.cur_mode {
None
} else {
match self.cur_mode {
Mode::Confirm => Some(self.prev_mode),
// Update prev_mode if appropriate
Mode::Confirm => {}
Mode::PreClone | Mode::Clone | Mode::PostClone | Mode::Done => {
// Override since we're past the point of no return
Some(self.cur_mode)
self.prev_mode = self.cur_mode;
}
_ => Some(self.cur_mode),
_ => self.prev_mode = self.cur_mode,
}
};
if new_mode == self.cur_mode {
// No mode change needed
(None, None)
} else {
(prev_mode, Some(new_mode))
Some(new_mode)
}
}
@ -155,10 +181,10 @@ impl App {
))?;
// Build Diskpart script to format destination disk
let disk_list = self.clone.disk_list.lock().unwrap();
if let Some(disk_index) = self.clone.disk_index_dest {
let disk_list = self.disk_list.lock().unwrap();
if let Some(disk_index) = self.disk_index_dest {
if let Some(disk) = disk_list.get(disk_index) {
let table_type = self.clone.table_type.clone().unwrap();
let table_type = self.table_type.clone().unwrap();
let diskpart_script = build_dest_format_script(disk.id, &table_type);
self.tasks.add(Task::Diskpart(diskpart_script));
}
@ -173,7 +199,7 @@ impl App {
self.config.clone_app_path.clone(),
Vec::new(),
));
if let Some(dest_index) = self.clone.disk_index_dest {
if let Some(dest_index) = self.disk_index_dest {
self.tasks.add(Task::UpdateDestDisk(dest_index));
}
}
@ -198,12 +224,12 @@ impl App {
};
// Add actions
let disk_list = self.clone.disk_list.lock().unwrap();
if let Some(disk_index) = self.clone.disk_index_dest {
let disk_list = self.disk_list.lock().unwrap();
if let Some(disk_index) = self.disk_index_dest {
if let Some(disk) = disk_list.get(disk_index) {
let table_type = self.clone.table_type.clone().unwrap();
let letter_boot = disk.get_part_letter(self.clone.part_index_boot.unwrap());
let letter_os = disk.get_part_letter(self.clone.part_index_os.unwrap());
let table_type = self.table_type.clone().unwrap();
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() {
@ -221,8 +247,8 @@ impl App {
}
// Inject driver(s) (if selected)
if let Some(driver) = &self.clone.driver {
if let Ok(task) = boot::inject_driver(driver, &letter_os, &system32) {
if let Some(driver) = &self.driver {
if let Ok(task) = boot::inject_driver(&driver, &letter_os, &system32) {
self.tasks.add(task);
} else {
self.action_tx.send(Action::Error(format!(
@ -353,12 +379,12 @@ impl App {
self.action_tx.send(Action::SetMode(Mode::InstallDrivers))?;
}
Action::SelectDriver(ref driver) => {
self.clone.driver = Some(driver.clone());
self.driver = Some(driver.clone());
drivers::load(&driver.inf_paths);
self.action_tx.send(Action::NextScreen)?;
}
Action::SelectTableType(ref table_type) => {
self.clone.table_type = Some(table_type.clone());
self.table_type = Some(table_type.clone());
self.action_tx.send(Action::NextScreen)?;
}
Action::Resize(w, h) => self.handle_resize(tui, w, h)?,
@ -370,26 +396,22 @@ impl App {
};
self.action_tx.send(Action::SetMode(new_mode))?;
}
Action::NextScreen => match self.next_mode() {
(None, None) => {}
(Some(prev), Some(next)) => {
self.prev_mode = prev;
self.cur_mode = next;
Action::NextScreen => {
if let Some(mode) = self.next_mode() {
self.action_tx.send(Action::DismissPopup)?;
self.action_tx.send(Action::SetMode(next))?;
self.action_tx.send(Action::SetMode(mode))?;
}
}
_ => panic!("Failed to determine next mode"),
},
Action::ScanDisks => self.action_tx.send(Action::SetMode(Mode::ScanDisks))?,
Action::Select(one, two) => {
match self.cur_mode {
Mode::SelectDisks => {
self.clone.disk_index_source = one;
self.clone.disk_index_dest = two;
self.disk_index_source = one;
self.disk_index_dest = two;
}
Mode::SelectParts => {
self.clone.part_index_boot = one;
self.clone.part_index_os = two;
self.part_index_boot = one;
self.part_index_os = two;
}
_ => {}
}

View file

@ -21,7 +21,7 @@ use ratatui::{
use tokio::sync::mpsc::UnboundedSender;
use super::Component;
use crate::{action::Action, config::Config, state::Mode};
use crate::{action::Action, app::Mode, config::Config};
#[derive(Default)]
pub struct Footer {

View file

@ -25,8 +25,8 @@ use tracing::info;
use super::{popup, state::StatefulList, Component};
use crate::{
action::Action,
app::Mode,
config::Config,
state::Mode,
system::{
disk::{Disk, Partition, PartitionTableType},
drivers::{self, Driver},

View file

@ -23,7 +23,7 @@ use strum::Display;
use tokio::sync::mpsc::UnboundedSender;
use super::Component;
use crate::{action::Action, config::Config, state::Mode};
use crate::{action::Action, app::Mode, config::Config};
#[derive(Default, Debug, Clone, PartialEq, Eq, Display, Serialize, Deserialize)]
pub enum Type {

View file

@ -25,8 +25,8 @@ use tracing::info;
use super::{state::StatefulList, Component};
use crate::{
action::Action,
app::Mode,
config::Config,
state::Mode,
system::{
cpu::get_cpu_name,
disk::{Disk, Partition, PartitionTableType},

View file

@ -26,7 +26,7 @@ use ratatui::style::{Color, Modifier, Style};
use serde::{de::Deserializer, Deserialize};
use tracing::error;
use crate::{action::Action, state::Mode};
use crate::{action::Action, app::Mode};
const CONFIG: &str = include_str!("../config/config.json5");

View file

@ -26,7 +26,6 @@ mod components;
mod config;
mod errors;
mod logging;
mod state;
mod system;
mod tasks;
mod tests;

View file

@ -1,60 +0,0 @@
// This file is part of Deja-vu.
//
// Deja-vu is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Deja-vu is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
//
use std::sync::{Arc, Mutex};
use serde::{Deserialize, Serialize};
use crate::system::{
disk::{Disk, PartitionTableType},
drivers::Driver,
};
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Mode {
#[default]
ScanDisks,
InstallDrivers,
SelectDisks,
SelectTableType,
Confirm,
PreClone,
Clone,
SelectParts,
PostClone,
Done,
Failed,
}
#[derive(Debug, Default)]
pub struct CloneSettings {
pub disk_index_dest: Option<usize>,
pub disk_index_source: Option<usize>,
pub disk_list: Arc<Mutex<Vec<Disk>>>,
pub part_index_boot: Option<usize>,
pub part_index_os: Option<usize>,
pub driver: Option<Driver>,
pub table_type: Option<PartitionTableType>,
}
impl CloneSettings {
pub fn new(disk_list: Arc<Mutex<Vec<Disk>>>) -> Self {
CloneSettings {
disk_list,
..Default::default()
}
}
}