Skip to main content

flashkraft_gui/
lib.rs

1//! FlashKraft GUI Library
2//!
3//! This crate contains the Iced desktop application for FlashKraft.
4//!
5//! ## Contents
6//!
7//! | Module | What lives here |
8//! |--------|-----------------|
9//! | [`core`] | Iced app state, messages, update logic, flash runner, storage |
10//! | [`ui`] | View dispatch, per-screen views, reusable widgets |
11//! | [`utils`] | GUI-specific utilities (Bootstrap icon mapper) |
12//!
13//! ## Dependency on `flashkraft-core`
14//!
15//! All domain models, the flash pipeline, and drive-detection logic live in
16//! the `flashkraft-core` crate.  This crate re-exports the most commonly
17//! used types so callers only need to import from `flashkraft_gui`.
18
19// GUI-specific utilities (Bootstrap icon mapper uses iced types)
20#[macro_use]
21pub mod utils;
22
23pub mod core;
24pub mod ui;
25
26// ── Core re-exports ───────────────────────────────────────────────────────────
27
28// Re-export `flashkraft_core::domain` at the crate root so that submodules can
29// use `crate::domain::DriveInfo` / `crate::domain::ImageInfo` etc.
30pub use flashkraft_core::domain;
31
32// Re-export the `flash_debug!` macro from flashkraft_core so that
33// `use crate::flash_debug;` in flash_runner.rs resolves correctly.
34pub use flashkraft_core::debug_log;
35pub use flashkraft_core::flash_debug;
36pub use flashkraft_core::status_log;
37
38// Re-export Iced app entry points
39pub use core::{FlashKraft, Message};
40
41// ── GUI entry point ───────────────────────────────────────────────────────────
42
43/// Entry point for the Iced desktop GUI.
44///
45/// The binary must be installed **setuid-root** for the flash pipeline to be
46/// able to open block devices:
47///
48/// ```text
49/// sudo chown root:root /usr/bin/flashkraft
50/// sudo chmod u+s       /usr/bin/flashkraft
51/// ```
52///
53/// The real UID is captured in `main.rs` before this function is called.
54pub fn run_gui() -> iced::Result {
55    use iced::{Settings, Task};
56
57    iced::application(
58        || {
59            let initial_state = FlashKraft::new();
60            let initial_command = Task::perform(
61                flashkraft_core::commands::load_drives(),
62                Message::DrivesRefreshed,
63            );
64            (initial_state, initial_command)
65        },
66        FlashKraft::update,
67        FlashKraft::view,
68    )
69    .title("FlashKraft - OS Image Writer")
70    .subscription(FlashKraft::subscription)
71    .theme(|state: &FlashKraft| state.theme.clone())
72    .settings(Settings {
73        fonts: vec![iced_fonts::BOOTSTRAP_FONT_BYTES.into()],
74        ..Default::default()
75    })
76    .window(iced::window::Settings {
77        size: iced::Size::new(1300.0, 700.0),
78        resizable: false,
79        decorations: true,
80        ..Default::default()
81    })
82    .run()
83}
84
85// Re-export domain types from core so downstream code can do
86// `use flashkraft_gui::{DriveInfo, ImageInfo}` without knowing about
87// flashkraft-core directly.
88pub use flashkraft_core::{DriveInfo, ImageInfo};