1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
mod app;
mod gentoo;
mod screens;
mod signal;
mod theme;
mod widgets;
use std::{
io::{self, Stdout, stdout},
panic::{set_hook, take_hook},
};
use ratatui::{
Terminal,
crossterm::{
execute,
terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode},
},
prelude::CrosstermBackend,
};
use crate::{
app::App,
gentoo::{Portage, portage_loader},
};
struct TuiGuard;
impl Drop for TuiGuard {
fn drop(&mut self) {
_ = restore_tui();
}
}
fn main() -> color_eyre::Result<()> {
color_eyre::install()?;
let _guard = TuiGuard;
let tui = init_tui()?;
let mut p = Portage::new();
p.world_packages = portage_loader::load_world_packages()?;
p.installed_packages = portage_loader::load_installed_packages()?;
// p.available_packages = portage_loader::load_available_packages()?;
let mut app = App::new(p);
run(tui, &mut app)?;
Ok(())
}
fn run(mut terminal: Terminal<CrosstermBackend<Stdout>>, app: &mut App) -> color_eyre::Result<()> {
loop {
terminal.draw(|frame| app.draw(frame))?;
let should_exit = app.update()?;
if should_exit {
break;
}
}
Ok(())
}
fn init_tui() -> io::Result<ratatui::Terminal<CrosstermBackend<Stdout>>> {
execute!(stdout(), EnterAlternateScreen)?;
enable_raw_mode()?;
init_panic_hook();
Terminal::new(CrosstermBackend::new(stdout()))
}
fn init_panic_hook() {
let original_hook = take_hook();
set_hook(Box::new(move |panic_info| {
let _ = restore_tui();
original_hook(panic_info);
}));
}
fn restore_tui() -> io::Result<()> {
disable_raw_mode()?;
execute!(stdout(), LeaveAlternateScreen)?;
Ok(())
}
|