diff --git a/src/kira_config.toml b/src/kira_config.toml index eb82653..5df472d 100644 --- a/src/kira_config.toml +++ b/src/kira_config.toml @@ -4,3 +4,4 @@ reqire_network = true [partition] min_disk_size_mb = 8192 +efi_size_mb = 128 diff --git a/src/kira_disk_layout.rs b/src/kira_disk_layout.rs index 672615a..47764fa 100644 --- a/src/kira_disk_layout.rs +++ b/src/kira_disk_layout.rs @@ -20,7 +20,7 @@ use crate::kira_size::KiraSize; use log; -use std::{collections::HashMap, io::Read, process::ExitStatus}; +use std::{collections::HashMap}; /// /// size - device size in bytes /// sector size - default 4096 @@ -106,6 +106,11 @@ impl BlkDev { Err(ex) => Err(ex.to_string()), } } + + pub fn from_sys(name: &str) -> Option { + Self::list_sys_blk_dev().ok()?.iter().find(|v| v.name == name).cloned() + } + } #[derive(Debug, Clone, PartialEq, Eq)] @@ -320,6 +325,7 @@ pub fn align_part(size: u64, start: u64, align: u64) -> Option<(u64, u64, u64)> Some((align_size, align_start, align_end)) } +#[derive(Debug, Clone, PartialEq)] pub struct PartLayout { pub dev: BlkDev, pub empty_space: KiraSize, @@ -400,7 +406,7 @@ impl PartLayout { self.add_part(p_size, fs_type, gpt_label, fs_label, mount_point, role) } - pub fn gen_classic_layout(dev: BlkDev, efi_size: KiraSize, swap_size: KiraSize) -> Self { + pub fn gen_kira_layout(dev: BlkDev, efi_size: KiraSize, swap_size: KiraSize) -> Self { let mut res: PartLayout = PartLayout::new(dev); // UEFI partition @@ -408,7 +414,7 @@ impl PartLayout { .add_part( efi_size, FSType::VFAT, - Some("efi".into()), + Some("bee-efi".into()), Some("EFI".into()), Some("/efi".into()), Some(PartRole::EFI), @@ -416,7 +422,7 @@ impl PartLayout { .add_part_reserve( swap_size, FSType::BTRFS, - Some("root".into()), + Some("bee-root".into()), None, Some("/".into()), Some(PartRole::ROOT), @@ -461,7 +467,7 @@ fn parted_get_last_part_num(dev: &BlkDev) -> Result { match res.lines().last().and_then(|last_line| { last_line .split_once(':') - .and_then(|(first_part, a)| u32::from_str_radix(first_part, 10).ok()) + .and_then(|(first_part, _)| u32::from_str_radix(first_part, 10).ok()) }) { Some(n) => Ok(n), None => Err("Error parsing parted output".to_string()), diff --git a/src/stage.rs b/src/stage.rs index 1b112fd..c7f9bf9 100644 --- a/src/stage.rs +++ b/src/stage.rs @@ -18,87 +18,116 @@ This file contains basic enums and structs to be used with stages. */ -use std::collections::HashMap; +use crate::stages; + +// #[derive(Debug, Clone)] +// pub enum ConfigValue { +// String(String), +// I64(i64), +// U64(u64), +// F64(f64), +// Bool(bool), +// PartLayout(PartLayout), +// KiraSize(KiraSize), +// Vector(Vec), +// Dictionary(HashMap), +// } #[derive(Debug, Clone)] -pub enum ConfigValue { - String(String), - I64(i64), - U64(u64), - F64(f64), - Bool(bool), - Vector(Vec), - Dictionary(HashMap), -} - -#[derive(Debug, Clone)] -pub struct StageResult { - pub name: String, - pub config: Option>, - pub error: Option, +pub enum StageResult { + WelcomeStageResult(stages::welcome::WelcomeStageResult), + NetworkStageResult(stages::network::NetworkStageResult), + LocaleStageResult(stages::locale::LocaleStageResult), + TimeZoneStageResult(stages::timezone::TimeZoneStageResult), + KeyboardStageResult(stages::keyboard::KeyboardStageResult), + SecurityStageResult(stages::security::SecurityStageResult), + PartitionStageResult(stages::partition::PartitionStageResult), + None, } impl StageResult { - pub fn new(name: &str) -> Self { - Self { - name: name.into(), - config: None, - error: None, - } - } - - pub fn add_error(mut self, ex: String) -> Self { - self.error = Some(ex); - self - } - - pub fn add_val(mut self, val_name: &str, conf_val: ConfigValue) -> Self { - match &mut self.config { - Some(c) => { - c.insert(val_name.into(), conf_val); - } - None => { - self.config = Some(HashMap::from([(val_name.into(), conf_val)])); - } - } - self - } - - pub fn add_val_string(self, val_name: &str, v: String) -> Self { - self.add_val(val_name, ConfigValue::String(v)) - } - - pub fn add_val_bool(self, val_name: &str, v: bool) -> Self { - self.add_val(val_name, ConfigValue::Bool(v)) - } - - pub fn add_val_u64(self, val_name: &str, v: u64) -> Self { - self.add_val(val_name, ConfigValue::U64(v)) - } - - pub fn get_val(&self, val_name: &str) -> Option { - let v = self - .config - .as_ref() - .and_then(|hm| hm.get(val_name).cloned()); - return v; - } - - pub fn get_val_str(&self, val_name: &str) -> Option { - match self.get_val(val_name) { - Some(ConfigValue::String(v)) => Some(v), - _ => None, - } - } - - pub fn get_val_bool(&self, val_name: &str) -> Option { - match self.get_val(val_name) { - Some(ConfigValue::Bool(v)) => Some(v), - _ => None, + pub fn name(&self) -> String { + match self { + Self::LocaleStageResult(_) => "locale".into(), + Self::WelcomeStageResult(_) => "welcome".into(), + Self::NetworkStageResult(_) => "network".into(), + Self::TimeZoneStageResult(_) => "timezone".into(), + Self::KeyboardStageResult(_) => "keyboard".into(), + Self::PartitionStageResult(_) => "partition".into(), + Self::SecurityStageResult(_) => "security".into(), + Self::None => "none".into(), } } } +// impl StageResult { +// pub fn new(name: &str) -> Self { +// Self { +// name: name.into(), +// config: None, +// error: None, +// } +// } +// pub fn add_error(mut self, ex: String) -> Self { +// self.error = Some(ex); +// self +// } + +// pub fn add_val(mut self, val_name: &str, conf_val: ConfigValue) -> Self { +// match &mut self.config { +// Some(c) => { +// c.insert(val_name.into(), conf_val); +// } +// None => { +// self.config = Some(HashMap::from([(val_name.into(), conf_val)])); +// } +// } +// self +// } + +// pub fn add_val_string(self, val_name: &str, v: String) -> Self { +// self.add_val(val_name, ConfigValue::String(v)) +// } + +// pub fn add_val_bool(self, val_name: &str, v: bool) -> Self { +// self.add_val(val_name, ConfigValue::Bool(v)) +// } + +// pub fn add_val_u64(self, val_name: &str, v: u64) -> Self { +// self.add_val(val_name, ConfigValue::U64(v)) +// } + +// pub fn get_val(&self, val_name: &str) -> Option { +// let v = self +// .config +// .as_ref() +// .and_then(|hm| hm.get(val_name).cloned()); +// return v; +// } + +// pub fn get_val_str(&self, val_name: &str) -> Option { +// match self.get_val(val_name) { +// Some(ConfigValue::String(v)) => Some(v), +// _ => None, +// } +// } + +// pub fn get_val_bool(&self, val_name: &str) -> Option { +// match self.get_val(val_name) { +// Some(ConfigValue::Bool(v)) => Some(v), +// _ => None, +// } +// } + +// pub fn get_val_part_layout(&self, val_name: &str) -> Option { +// match self.get_val(val_name) { +// Some(ConfigValue::PartLayout(v)) => Some(v), +// _ => None, +// } +// } +// } + +#[derive(Debug, Clone)] pub struct KiraConfig { pub config_trail: Vec, } @@ -115,7 +144,7 @@ impl KiraConfig { pub fn get_stage(&self, name: &str) -> Option { self.config_trail .iter() - .find(|v| v.name == name) + .find(|v| v.name() == name) .and_then(|v| Some(v.clone())) } pub fn pop_last(&mut self) -> Option { diff --git a/src/stages/install/mod.rs b/src/stages/install/mod.rs index 4a54f9b..a006337 100644 --- a/src/stages/install/mod.rs +++ b/src/stages/install/mod.rs @@ -27,11 +27,11 @@ use log; use crate::{ - kira_theming, - stage::{KiraConfig, StageAction, StageResult}, + kira_disk_layout::{self, BlkDev, PartLayout}, kira_size::KiraSize, kira_theming, stage::{KiraConfig, StageAction, StageResult} }; -use iced::{Alignment, Task, futures, widget}; +use iced::{Alignment, Task, futures::{self, SinkExt}, widget}; use rust_i18n::t; +use iced::futures::channel::mpsc::{Sender}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum InstallationState { @@ -43,11 +43,12 @@ enum InstallationState { Error, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone)] pub struct InstallStage { state: InstallationState, progress: f32, progress_message: String, + kira_config: KiraConfig, } #[derive(Debug, Clone)] @@ -69,6 +70,32 @@ pub enum Update { } +fn partition_disk(disk_layout: PartLayout, password: Option) -> impl futures::Stream> { + use blocking; + + iced::stream::channel(100, |mut output: Sender>| async move { + for i in 0..=1000 { + //sleep(Duration::from_millis(10)).await; + let dev = disk_layout.dev.clone(); + // creating gpt partition table + match output.send(blocking::unblock(move || kira_disk_layout::parted_init_gpt_part_table(&dev)).await.and(Ok((1.0f32, String::new())))).await { + Err(ex) =>{ + log::error!("Error creating GPT partition table: {}", ex.to_string()); + return; + }, + _ => () + }; + + // Check if send fails (receiver dropped/cancelled) + // if output.send(res).await.is_err() { + // return; // Exit early if UI is gone + // } + } + + // Optional: Send completion or error state here + // output.send(Message::WorkFailed).await.ok(); + }) +} impl InstallStage { @@ -77,11 +104,12 @@ impl InstallStage { state: InstallationState::UserConfirmDialog, progress: 0.0, progress_message: String::new(), + kira_config: config.clone(), } } fn gen_result(&self) -> StageResult { - StageResult::new("install") + StageResult::None } pub fn update(&mut self, message: Message) -> Update { @@ -89,8 +117,16 @@ impl InstallStage { Message::UserDenies => Update::StgAct(StageAction::Back), Message::UserConfirms => { // starting installation process here + let part_data = self.kira_config.config_trail.iter().find_map(|v| match v { + StageResult::PartitionStageResult(res) => Some(res.clone()), + _ => None, + }).unwrap(); self.state = InstallationState::Partitionning; - Update::Task(Task::run(disk_part::check_connected(), Message::UpdateProgress)) + let disk_layout = part_data.part_layout.clone(); + let disk_password = part_data.password.clone(); + + + Update::Task(Task::run(partition_disk(disk_layout, disk_password), Message::UpdateProgress)) //Update::Task(Task::perform(, Message::PartitioningFinish)) } Message::StartPartitioning => Update::StgAct(StageAction::None), diff --git a/src/stages/keyboard/mod.rs b/src/stages/keyboard/mod.rs index c8a9aff..deb2221 100644 --- a/src/stages/keyboard/mod.rs +++ b/src/stages/keyboard/mod.rs @@ -18,10 +18,10 @@ This is Keyboar stage, used to select Keyboard Layouts */ -use log; use crate::kira_scroll_list::{self, ListViewMessage}; use crate::stage::{StageAction, StageResult}; use iced::{Alignment, Length, widget}; +use log; use rust_i18n::t; use std::collections::HashMap; @@ -124,6 +124,12 @@ pub struct KeyboardStage { // selected_kbd_layout_id: Option, } +#[derive(Debug, Clone, PartialEq)] +pub struct KeyboardStageResult { + pub keyboard_model: KeyboarModel, + pub keyboard_layout: KeyboarLayout, +} + #[derive(Debug, Clone)] pub enum Message { SelectKeyboardModel(KeyboarModel), @@ -274,16 +280,13 @@ impl KeyboardStage { } fn gen_result(&self) -> StageResult { - if let Some(model) = &self.model - && let Some(k_l) = &self.keyboard_layout - { - StageResult::new("keyboard") - .add_val_string("model", model.model.clone()) - .add_val_string("layout", k_l.to_result()) - } else { - StageResult::new("keyboard") - .add_error("Something go terrible wrong, there is no keyboard layouts.".into()) - } + StageResult::KeyboardStageResult(KeyboardStageResult { + keyboard_model: self.model.clone().expect("Keyboard model must be choosed!"), + keyboard_layout: self + .keyboard_layout + .clone() + .expect("Keyboard layout must be choosed!"), + }) } pub fn update(&mut self, message: Message) -> StageAction { diff --git a/src/stages/license/mod.rs b/src/stages/license/mod.rs index 60e310f..6c9cea6 100644 --- a/src/stages/license/mod.rs +++ b/src/stages/license/mod.rs @@ -43,8 +43,7 @@ pub enum Message { impl LicenseStage { fn accepted() -> StageResult { - StageResult::new("license") - .add_val_bool("accepted", true) + StageResult::None } pub fn update(&mut self, message: Message) -> stage::StageAction { diff --git a/src/stages/locale/mod.rs b/src/stages/locale/mod.rs index c22cff2..471dc4d 100644 --- a/src/stages/locale/mod.rs +++ b/src/stages/locale/mod.rs @@ -20,7 +20,7 @@ use crate::{ kira_theming, - stage::{ConfigValue, KiraConfig, StageAction, StageResult}, + stage::{KiraConfig, StageAction, StageResult}, }; use iced::{Alignment, widget}; use rust_i18n::t; @@ -138,6 +138,12 @@ pub struct LocaleStage { all_locale_text: String, } +#[derive(Debug, Clone, PartialEq)] +pub struct LocaleStageResult { + pub lang_locale: LocaleData, + pub formats_locale: LocaleData, +} + #[derive(Debug, Clone)] pub enum Message { SelectLangLocale(LocaleData), @@ -149,9 +155,10 @@ pub enum Message { impl LocaleStage { pub fn new(kira_config: &KiraConfig) -> Self { // get seelctet language code from welcome stage - let maybe_lang = kira_config - .get_stage("welcome") - .and_then(|v| v.config.and_then(|v| v.get("loc_code").cloned())); + let maybe_lang = kira_config.config_trail.iter().find_map(|v| match v { + StageResult::WelcomeStageResult(res) => Some(res.loc_code.clone()), + _ => None, + }); let raw_loc_codes = get_locales_codes_list_blocking().unwrap(); let raw_loc_descr = get_locales_description_blocking().unwrap(); @@ -174,7 +181,9 @@ impl LocaleStage { .collect(); // if we get lang code from wellcome stage, try to fing match with system locales - let lang_match = if let Some(ConfigValue::String(lang)) = maybe_lang && lang != "en" { + let lang_match = if let Some(lang) = maybe_lang + && lang != "en" + { let lang = lang.replace("-", "_").to_lowercase(); locales .iter() @@ -208,15 +217,16 @@ impl LocaleStage { if let Some(lang_locale) = &self.lang_locale && let Some(formats_locale) = &self.formats_locale { - StageResult::new("locale") - .add_val_string("lang_locale", lang_locale.code.clone()) - .add_val_string("formats_locale", formats_locale.code.clone()) - + StageResult::LocaleStageResult(LocaleStageResult { + lang_locale: lang_locale.clone(), + formats_locale: formats_locale.clone(), + }) } else { let loc = LocaleData::default(); - StageResult::new("locale") - .add_val_string("lang_locale", loc.code.clone()) - .add_val_string("formats_locale", loc.code) + StageResult::LocaleStageResult(LocaleStageResult { + lang_locale: loc.clone(), + formats_locale: loc, + }) } } diff --git a/src/stages/network/mod.rs b/src/stages/network/mod.rs index 1ee808e..765431c 100644 --- a/src/stages/network/mod.rs +++ b/src/stages/network/mod.rs @@ -19,17 +19,16 @@ it needed for installation to process. */ -use log; use iced::{Alignment, Task, widget}; use iced_moving_picture::widget::apng; +use log; use rust_i18n::t; use toml::Table; use crate::stage; use crate::stage::StageResult; -#[derive(Debug, Clone)] -#[derive(PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum State { Cheking, Normal, @@ -53,6 +52,12 @@ pub struct NetworkStage { status_message: String, } +#[derive(Debug, Clone, PartialEq)] +pub struct NetworkStageResult { + pub internet_active: bool, + pub use_net_settings: bool, +} + #[derive(Debug, Clone)] pub enum Message { Next, @@ -127,9 +132,10 @@ impl NetworkStage { } fn gen_result(&self) -> StageResult { - StageResult::new("network") - .add_val_bool("internet_active", self.internet_active) - .add_val_bool("use_net_settings", self.use_net_settings) + StageResult::NetworkStageResult(NetworkStageResult { + internet_active: self.internet_active, + use_net_settings: self.use_net_settings, + }) } pub fn update(&mut self, message: Message) -> UpdateResult { diff --git a/src/stages/partition/mod.rs b/src/stages/partition/mod.rs index c97bdcd..ef28927 100644 --- a/src/stages/partition/mod.rs +++ b/src/stages/partition/mod.rs @@ -77,11 +77,28 @@ fn part_to_ct_params(part: &PartInfo, dev_size: KiraSize) -> (String, u16, Color (part.to_string(), fill_ratio, part_color) } + + +#[derive(Debug, Clone, PartialEq)] +pub struct PartitionStageResult { + pub swap_mode: SwapMode, + pub swap_size: KiraSize, + pub efi_size: KiraSize, + pub use_zram: bool, + pub secure_boot: bool, + pub encrypt_drive: bool, + pub password: Option, + pub part_layout: PartLayout, +} + + + #[derive(Debug, Clone)] pub struct PartitionStage { device: Option, devices: Vec, swap_mode: Option, + efi_size: KiraSize, use_zram: bool, secure_boot: bool, encrypt_drive: bool, @@ -90,10 +107,13 @@ pub struct PartitionStage { custom_swap_size_str: String, selected_disk_parts: Option>, generated_disk_parts: Option>, + generated_part_layout: Option, system_ram_size: KiraSize, vram_of_all_gpus_size: KiraSize, } + + #[derive(Debug, Clone)] pub enum Message { SelectDevice(BlkDev), @@ -112,15 +132,24 @@ impl PartitionStage { pub fn new(toml_config: &Table) -> Result { let maybe_dev_list = BlkDev::list_sys_blk_dev(); log::info!("hiii from partition"); - let min_disk_size_mb = toml_config + let mut min_disk_size_mb = 8192; + let mut efi_size_mb = 128; + if let Some(part_table) = toml_config .get("partition") - .and_then(|v| v.as_table()) - .and_then(|v| v.get("min_disk_size_mb")) + .and_then(|v| v.as_table()) { + + min_disk_size_mb = part_table.get("min_disk_size_mb") .and_then(|v| v.as_integer()) .unwrap_or(8192); - let min_disk_size: KiraSize = KiraSize::new_mb(min_disk_size_mb.try_into().unwrap_or(8192)); + efi_size_mb = part_table.get("efi_size_mb") + .and_then(|v| v.as_integer()) + .unwrap_or(128); + } + + let min_disk_size: KiraSize = KiraSize::new_mb(min_disk_size_mb.try_into().unwrap_or(8192)); + let efi_size: KiraSize = KiraSize::new_mb(efi_size_mb.try_into().unwrap_or(128)); let sec_boot_setup = match kira_sysinfo::get_secure_boot_status() { Ok(sb_status) => sb_status.setup_mode, @@ -160,8 +189,10 @@ impl PartitionStage { secure_boot_in_setup_mode: sec_boot_setup, custom_swap_size_mb: 1024, custom_swap_size_str: "1024MB".into(), + efi_size: efi_size, selected_disk_parts: None, generated_disk_parts: None, + generated_part_layout:None, system_ram_size: system_ram_size, vram_of_all_gpus_size: vram_of_all_gpus_size, }) @@ -209,36 +240,24 @@ impl PartitionStage { fn gen_layout(&mut self) { if let Some(dev) = self.device.clone() { let swap_size: KiraSize = self.get_swap_size(); - self.generated_disk_parts = Some( - PartLayout::gen_classic_layout(dev.clone(), KiraSize::new_mb(512), swap_size) - .part_list + let patr_layout = PartLayout::gen_kira_layout(dev.clone(), self.efi_size, swap_size); + self.generated_disk_parts = Some(patr_layout.part_list .iter() .map(|part_info| part_to_ct_params(part_info, dev.size)) .collect(), ); + self.generated_part_layout = Some(patr_layout); } } fn gen_result(&self) -> StageResult { - let swap_size: KiraSize = self.get_swap_size(); - let dev_name = self - .device - .clone() - .expect("Device should be selected!") - .name; - StageResult::new("partition") - .add_val_string("device", dev_name) - .add_val_string( - "swap_mode", - self.swap_mode - .clone() - .unwrap_or(SwapMode::NoSwap) - .to_string(), - ) - .add_val_u64("swap_size_mb", swap_size.mb()) - .add_val_bool("use_zram", self.use_zram) - .add_val_bool("secure_boot", self.secure_boot) - .add_val_bool("encrypt_drive", self.encrypt_drive) + let disk_layout = self.generated_part_layout.clone().expect("Layout must be generated!"); + + StageResult::PartitionStageResult(PartitionStageResult { swap_mode: self.swap_mode.clone().unwrap(), + swap_size: self.get_swap_size(), efi_size: self.efi_size, + use_zram: self.use_zram, secure_boot: self.secure_boot, encrypt_drive: true, + password: Some("123456".to_string()), part_layout: disk_layout }) + } pub fn update(&mut self, message: Message) -> StageAction { @@ -258,17 +277,18 @@ impl PartitionStage { } }; - let swap_size: KiraSize = self.get_swap_size(); + // let swap_size: KiraSize = self.get_swap_size(); - self.generated_disk_parts = Some( - PartLayout::gen_classic_layout(dev.clone(), KiraSize::new_mb(128), swap_size) - .part_list - .iter() - .map(|part_info| part_to_ct_params(part_info, dev.size)) - .collect(), - ); + // self.generated_disk_parts = Some( + // PartLayout::gen_kira_layout(dev.clone(), self.efi_size, swap_size) + // .part_list + // .iter() + // .map(|part_info| part_to_ct_params(part_info, dev.size)) + // .collect(), + // ); self.device = Some(dev); + self.gen_layout(); StageAction::None }, Message::SelectSwapMode(sm) => { diff --git a/src/stages/security/mod.rs b/src/stages/security/mod.rs index c7c03b9..98d26f8 100644 --- a/src/stages/security/mod.rs +++ b/src/stages/security/mod.rs @@ -71,6 +71,14 @@ pub struct SecurityStage { root_password_strenght: PasswordStrenght, } +#[derive(Debug, Clone)] +pub struct SecurityStageResult { + pub user_name: String, + pub user_full_name: String, + pub user_password: String, + pub root_password: String, +} + #[derive(Debug, Clone)] pub enum Message { ToggleReusePass(bool), @@ -108,12 +116,12 @@ impl SecurityStage { } fn gen_result(&self) -> StageResult { - StageResult::new("security") - .add_val_string("user_name", self.user_name.clone()) - .add_val_string("user_full_name", self.user_full_name.clone()) - .add_val_string("user_full_name", self.user_full_name.clone()) - .add_val_string("user_password", self.user_password.clone()) - .add_val_string("root_password", self.root_password.clone()) + StageResult::SecurityStageResult(SecurityStageResult { + user_name: self.user_name.clone(), + user_full_name: self.user_full_name.clone(), + user_password: self.user_password.clone(), + root_password: self.root_password.clone(), + }) } pub fn update(&mut self, message: Message) -> StageAction { diff --git a/src/stages/timezone/mod.rs b/src/stages/timezone/mod.rs index 7ce3151..c196fc4 100644 --- a/src/stages/timezone/mod.rs +++ b/src/stages/timezone/mod.rs @@ -18,9 +18,9 @@ This is TimeZone stage, used to select timezone */ -use log; use crate::stage::{StageAction, StageResult}; use iced::{Alignment, Length, widget}; +use log; use rust_i18n::t; use std::collections::HashMap; @@ -60,6 +60,11 @@ pub struct TimeZoneStage { selected_zone_text: String, } +#[derive(Debug, Clone)] +pub struct TimeZoneStageResult { + pub time_zone: TimeZoneData, +} + #[derive(Debug, Clone)] pub enum Message { SelectRegion(kira_scroll_list::ListViewMessage), @@ -146,14 +151,12 @@ impl TimeZoneStage { } fn gen_result(&self) -> StageResult { - if let Some(time_zone) = &self.selected_zone { - StageResult::new("time_zone") - .add_val_string("name", time_zone.to_string()) - .add_val_string("region", time_zone.region.clone()) - .add_val_string("zone", time_zone.zone.clone()) - } else { - StageResult::new("time_zone") - } + StageResult::TimeZoneStageResult(TimeZoneStageResult { + time_zone: self + .selected_zone + .clone() + .expect("Timezone must be selected!"), + }) } pub fn update(&mut self, message: Message) -> StageAction { @@ -201,10 +204,14 @@ impl TimeZoneStage { widget::row![ kira_scroll_list::list_view(&self.regions, self.region_id, Length::Shrink) .map(Message::SelectRegion), - kira_scroll_list::list_view(&self.zones, self.zone_id, Length::FillPortion(1)) - .map(Message::SelectZone), + kira_scroll_list::list_view( + &self.zones, + self.zone_id, + Length::FillPortion(1) + ) + .map(Message::SelectZone), ] - .padding([0,10]) + .padding([0, 10]) .spacing(10) .height(Length::Shrink), widget::text(self.selected_zone_text.clone()) diff --git a/src/stages/welcome/mod.rs b/src/stages/welcome/mod.rs index bd06716..adf2853 100644 --- a/src/stages/welcome/mod.rs +++ b/src/stages/welcome/mod.rs @@ -1,26 +1,27 @@ - // - // Copyright (C) <2026> +// +// Copyright (C) <2026> - // This program 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. +// This program 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. - // This program 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 this program. If not, see . +// This program 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 this program. If not, see . /* - This is Welcome stage, used to greet used and allow user to choose program language - */ + This is Welcome stage, used to greet used and allow user to choose program language +*/ - -use crate::{stage::{StageAction, StageResult}, kira_theming}; +use crate::{ + kira_theming, + stage::{StageAction, StageResult}, +}; use iced::{Alignment, widget}; use rust_i18n::t; @@ -42,6 +43,12 @@ pub struct WelcomeStage { locales: Vec, } +#[derive(Debug, Clone, PartialEq)] +pub struct WelcomeStageResult { + pub loc_code: String, + pub loc_name: String, +} + #[derive(Debug, Clone)] pub enum Message { SelectLocale(LocData), @@ -51,7 +58,6 @@ pub enum Message { impl WelcomeStage { pub fn new() -> Self { - Self { locale: Some(LocData { name: "English".into(), @@ -69,13 +75,15 @@ impl WelcomeStage { fn gen_result(&self) -> StageResult { if let Some(loc) = &self.locale { - StageResult::new("welcome") - .add_val_string("loc_code", loc.code.clone()) - .add_val_string("loc_name", loc.name.clone()) + StageResult::WelcomeStageResult(WelcomeStageResult { + loc_code: loc.code.clone(), + loc_name: loc.name.clone(), + }) } else { - StageResult::new("welcome") - .add_val_string("loc_code", "en".to_string()) - .add_val_string("loc_name", "English".to_string()) + StageResult::WelcomeStageResult(WelcomeStageResult { + loc_code: "en".to_string(), + loc_name: "English".to_string(), + }) } } @@ -96,8 +104,7 @@ impl WelcomeStage { let exit_button = widget::button(widget::text(t!("button.exit"))).on_press(Message::Exit); // Embed the image bytes into the executable - let welcom_logo_handle = - widget::image::Handle::from_bytes(kira_theming::get_logo_bytes()); + let welcom_logo_handle = widget::image::Handle::from_bytes(kira_theming::get_logo_bytes()); widget::column![ widget::container(