Compare commits

...

4 Commits

9 changed files with 520 additions and 167 deletions
Generated
+59 -59
View File
@@ -85,9 +85,9 @@ dependencies = [
[[package]] [[package]]
name = "android-build" name = "android-build"
version = "0.1.3" version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cac4c64175d504608cf239756339c07f6384a476f97f20a7043f92920b0b8fd" checksum = "f9fc9904ad2ad097c3c1cfe2eacaaf0fc24710936fa9ed941cb310b7c6ed2ab7"
dependencies = [ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
@@ -397,9 +397,9 @@ dependencies = [
[[package]] [[package]]
name = "avif-serialize" name = "avif-serialize"
version = "0.8.8" version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "375082f007bd67184fb9c0374614b29f9aaa604ec301635f72338bb65386a53d" checksum = "e7178fe5f7d460b13895ebb9dcb28a3a6216d2df2574a0806cb51b555d297f38"
dependencies = [ dependencies = [
"arrayvec", "arrayvec",
] ]
@@ -602,9 +602,9 @@ dependencies = [
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.2.61" version = "1.2.62"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98"
dependencies = [ dependencies = [
"find-msvc-tools", "find-msvc-tools",
"jobserver", "jobserver",
@@ -935,9 +935,9 @@ checksum = "edf234dd1594d6dd434a8fb8cada51ddbbc593e40e4a01556a0b31c62da2775b"
[[package]] [[package]]
name = "either" name = "either"
version = "1.15.0" version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
[[package]] [[package]]
name = "endi" name = "endi"
@@ -1541,9 +1541,9 @@ dependencies = [
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.17.0" version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
[[package]] [[package]]
name = "heck" name = "heck"
@@ -1858,7 +1858,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown 0.17.0", "hashbrown 0.17.1",
"serde", "serde",
"serde_core", "serde_core",
] ]
@@ -1986,9 +1986,9 @@ dependencies = [
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.97" version = "0.3.98"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1840c94c045fbcf8ba2812c95db44499f7c64910a912551aaaa541decebcacf" checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"futures-util", "futures-util",
@@ -2103,7 +2103,7 @@ dependencies = [
"bitflags 2.11.1", "bitflags 2.11.1",
"libc", "libc",
"plain", "plain",
"redox_syscall 0.7.4", "redox_syscall 0.7.5",
] ]
[[package]] [[package]]
@@ -2342,9 +2342,9 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
[[package]] [[package]]
name = "no_std_io2" name = "no_std_io2"
version = "0.9.3" version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b51ed7824b6e07d354605f4abb3d9d300350701299da96642ee084f5ce631550" checksum = "418abd1b6d34fbf6cae440dc874771b0525a604428704c76e48b29a5e67b8003"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@@ -2366,9 +2366,9 @@ checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
[[package]] [[package]]
name = "normpath" name = "normpath"
version = "1.5.0" version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf23ab2b905654b4cb177e30b629937b3868311d4e1cba859f899c041046e69b" checksum = "b9985ef7269fa99f3b12437bb698381da2428743ab90f20393f399fa14cab21a"
dependencies = [ dependencies = [
"windows-sys 0.61.2", "windows-sys 0.61.2",
] ]
@@ -2898,18 +2898,18 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[package]] [[package]]
name = "pin-project" name = "pin-project"
version = "1.1.11" version = "1.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924"
dependencies = [ dependencies = [
"pin-project-internal", "pin-project-internal",
] ]
[[package]] [[package]]
name = "pin-project-internal" name = "pin-project-internal"
version = "1.1.11" version = "1.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -3051,18 +3051,18 @@ dependencies = [
[[package]] [[package]]
name = "profiling" name = "profiling"
version = "1.0.17" version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" checksum = "3d595e54a326bc53c1c197b32d295e14b169e3cfeaa8dc82b529f947fba6bcf5"
dependencies = [ dependencies = [
"profiling-procmacros", "profiling-procmacros",
] ]
[[package]] [[package]]
name = "profiling-procmacros" name = "profiling-procmacros"
version = "1.0.17" version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b" checksum = "4488a4a36b9a4ba6b9334a32a39971f77c1436ec82c38707bce707699cc3bbcb"
dependencies = [ dependencies = [
"quote", "quote",
"syn", "syn",
@@ -3091,9 +3091,9 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
[[package]] [[package]]
name = "quick-xml" name = "quick-xml"
version = "0.39.2" version = "0.39.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "958f21e8e7ceb5a1aa7fa87fab28e7c75976e0bfe7e23ff069e0a260f894067d" checksum = "cdcc8dd4e2f670d309a5f0e83fe36dfdc05af317008fea29144da1a2ac858e5e"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@@ -3294,9 +3294,9 @@ dependencies = [
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.7.4" version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" checksum = "4666a1a60d8412eab19d94f6d13dcc9cea0a5ef4fdf6a5db306537413c661b1b"
dependencies = [ dependencies = [
"bitflags 2.11.1", "bitflags 2.11.1",
] ]
@@ -3641,9 +3641,9 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
[[package]] [[package]]
name = "siphasher" name = "siphasher"
version = "1.0.2" version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649"
[[package]] [[package]]
name = "skrifa" name = "skrifa"
@@ -3877,10 +3877,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
dependencies = [ dependencies = [
"fastrand 2.4.1", "fastrand 2.4.1",
"getrandom 0.4.2", "getrandom 0.3.4",
"once_cell", "once_cell",
"rustix 1.1.4", "rustix 1.1.4",
"windows-sys 0.61.2", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
@@ -4034,7 +4034,7 @@ dependencies = [
"toml_datetime 1.1.1+spec-1.1.0", "toml_datetime 1.1.1+spec-1.1.0",
"toml_parser", "toml_parser",
"toml_writer", "toml_writer",
"winnow 1.0.2", "winnow 1.0.3",
] ]
[[package]] [[package]]
@@ -4078,7 +4078,7 @@ dependencies = [
"indexmap", "indexmap",
"toml_datetime 1.1.1+spec-1.1.0", "toml_datetime 1.1.1+spec-1.1.0",
"toml_parser", "toml_parser",
"winnow 1.0.2", "winnow 1.0.3",
] ]
[[package]] [[package]]
@@ -4087,7 +4087,7 @@ version = "1.1.2+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
dependencies = [ dependencies = [
"winnow 1.0.2", "winnow 1.0.3",
] ]
[[package]] [[package]]
@@ -4277,9 +4277,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.120" version = "0.2.121"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df52b6d9b87e0c74c9edfa1eb2d9bf85e5d63515474513aa50fa181b3c4f5db1" checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"once_cell", "once_cell",
@@ -4290,9 +4290,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-futures" name = "wasm-bindgen-futures"
version = "0.4.70" version = "0.4.71"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af934872acec734c2d80e6617bbb5ff4f12b052dd8e6332b0817bce889516084" checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8"
dependencies = [ dependencies = [
"js-sys", "js-sys",
"wasm-bindgen", "wasm-bindgen",
@@ -4300,9 +4300,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro" name = "wasm-bindgen-macro"
version = "0.2.120" version = "0.2.121"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b1041f495fb322e64aca85f5756b2172e35cd459376e67f2a6c9dffcedb103" checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578"
dependencies = [ dependencies = [
"quote", "quote",
"wasm-bindgen-macro-support", "wasm-bindgen-macro-support",
@@ -4310,9 +4310,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro-support" name = "wasm-bindgen-macro-support"
version = "0.2.120" version = "0.2.121"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dcd0ff20416988a18ac686d4d4d0f6aae9ebf08a389ff5d29012b05af2a1b41" checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"proc-macro2", "proc-macro2",
@@ -4323,9 +4323,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-shared" name = "wasm-bindgen-shared"
version = "0.2.120" version = "0.2.121"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49757b3c82ebf16c57d69365a142940b384176c24df52a087fb748e2085359ea" checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@@ -4515,9 +4515,9 @@ dependencies = [
[[package]] [[package]]
name = "web-sys" name = "web-sys"
version = "0.3.97" version = "0.3.98"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2eadbac71025cd7b0834f20d1fe8472e8495821b4e9801eb0a60bd1f19827602" checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa"
dependencies = [ dependencies = [
"js-sys", "js-sys",
"wasm-bindgen", "wasm-bindgen",
@@ -5041,9 +5041,9 @@ dependencies = [
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "1.0.2" version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@@ -5246,7 +5246,7 @@ dependencies = [
"uds_windows", "uds_windows",
"uuid", "uuid",
"windows-sys 0.61.2", "windows-sys 0.61.2",
"winnow 1.0.2", "winnow 1.0.3",
"zbus_macros", "zbus_macros",
"zbus_names", "zbus_names",
"zvariant", "zvariant",
@@ -5274,7 +5274,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7074f3e50b894eac91750142016d30d0a89be8e67dbfd9704fb875825760e52d" checksum = "7074f3e50b894eac91750142016d30d0a89be8e67dbfd9704fb875825760e52d"
dependencies = [ dependencies = [
"serde", "serde",
"winnow 1.0.2", "winnow 1.0.3",
"zvariant", "zvariant",
] ]
@@ -5336,23 +5336,23 @@ dependencies = [
[[package]] [[package]]
name = "zvariant" name = "zvariant"
version = "5.10.1" version = "5.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4db0ecb8987cf5e92653c57c098f7f0e39a03112edb796f4fe089fb7eaa14ff" checksum = "1c1567a6ec68df868cbbfde844cfc6d81649fe5109a62b116b19fabd53e618ee"
dependencies = [ dependencies = [
"endi", "endi",
"enumflags2", "enumflags2",
"serde", "serde",
"winnow 1.0.2", "winnow 1.0.3",
"zvariant_derive", "zvariant_derive",
"zvariant_utils", "zvariant_utils",
] ]
[[package]] [[package]]
name = "zvariant_derive" name = "zvariant_derive"
version = "5.10.1" version = "5.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b949b639ab1b4bed763aa7481ba0e368af68d8b55532f8ed4bec86a59f2ca98" checksum = "c7d5b780599bbde114e39d9a0799577fad1ced5105d38515745f7b3099d8ceda"
dependencies = [ dependencies = [
"proc-macro-crate", "proc-macro-crate",
"proc-macro2", "proc-macro2",
@@ -5371,5 +5371,5 @@ dependencies = [
"quote", "quote",
"serde", "serde",
"syn", "syn",
"winnow 1.0.2", "winnow 1.0.3",
] ]
+1 -1
View File
@@ -5,7 +5,7 @@ edition = "2024"
[dependencies] [dependencies]
blocking = "1.6" blocking = "1.6"
iced = { version = "0.14", features = ["smol", "image"] } iced = { version = "0.14", default-features = false, features = ["crisp", "linux-theme-detection", "web-colors", "wgpu", "x11", "wayland", "smol", "image"] }
iced_moving_picture = "0" iced_moving_picture = "0"
rust-i18n = "3" rust-i18n = "3"
toml = "1" toml = "1"
+7 -2
View File
@@ -9,6 +9,7 @@ pub fn color_bar<Message: 'static>(
let mut c_b = Row::new().height(bar_height); let mut c_b = Row::new().height(bar_height);
if let Some(items) = maybe_items { if let Some(items) = maybe_items {
for (bar_text, bar_fill, bar_color) in items { for (bar_text, bar_fill, bar_color) in items {
c_b = c_b.push( c_b = c_b.push(
container(text(bar_text).color(Color::BLACK).size(iced::Pixels(14.0))) container(text(bar_text).color(Color::BLACK).size(iced::Pixels(14.0)))
@@ -16,9 +17,13 @@ pub fn color_bar<Message: 'static>(
.width(Length::FillPortion(bar_fill)) .width(Length::FillPortion(bar_fill))
.style(move |_| container::background(bar_color)) .style(move |_| container::background(bar_color))
.align_x(Alignment::Center) .align_x(Alignment::Center)
.align_y(Alignment::Center), .align_y(Alignment::Center)
.padding(2),
); );
} }
} }
c_b.into() container(c_b.spacing(2))
.style(container::rounded_box)
.padding(3)
.into()
} }
+100 -51
View File
@@ -1,53 +1,55 @@
// <Kira Installer - universal Linux installer.>
// Copyright (C) <2026> <Kira Foundation>
// 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 <https://www.gnu.org/licenses/>.
/*
Functions for working with disk layout
*/
use std::collections::HashMap; use std::collections::HashMap;
use crate::kira_size::{KiraSize};
pub fn format_bytes_size(size: u64) -> String {
let suffixs: [&str; 5] = ["KB", "MB", "GB", "TB", "PB"];
if size < 1000 {
format!("{}B", size)
} else {
let mut s = size as f64;
let mut idx = 0;
for i in 0..5 {
s = s / 1024.0;
idx = i;
if s < 1000.0 {
break;
}
}
format!("{:.2}{}", s, suffixs[idx])
}
}
/// ///
/// size - device size in bytes /// size - device size in bytes
/// sector size - default 4096 /// sector size - default 4096
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct BlkDev { pub struct BlkDev {
pub name: String, pub name: String,
pub size: u64, pub size: KiraSize,
pub sector_size: u32, pub sector_size: KiraSize,
} }
impl std::fmt::Display for BlkDev { impl std::fmt::Display for BlkDev {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} ({})", &self.name, format_bytes_size(self.size)) write!(f, "{} ({})", &self.name, self.size)
} }
} }
impl BlkDev { impl BlkDev {
pub fn new(name: String, size: u64) -> Self { pub fn new(name: String, size: KiraSize) -> Self {
Self { Self {
name: name, name: name,
size: size, size: size,
sector_size: 4096, sector_size: KiraSize::new(4096),
} }
} }
pub fn from_hash_map(data: &HashMap<String, String>) -> Option<Self> { pub fn from_hash_map(data: &HashMap<String, String>) -> Option<Self> {
Some(Self { Some(Self {
name: data.get("NAME")?.clone(), name: data.get("NAME")?.clone(),
size: u64::from_str_radix(data.get("SIZE")?, 10).ok()?, size: KiraSize::from_str_bytes(data.get("SIZE")?)?,
sector_size: 4096, sector_size: KiraSize::new(4096),
}) })
} }
/// this is blocking function /// this is blocking function
@@ -151,15 +153,26 @@ impl FSType {
// } // }
// } // }
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PartRole {
EFI,
ROOT,
HOME,
SWAP,
LuksRoot,
LuksHome,
}
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct PartInfo { pub struct PartInfo {
pub name: String, pub name: String,
pub size: u64, pub size: KiraSize,
pub start: u64, pub start: KiraSize,
pub fs_type: FSType, pub fs_type: FSType,
pub gpt_label: Option<String>, pub gpt_label: Option<String>,
pub fs_label: Option<String>, pub fs_label: Option<String>,
pub mount_point: Option<String>, pub mount_point: Option<String>,
pub role: Option<PartRole>,
} }
impl std::fmt::Display for PartInfo { impl std::fmt::Display for PartInfo {
@@ -169,7 +182,7 @@ impl std::fmt::Display for PartInfo {
"{} {} {}", "{} {} {}",
&self.name, &self.name,
&self.fs_type, &self.fs_type,
format_bytes_size(self.size) self.size
) )
} }
} }
@@ -178,8 +191,8 @@ impl PartInfo {
pub fn from_hash_map(data: &HashMap<String, String>) -> Option<Self> { pub fn from_hash_map(data: &HashMap<String, String>) -> Option<Self> {
Some(Self { Some(Self {
name: data.get("NAME")?.clone(), name: data.get("NAME")?.clone(),
size: u64::from_str_radix(data.get("SIZE")?, 10).ok()?, size: KiraSize::from_str_bytes(data.get("SIZE")?)?,
start: 0, start: KiraSize::new(0),
fs_type: FSType::from_str(data.get("FSTYPE")?), fs_type: FSType::from_str(data.get("FSTYPE")?),
gpt_label: data gpt_label: data
.get("PARTLABEL") .get("PARTLABEL")
@@ -190,6 +203,7 @@ impl PartInfo {
mount_point: data mount_point: data
.get("MOUNTPOINT") .get("MOUNTPOINT")
.and_then(|v| if v.is_empty() { None } else { Some(v.clone()) }), .and_then(|v| if v.is_empty() { None } else { Some(v.clone()) }),
role: None,
}) })
} }
} }
@@ -287,7 +301,7 @@ pub fn align_part(size: u64, start: u64, align: u64) -> Option<(u64, u64, u64)>
pub struct PartLayout { pub struct PartLayout {
pub dev: BlkDev, pub dev: BlkDev,
pub empty_space: u64, pub empty_space: KiraSize,
pub part_list: Vec<PartInfo>, pub part_list: Vec<PartInfo>,
} }
@@ -302,7 +316,7 @@ impl PartLayout {
pub fn read_from_disk(dev: &BlkDev) -> Result<Self, String> { pub fn read_from_disk(dev: &BlkDev) -> Result<Self, String> {
let part_list = get_dev_part_blocking(&dev.name)?; let part_list = get_dev_part_blocking(&dev.name)?;
let parts_size = part_list.iter().fold(0, |acc, part| acc + part.size); let parts_size = part_list.iter().fold(KiraSize::new(0), |acc, part| acc + part.size);
Ok(Self { Ok(Self {
dev: dev.clone(), dev: dev.clone(),
empty_space: dev.size - parts_size, empty_space: dev.size - parts_size,
@@ -318,45 +332,86 @@ impl PartLayout {
pub fn add_part( pub fn add_part(
mut self, mut self,
part_size: u64, part_size: KiraSize,
fs_type: FSType, fs_type: FSType,
gpt_label: Option<String>, gpt_label: Option<String>,
fs_label: Option<String>, fs_label: Option<String>,
mount_point: Option<String>, mount_point: Option<String>,
role: Option<PartRole>,
) -> Self { ) -> Self {
let part_start = if self.part_list.is_empty() { let part_start = if self.part_list.is_empty() {
2u64 * 1024u64 * 1024u64 KiraSize::new_mb(2)
} else { } else {
self.dev.size.checked_sub(self.empty_space).unwrap() self.dev.size - self.empty_space
}; };
let (size, start, _) = let (size, start, _) =
align_part(part_size, part_start, self.dev.sector_size as u64).unwrap(); align_part(part_size.b(), part_start.b(), self.dev.sector_size.b()).unwrap();
let part_name = format!("{}p{}", self.dev.name, self.part_list.len() + 1);
self.part_list.push(PartInfo { self.part_list.push(PartInfo {
name: "_".into(), name: part_name,
size: size, size: KiraSize::new(size),
start: start, start: KiraSize::new(start),
fs_type: fs_type, fs_type: fs_type,
gpt_label: gpt_label, gpt_label: gpt_label,
fs_label: fs_label, fs_label: fs_label,
mount_point: mount_point, mount_point: mount_point,
role: role,
}); });
self.empty_space = self.empty_space.checked_sub(size).unwrap(); self.empty_space = self.empty_space - KiraSize::new(size);
self self
} }
pub fn add_part_reserve( pub fn add_part_reserve(
self, self,
reserve_space: u64, reserve_space: KiraSize,
fs_type: FSType, fs_type: FSType,
gpt_label: Option<String>, gpt_label: Option<String>,
fs_label: Option<String>, fs_label: Option<String>,
mount_point: Option<String>, mount_point: Option<String>,
role: Option<PartRole>,
) -> Self { ) -> Self {
let p_size = self.empty_space.checked_sub(reserve_space).unwrap(); let p_size = self.empty_space - reserve_space;
self.add_part(p_size, fs_type, gpt_label, fs_label, mount_point) 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 {
let mut res: PartLayout = PartLayout::new(dev);
// UEFI partition
res = res
.add_part(
efi_size,
FSType::VFAT,
Some("efi".into()),
Some("EFI".into()),
Some("/efi".into()),
Some(PartRole::EFI),
)
.add_part_reserve(
swap_size,
FSType::XFS,
Some("root".into()),
None,
Some("/".into()),
Some(PartRole::ROOT),
);
// swap
if swap_size.b() > 0 {
res = res.add_part(
swap_size,
FSType::SWAP,
Some("swap".into()),
None,
Some("SWAP".into()),
Some(PartRole::SWAP),
);
}
res
} }
} }
@@ -412,9 +467,3 @@ mod tests {
} }
} }
// fn add_part(part_list: Vec<PartInfo>, rem_size: u64, part_t: PartType, )
// fn gen_layout(dev: &BlkDev, swap_size: u64) -> Vec<PartInfo> {
// Vec::new()
// }
+20
View File
@@ -1,3 +1,23 @@
// <Kira Installer - universal Linux installer.>
// Copyright (C) <2026> <Kira Foundation>
// 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 <https://www.gnu.org/licenses/>.
/*
Scroll List iced widget implementation
*/
use std::fmt::Display; use std::fmt::Display;
use iced::widget::{Column, button, container, scrollable, text}; use iced::widget::{Column, button, container, scrollable, text};
+143
View File
@@ -0,0 +1,143 @@
// <Kira Installer - universal Linux installer.>
// Copyright (C) <2026> <Kira Foundation>
// 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 <https://www.gnu.org/licenses/>.
/*
KiraSize struct implementation for work with base2 sizes.
*/
use std::ops::{Add, Sub};
pub fn format_bytes_size(size: u64) -> String {
let suffixs: [&str; 5] = ["KB", "MB", "GB", "TB", "PB"];
if size < 1000 {
format!("{}B", size)
} else {
let mut s = size as f64;
let mut idx = 0;
for i in 0..5 {
s = s / 1024.0;
idx = i;
if s < 1000.0 {
break;
}
}
format!("{:.2}{}", s, suffixs[idx])
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct KiraSize {
size_bytes: u64,
}
impl std::fmt::Display for KiraSize {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.size_bytes < 1000 {
write!(f, "{}B", self.size_bytes)
} else {
let mut s = self.size_bytes as f64;
let mut idx = 0;
for i in 0..5 {
s = s / 1024.0;
idx = i;
if s < 1000.0 {
break;
}
}
write!(f, "{:.2}{}", s, Self::SUFFIXS[idx])
}
}
}
impl KiraSize {
pub const SUFFIXS: [&str; 5] = ["KB", "MB", "GB", "TB", "PB"];
pub fn new(size:u64) -> Self {
Self { size_bytes: size }
}
pub fn new_kb(size:u64) -> Self {
Self { size_bytes: size * 1024 }
}
pub fn new_mb(size:u64) -> Self {
Self { size_bytes: size * 1024u64.pow(2) }
}
pub fn new_gb(size:u64) -> Self {
Self { size_bytes: size * 1024u64.pow(3) }
}
pub fn new_tb(size:u64) -> Self {
Self { size_bytes: size * 1024u64.pow(4) }
}
pub fn new_pb(size:u64) -> Self {
Self { size_bytes: size * 1024u64.pow(5) }
}
pub fn b(&self) -> u64 {
self.size_bytes
}
pub fn kb(&self) -> u64 {
self.size_bytes / 1024u64
}
pub fn mb(&self) -> u64 {
self.size_bytes / 1024u64.pow(2)
}
pub fn gb(&self) -> u64 {
self.size_bytes / 1024u64.pow(3)
}
pub fn tb(&self) -> u64 {
self.size_bytes / 1024u64.pow(4)
}
pub fn pb(&self) -> u64 {
self.size_bytes / 1024u64.pow(5)
}
pub fn from_str_bytes(s: &str) -> Option<Self> {
Some(Self::new(u64::from_str_radix(s, 10).ok()?))
}
pub fn div_c(self, other: u64) -> Self {
Self { size_bytes: self.size_bytes / other }
}
///
/// Panics if overflow accurs.
///
pub fn mul_c(self, other: u64) -> Self {
Self { size_bytes: self.size_bytes.strict_mul(other) }
}
}
impl Add for KiraSize {
type Output = KiraSize;
fn add(self, other: KiraSize) -> Self::Output {
KiraSize {
size_bytes: self.size_bytes + other.size_bytes,
}
}
}
impl Sub for KiraSize {
type Output = KiraSize;
/// Panics if overflow accors.
fn sub(self, other: KiraSize) -> Self::Output {
KiraSize {
size_bytes: self.size_bytes.strict_sub(other.size_bytes),
}
}
}
+97
View File
@@ -0,0 +1,97 @@
// <Kira Installer - universal Linux installer.>
// Copyright (C) <2026> <Kira Foundation> <Kira>
// 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 <https://www.gnu.org/licenses/>.
/*
This file contains functions to query system information.
*/
use std::collections::HashMap;
use std::fs;
///
/// vis_vram_total - size of vram in bytes
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GpuInfo {
pub id: u8,
pub name: String,
pub vis_vram_total: u64,
}
/// See /proc/meminfo output format and units (kB)
pub fn get_meminfo() -> HashMap<String, u64> {
let mem_info_str = fs::read_to_string("/proc/meminfo").unwrap();
mem_info_str
.lines()
.filter_map(|l| {
l.split_once(':').and_then(|(k, v)| {
u64::from_str_radix(v.trim_end_matches("kB").trim(), 10)
.ok()
.and_then(|v_num| Some((k.to_string(), v_num)))
})
})
.collect()
}
// cat /sys/class/drm/card1/device/mem_info_vis_vram_total
pub fn get_gpus_list() -> Vec<GpuInfo> {
let drm_devs_dirs: Vec<(String, u8)> = fs::read_dir("/sys/class/drm/")
.unwrap()
.filter_map(|maybe_entry| {
maybe_entry.ok().and_then(|entry| {
entry.file_type().ok().and_then(|ft| {
if ft.is_symlink() || ft.is_dir() {
entry.file_name().into_string().ok()
} else {
None
}
})
})
})
.filter(|f_name| f_name.len() == 5 && f_name.starts_with("card"))
.filter_map(|dir_name| {
dir_name.split_once("card").and_then(|name_touple| {
u8::from_str_radix(name_touple.1, 10)
.ok()
.and_then(|gpu_id| Some((dir_name.clone(), gpu_id)))
})
})
.collect();
let res: Vec<GpuInfo> = drm_devs_dirs
.iter()
.filter_map(|(d, id)| {
fs::read_to_string(format!(
"/sys/class/drm/{}/device/mem_info_vis_vram_total",
d
))
.ok()
.and_then(|mem_str| {
u64::from_str_radix(mem_str.trim(), 10)
.ok()
.and_then(|mem_size| {
Some(GpuInfo {
id: *id,
name: d.clone(),
vis_vram_total: mem_size,
})
})
})
})
.collect();
res
}
+2
View File
@@ -36,6 +36,8 @@ mod kira_theming;
mod kira_scroll_list; mod kira_scroll_list;
mod kira_color_bar; mod kira_color_bar;
mod kira_disk_layout; mod kira_disk_layout;
mod kira_size;
mod kira_sysinfo;
mod stage; mod stage;
mod stages; mod stages;
+91 -54
View File
@@ -21,10 +21,12 @@
use crate::stage::{StageAction, StageResult}; use crate::stage::{StageAction, StageResult};
use crate::kira_color_bar; use crate::kira_color_bar;
use crate::kira_disk_layout::{BlkDev,PartInfo, PartLayout, FSType}; use crate::kira_disk_layout::{BlkDev, FSType, PartInfo, PartLayout};
use toml::Table; use crate::kira_size::KiraSize;
use iced::{Alignment, Color, Length, widget}; use crate::kira_sysinfo;
use iced::{Alignment, Color, widget};
use rust_i18n::t; use rust_i18n::t;
use toml::Table;
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SwapMode { pub enum SwapMode {
@@ -61,13 +63,12 @@ fn part_type_to_color(t: &FSType) -> Color {
} }
} }
fn part_to_ct_params(part: &PartInfo, dev_size: u64) -> (String, u16, Color) { fn part_to_ct_params(part: &PartInfo, dev_size: KiraSize) -> (String, u16, Color) {
let fill_ratio: u16 = ((part.size as f32 / dev_size as f32) * 12.0) as u16; let fill_ratio: u16 = ((part.size.b() as f32 / dev_size.b() as f32) * 11.0) as u16;
let fill_ratio = fill_ratio.max(1); let fill_ratio = fill_ratio.max(1);
let part_color = part_type_to_color(&part.fs_type); let part_color = part_type_to_color(&part.fs_type);
(part.to_string(), fill_ratio, part_color) (part.to_string(), fill_ratio, part_color)
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct PartitionStage { pub struct PartitionStage {
@@ -77,6 +78,9 @@ pub struct PartitionStage {
use_zram: bool, use_zram: bool,
secure_boot: bool, secure_boot: bool,
selected_disk_parts: Option<Vec<(String, u16, Color)>>, selected_disk_parts: Option<Vec<(String, u16, Color)>>,
generated_disk_parts: Option<Vec<(String, u16, Color)>>,
system_ram_size: KiraSize,
vram_of_all_gpus_size: KiraSize,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -89,33 +93,7 @@ pub enum Message {
Back, Back,
} }
impl PartitionStage { impl PartitionStage {
pub fn gen_disk_layout_estimate(&self) -> PartLayout {
let dev = self.device.clone().unwrap();
let swap_size: u64 = match self.swap_mode {
Some(SwapMode::NoSwap) => 0,
Some(SwapMode::SwapHibernate) => 666*1024*1024,
Some(SwapMode::SwapNoHibernate) => 1024*1024*1024,
_ => 1024*1024*1024,
};
let mut res: PartLayout = PartLayout::new(dev);
// UEFI partition
res = res.add_part(256*1024*1024, FSType::VFAT, Some("kira-efi".into()), Some("EFI".into()), Some("/efi".into()))
.add_part(512*1024*1024, FSType::XFS, Some("kira-boot-a".into()), None, Some("/".into()))
.add_part_reserve(swap_size, FSType::XFS, Some("kira-home".into()), None, Some("/home".into()));
// swap
if swap_size > 0 {
res = res.add_part(swap_size, FSType::SWAP, Some("kira-swap".into()), None, Some("SWAP".into()));
}
res
}
pub fn new(toml_config: &Table) -> Result<Self, String> { pub fn new(toml_config: &Table) -> Result<Self, String> {
let maybe_dev_list = BlkDev::list_sys_blk_dev(); let maybe_dev_list = BlkDev::list_sys_blk_dev();
@@ -126,16 +104,28 @@ impl PartitionStage {
.and_then(|v| v.as_integer()) .and_then(|v| v.as_integer())
.unwrap_or(8192); .unwrap_or(8192);
let min_disk_size: u64 = min_disk_size_mb.try_into().unwrap_or(8192) * 1024 * 1024; let min_disk_size: KiraSize = KiraSize::new_mb(min_disk_size_mb.try_into().unwrap_or(8192));
match maybe_dev_list { match maybe_dev_list {
Ok(dev_list) => { Ok(dev_list) => {
let acepted_dev: Vec<BlkDev> = dev_list let acepted_dev: Vec<BlkDev> = dev_list
.iter() .iter()
.filter(|v| v.size >= min_disk_size) .filter(|v| v.size.b() >= min_disk_size.b())
.cloned() .cloned()
.collect(); .collect();
// getting system memory info
let system_ram_size = KiraSize::new_kb(kira_sysinfo::get_meminfo()["MemTotal"]); // from kB to bytes
let vram_of_all_gpus_size = KiraSize::new(
kira_sysinfo::get_gpus_list()
.iter()
.fold(0u64, |acc, gpi| acc + gpi.vis_vram_total),
);
println!(
"stage init ram {} vram {}",
system_ram_size, vram_of_all_gpus_size
);
Ok(Self { Ok(Self {
device: None, device: None,
devices: acepted_dev, devices: acepted_dev,
@@ -143,12 +133,43 @@ impl PartitionStage {
use_zram: true, use_zram: true,
secure_boot: false, secure_boot: false,
selected_disk_parts: None, selected_disk_parts: None,
generated_disk_parts: None,
system_ram_size: system_ram_size,
vram_of_all_gpus_size: vram_of_all_gpus_size,
}) })
} }
Err(ex) => Err(ex), Err(ex) => Err(ex),
} }
} }
fn get_swap_size(&self) -> KiraSize {
let total_ram = self.system_ram_size + self.vram_of_all_gpus_size;
println!("total_ram {}", total_ram);
let sys_ram_gb = self.system_ram_size.gb();
println!("sys_ram_gb {}", sys_ram_gb);
let disk_swap_gb = if sys_ram_gb >= 32 {
1u64
} else if sys_ram_gb >= 24 {
2u64
} else if sys_ram_gb >= 16 {
sys_ram_gb / 2
} else if sys_ram_gb >= 8 {
sys_ram_gb
} else {
sys_ram_gb * 2
};
println!("disk_swap_gb {}", disk_swap_gb);
let disk_swap = KiraSize::new_gb(disk_swap_gb);
println!("disk_swap {}", disk_swap);
match self.swap_mode {
Some(SwapMode::NoSwap) => KiraSize::new(0),
Some(SwapMode::SwapHibernate) => disk_swap + total_ram,
Some(SwapMode::SwapNoHibernate) => disk_swap,
_ => KiraSize::new_gb(2),
}
}
fn gen_result(&self) -> StageResult { fn gen_result(&self) -> StageResult {
StageResult::new("partition") StageResult::new("partition")
.add_val_string( .add_val_string(
@@ -174,7 +195,8 @@ impl PartitionStage {
Message::SelectDevice(dev) => { Message::SelectDevice(dev) => {
self.selected_disk_parts = match PartLayout::read_from_disk(&dev) { self.selected_disk_parts = match PartLayout::read_from_disk(&dev) {
Ok(dev_parts) => Some( Ok(dev_parts) => Some(
dev_parts.part_list dev_parts
.part_list
.iter() .iter()
.map(|part_inf| part_to_ct_params(&part_inf, dev.size)) .map(|part_inf| part_to_ct_params(&part_inf, dev.size))
.collect(), .collect(),
@@ -185,11 +207,38 @@ impl PartitionStage {
} }
}; };
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
.iter()
.map(|part_info| part_to_ct_params(part_info, dev.size))
.collect(),
);
self.device = Some(dev); self.device = Some(dev);
StageAction::None StageAction::None
} }
Message::SelectSwapMode(sm) => { Message::SelectSwapMode(sm) => {
self.swap_mode = Some(sm); self.swap_mode = Some(sm);
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
.iter()
.map(|part_info| part_to_ct_params(part_info, dev.size))
.collect(),
);
}
StageAction::None StageAction::None
} }
Message::ToggleSecureBoot(t) => { Message::ToggleSecureBoot(t) => {
@@ -206,23 +255,11 @@ impl PartitionStage {
} }
pub fn view(&self) -> iced::Element<'_, Message> { pub fn view(&self) -> iced::Element<'_, Message> {
let dev_parts_es: Option<Vec<(String, u16, Color)>> = if self.selected_disk_parts.is_some() let dev_parts_text = match self.generated_disk_parts {
{
let p_l = self.gen_disk_layout_estimate();
Some(
p_l.part_list.iter()
.map(|part_info| part_to_ct_params(part_info, p_l.dev.size))
.collect()
)
} else {
None
};
let dev_parts_text = match dev_parts_es {
Some(_) => widget::text(t!("partition.current_after_install")), Some(_) => widget::text(t!("partition.current_after_install")),
None => widget::text(""), None => widget::text(""),
}; };
let dev_parts_content = kira_color_bar::color_bar(dev_parts_es, 48); let dev_parts_content = kira_color_bar::color_bar(self.generated_disk_parts.clone(), 56);
let dev_parts_content = widget::column![dev_parts_text, dev_parts_content]; let dev_parts_content = widget::column![dev_parts_text, dev_parts_content];
let back_button = widget::button(widget::text(t!("button.back"))).on_press(Message::Back); let back_button = widget::button(widget::text(t!("button.back"))).on_press(Message::Back);
@@ -232,7 +269,7 @@ impl PartitionStage {
Some(_) => widget::text(t!("partition.current_dev_layout")), Some(_) => widget::text(t!("partition.current_dev_layout")),
None => widget::text(""), None => widget::text(""),
}; };
let selected_dev_content = kira_color_bar::color_bar(self.selected_disk_parts.clone(), 48); let selected_dev_content = kira_color_bar::color_bar(self.selected_disk_parts.clone(), 56);
let selected_dev_content = widget::column![selected_dev_text, selected_dev_content]; let selected_dev_content = widget::column![selected_dev_text, selected_dev_content];
widget::column![ widget::column![