Files
kira-installer/src/main.rs
T

212 lines
6.8 KiB
Rust
Raw Normal View History

2026-04-23 00:44:01 +02:00
// <Kira Installer - universal Linux installer.>
// Copyright (C) <2026> <Kira Foundation>
2026-04-23 00:44:01 +02:00
// 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.
2026-04-23 00:44:01 +02:00
// 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.
2026-04-23 00:44:01 +02:00
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
/*
2026-04-23 00:44:01 +02:00
This file is the main application file.
Main logic and stuff is located here. Including config loading.
stages loading, switching between stages, and stuff.
*/
use iced::widget;
2026-04-22 14:21:24 +02:00
use std::process::ExitCode;
use iced::{Element, Task};
2026-04-23 00:44:01 +02:00
use crate::stage::{KiraConfig, StageAction};
use crate::stages::license;
2026-04-22 14:21:24 +02:00
use crate::stages::network;
use crate::stages::welcome;
use crate::stages::welcome::WelcomeStage;
rust_i18n::i18n!("src/locales", fallback = "en");
mod stage;
mod stages;
mod theme;
enum Views {
Start,
Welcome(welcome::WelcomeStage),
License(license::LicenseStage),
2026-04-22 14:21:24 +02:00
Network(stages::network::NetworkStage),
}
enum Message {
2026-04-22 14:21:24 +02:00
Start,
2026-04-23 00:44:01 +02:00
Welcome(welcome::Message),
License(license::Message),
Network(stages::network::Message),
}
struct KiraState {
current_view: Views,
toml_config: toml::Table,
config: KiraConfig,
}
2026-04-22 14:21:24 +02:00
const CONFIG_PATH_STR: &str = "kira_config.toml";
2026-04-22 14:21:24 +02:00
fn load_kira_config(config_path: &str) -> Result<toml::Table, Box<dyn std::error::Error>> {
use std::fs;
use toml::Table;
// 1. Read the file content into a String
let content = fs::read_to_string(config_path)?;
2026-04-22 14:21:24 +02:00
// 2. Parse the string into a Table
let table: Table = content.parse()?;
2026-04-22 14:21:24 +02:00
println!("{:?}", table);
Ok(table)
}
impl KiraState {
fn boot() -> (Self, Task<Message>) {
2026-04-23 00:44:01 +02:00
(
Self {
current_view: Views::Start,
toml_config: toml::Table::new(),
config: KiraConfig {
config_trail: Vec::new(),
},
},
Task::done(Message::Start),
)
}
}
2026-04-22 14:21:24 +02:00
// impl KiraState {
// fn new(toml_config: toml::Table) -> Self {
// Self {
// current_view: Views::Start,
// toml_config: toml_config,
// config: KiraConfig { config_trail: Vec::new() }
// }
// }
2026-04-23 00:44:01 +02:00
// }
2026-04-22 14:21:24 +02:00
fn view(k_state: &KiraState) -> Element<'_, Message> {
match &k_state.current_view {
2026-04-23 00:44:01 +02:00
Views::Start => Element::new(widget::space()),
Views::Welcome(wellcome_stage) => wellcome_stage.view().map(Message::Welcome),
Views::License(license_stage) => license_stage.view().map(Message::License),
2026-04-22 14:21:24 +02:00
Views::Network(network_stage) => network_stage.view().map(Message::Network),
}
}
fn update(k_state: &mut KiraState, message: Message) -> Task<Message> {
match message {
2026-04-23 00:44:01 +02:00
Message::Start => match load_kira_config(CONFIG_PATH_STR) {
Ok(conf) => {
println!("Config loaded!");
k_state.toml_config = conf;
k_state.current_view = Views::Welcome(WelcomeStage::new());
Task::none()
}
Err(ex) => {
println!("Error reading config {}: {}", CONFIG_PATH_STR, ex);
iced::exit()
2026-04-22 14:21:24 +02:00
}
},
Message::Welcome(wlc_msg) => {
if let Views::Welcome(wlc_view) = &mut k_state.current_view {
let action = wlc_view.update(wlc_msg);
if let StageAction::Next(welcome_res) = action {
k_state.config.config_trail.push(welcome_res);
2026-04-23 00:44:01 +02:00
k_state.current_view = Views::License(license::LicenseStage {});
}
}
Task::none()
2026-04-23 00:44:01 +02:00
}
Message::License(license_message) => {
if let Views::License(license_view) = &mut k_state.current_view {
let action = license_view.update(license_message);
match action {
StageAction::Next(license_res) => {
k_state.config.config_trail.push(license_res);
2026-04-23 00:44:01 +02:00
k_state.current_view =
Views::Network(network::NetworkStage::new(&k_state.toml_config));
Task::done(Message::Network(network::Message::CheckNetwork))
}
StageAction::Abort(_) => iced::exit(),
StageAction::Back => iced::exit(),
2026-04-23 00:44:01 +02:00
StageAction::None => Task::none(),
}
2026-04-23 00:44:01 +02:00
} else {
Task::none()
}
2026-04-23 00:44:01 +02:00
}
2026-04-22 14:21:24 +02:00
Message::Network(network_message) => {
if let Views::Network(network_view) = &mut k_state.current_view {
2026-04-23 00:44:01 +02:00
let update_result = network_view.update(network_message);
match update_result {
network::UpdateResult::Task(t) => t.map(Message::Network),
network::UpdateResult::StageAction(action) => match action {
StageAction::Next(network_res) => {
k_state.config.config_trail.push(network_res);
iced::exit()
}
StageAction::Back => {
k_state.current_view = Views::License(license::LicenseStage {});
Task::none()
}
_ => Task::none(),
},
}
} else {
2026-04-22 14:21:24 +02:00
Task::none()
}
}
}
}
// pub fn main_interface() -> iced::Result {
// iced::run(WellcomeStage::update, WellcomeStage::view)
// }
2026-04-22 14:21:24 +02:00
pub fn main() -> ExitCode {
// let app_init = || {
// let mut k_state = KiraState::default()
// k_state.current_view = Views::Welcome(WelcomeStage::new());
// k_stateapp_init
// };
let iced_result = iced::application(KiraState::boot, update, view)
2026-04-23 00:44:01 +02:00
.window(iced::window::Settings {
icon: Some(
iced::window::icon::from_file_data(include_bytes!("icon.png"), None)
.expect("icon should be a valid PNG"),
),
..Default::default()
})
.centered()
.theme(theme::main_theme())
2026-04-22 14:21:24 +02:00
.run();
match iced_result {
Ok(()) => ExitCode::SUCCESS,
Err(_) => ExitCode::from(42), // Custom error code
}
}
// fn main() {
// println!("Hello, world!");
// println!("{}", t!("wellcome.text"));
// // Initialize the state
// let _res = main_interface();
// }