Skip to main content

ferrix_app/pages/
kernel.rs

1/* kernel.rs
2 *
3 * Copyright 2025-2026 Michail Krasnov <mskrasnov07@ya.ru>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: GPL-3.0-or-later
19 */
20
21//! Kernel page
22
23use crate::{
24    Message, fl,
25    load_state::DataLoadingState,
26    widgets::table::{InfoRow, fmt_val, hdr_name, kv_info_table, text_fmt_val},
27};
28use ferrix_lib::sys::{KModules, Kernel, Module};
29
30use iced::{
31    Length,
32    widget::{Id, center, container, scrollable, table, text},
33};
34
35pub fn kernel_page<'a>(
36    kernel_data: &'a DataLoadingState<Kernel>,
37) -> container::Container<'a, Message> {
38    match kernel_data {
39        DataLoadingState::Loaded(kern) => {
40            let rows = vec![
41                InfoRow::new(fl!("kernel-summary"), kern.uname.clone()),
42                InfoRow::new(fl!("kernel-cmdline"), kern.cmdline.clone()),
43                InfoRow::new(fl!("kernel-arch"), kern.arch.clone()),
44                InfoRow::new(fl!("kernel-version"), kern.version.clone()),
45                InfoRow::new(fl!("kernel-build"), kern.build_info.clone()),
46                InfoRow::new(fl!("kernel-pid-max"), fmt_val(Some(kern.pid_max))),
47                InfoRow::new(fl!("kernel-threads-max"), fmt_val(Some(kern.threads_max))),
48                InfoRow::new(fl!("kernel-user-evs"), fmt_val(kern.user_events_max)),
49                InfoRow::new(fl!("kernel-avail-enthropy"), fmt_val(kern.enthropy_avail)),
50            ];
51
52            container(
53                scrollable(container(kv_info_table(rows)).style(container::rounded_box))
54                    .spacing(5)
55                    .id(Id::new(super::Page::Kernel.page_id())),
56            )
57        }
58        DataLoadingState::Error(why) => super::error_page(why),
59        DataLoadingState::Loading => super::loading_page(),
60    }
61}
62
63pub fn kmods_page<'a>(kmods: &'a DataLoadingState<KModules>) -> container::Container<'a, Message> {
64    match kmods {
65        DataLoadingState::Loaded(kmods) => {
66            if kmods.modules.is_empty() {
67                container(center(
68                    text(fl!("kernel-mods-is-empty"))
69                        .size(16)
70                        .style(text::secondary),
71                ))
72            } else {
73                let table = container(modules_table(&kmods.modules)).style(container::rounded_box);
74                container(
75                    scrollable(table)
76                        .spacing(5)
77                        .id(Id::new(super::Page::KModules.page_id())),
78                )
79            }
80        }
81        DataLoadingState::Error(why) => super::error_page(why),
82        DataLoadingState::Loading => super::loading_page(),
83    }
84}
85
86fn modules_table<'a>(rows: &'a [Module]) -> table::Table<'a, Message> {
87    let columns = [
88        table::column(hdr_name(fl!("kmod-name")), |row: &'a Module| {
89            text(&row.name).wrapping(text::Wrapping::WordOrGlyph)
90        })
91        .width(Length::FillPortion(1)),
92        table::column(hdr_name(fl!("kmod-size")), |row: &'a Module| {
93            text_fmt_val(row.size.round(2))
94        }),
95        table::column(hdr_name(fl!("kmod-instances")), |row: &'a Module| {
96            text(row.instances)
97        }),
98        table::column(hdr_name(fl!("kmod-depends")), |row: &'a Module| {
99            text(if &row.dependencies == "-" {
100                ""
101            } else {
102                &row.dependencies
103            })
104            .wrapping(text::Wrapping::WordOrGlyph)
105        })
106        .width(Length::FillPortion(3)),
107        table::column(hdr_name(fl!("kmod-state")), |row: &'a Module| {
108            text(&row.state).style(if &row.state == "Live" {
109                text::success
110            } else {
111                text::default
112            })
113        }),
114        table::column(hdr_name(fl!("kmod-addrs")), |row: &'a Module| {
115            text(&row.memory_addrs)
116        }),
117    ];
118
119    table(columns, rows).padding(2).width(Length::Fill)
120}