Skip to content

Commit e09db03

Browse files
committed
@v0.2.0
1 parent cbde781 commit e09db03

File tree

6 files changed

+284
-186
lines changed

6 files changed

+284
-186
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ json5 = "0.4.1"
2424
lazy_static = "1.4.0"
2525
libc = "0.2.148"
2626
log = "0.4.20"
27+
pnet = "0.34.0"
2728
pretty_assertions = "1.4.0"
2829
ratatui = { version = "0.24.0", features = ["serde", "macros"] }
2930
serde = { version = "1.0.188", features = ["derive"] }

src/app.rs

Lines changed: 134 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -5,148 +5,157 @@ use serde::{Deserialize, Serialize};
55
use tokio::sync::mpsc;
66

77
use crate::{
8-
action::Action,
9-
components::{home::Home, wifiscan::WifiScan, Component},
10-
config::Config,
11-
mode::Mode,
12-
tui,
8+
action::Action,
9+
components::{home::Home, interfaces::Interfaces, wifiscan::WifiScan, Component},
10+
config::Config,
11+
mode::Mode,
12+
tui,
1313
};
1414

1515
pub struct App {
16-
pub config: Config,
17-
pub tick_rate: f64,
18-
pub frame_rate: f64,
19-
pub components: Vec<Box<dyn Component>>,
20-
pub should_quit: bool,
21-
pub should_suspend: bool,
22-
pub mode: Mode,
23-
pub last_tick_key_events: Vec<KeyEvent>,
16+
pub config: Config,
17+
pub tick_rate: f64,
18+
pub frame_rate: f64,
19+
pub components: Vec<Box<dyn Component>>,
20+
pub should_quit: bool,
21+
pub should_suspend: bool,
22+
pub mode: Mode,
23+
pub last_tick_key_events: Vec<KeyEvent>,
2424
}
2525

2626
impl App {
27-
pub fn new(tick_rate: f64, frame_rate: f64) -> Result<Self> {
28-
let home = Home::new();
29-
let wifiscan = WifiScan::default();
30-
let config = Config::new()?;
31-
let mode = Mode::Home;
32-
Ok(Self {
33-
tick_rate: 1.0,
34-
// tick_rate,
35-
frame_rate,
36-
components: vec![Box::new(home), Box::new(wifiscan)],
37-
should_quit: false,
38-
should_suspend: false,
39-
config,
40-
mode,
41-
last_tick_key_events: Vec::new(),
42-
})
43-
}
44-
45-
pub async fn run(&mut self) -> Result<()> {
46-
let (action_tx, mut action_rx) = mpsc::unbounded_channel();
47-
48-
let mut tui = tui::Tui::new()?.tick_rate(self.tick_rate).frame_rate(self.frame_rate);
49-
// tui.mouse(true);
50-
tui.enter()?;
51-
52-
for component in self.components.iter_mut() {
53-
component.register_action_handler(action_tx.clone())?;
27+
pub fn new(tick_rate: f64, frame_rate: f64) -> Result<Self> {
28+
let home = Home::new();
29+
let wifiscan = WifiScan::default();
30+
let interfaces = Interfaces::default();
31+
let config = Config::new()?;
32+
let mode = Mode::Home;
33+
Ok(Self {
34+
tick_rate: 1.0,
35+
// tick_rate,
36+
frame_rate,
37+
components: vec![Box::new(home), Box::new(interfaces), Box::new(wifiscan)],
38+
should_quit: false,
39+
should_suspend: false,
40+
config,
41+
mode,
42+
last_tick_key_events: Vec::new(),
43+
})
5444
}
5545

56-
for component in self.components.iter_mut() {
57-
component.register_config_handler(self.config.clone())?;
58-
}
59-
60-
for component in self.components.iter_mut() {
61-
component.init(tui.size()?)?;
62-
}
46+
pub async fn run(&mut self) -> Result<()> {
47+
let (action_tx, mut action_rx) = mpsc::unbounded_channel();
6348

64-
loop {
65-
if let Some(e) = tui.next().await {
66-
match e {
67-
tui::Event::Quit => action_tx.send(Action::Quit)?,
68-
tui::Event::Tick => action_tx.send(Action::Tick)?,
69-
tui::Event::Render => action_tx.send(Action::Render)?,
70-
tui::Event::Resize(x, y) => action_tx.send(Action::Resize(x, y))?,
71-
tui::Event::Key(key) => {
72-
if let Some(keymap) = self.config.keybindings.get(&self.mode) {
73-
if let Some(action) = keymap.get(&vec![key]) {
74-
log::info!("Got action: {action:?}");
75-
action_tx.send(action.clone())?;
76-
} else {
77-
// If the key was not handled as a single key action,
78-
// then consider it for multi-key combinations.
79-
self.last_tick_key_events.push(key);
49+
let mut tui = tui::Tui::new()?
50+
.tick_rate(self.tick_rate)
51+
.frame_rate(self.frame_rate);
52+
// tui.mouse(true);
53+
tui.enter()?;
8054

81-
// Check for multi-key combinations
82-
if let Some(action) = keymap.get(&self.last_tick_key_events) {
83-
log::info!("Got action: {action:?}");
84-
action_tx.send(action.clone())?;
85-
}
86-
}
87-
};
88-
},
89-
_ => {},
55+
for component in self.components.iter_mut() {
56+
component.register_action_handler(action_tx.clone())?;
9057
}
58+
9159
for component in self.components.iter_mut() {
92-
if let Some(action) = component.handle_events(Some(e.clone()))? {
93-
action_tx.send(action)?;
94-
}
60+
component.register_config_handler(self.config.clone())?;
9561
}
96-
}
9762

98-
while let Ok(action) = action_rx.try_recv() {
99-
if action != Action::Tick && action != Action::Render {
100-
log::debug!("{action:?}");
63+
for component in self.components.iter_mut() {
64+
component.init(tui.size()?)?;
10165
}
102-
match action {
103-
Action::Tick => {
104-
self.last_tick_key_events.drain(..);
105-
},
106-
Action::Quit => self.should_quit = true,
107-
Action::Suspend => self.should_suspend = true,
108-
Action::Resume => self.should_suspend = false,
109-
Action::Resize(w, h) => {
110-
tui.resize(Rect::new(0, 0, w, h))?;
111-
tui.draw(|f| {
112-
for component in self.components.iter_mut() {
113-
let r = component.draw(f, f.size());
114-
if let Err(e) = r {
115-
action_tx.send(Action::Error(format!("Failed to draw: {:?}", e))).unwrap();
66+
67+
loop {
68+
if let Some(e) = tui.next().await {
69+
match e {
70+
tui::Event::Quit => action_tx.send(Action::Quit)?,
71+
tui::Event::Tick => action_tx.send(Action::Tick)?,
72+
tui::Event::Render => action_tx.send(Action::Render)?,
73+
tui::Event::Resize(x, y) => action_tx.send(Action::Resize(x, y))?,
74+
tui::Event::Key(key) => {
75+
if let Some(keymap) = self.config.keybindings.get(&self.mode) {
76+
if let Some(action) = keymap.get(&vec![key]) {
77+
log::info!("Got action: {action:?}");
78+
action_tx.send(action.clone())?;
79+
} else {
80+
// If the key was not handled as a single key action,
81+
// then consider it for multi-key combinations.
82+
self.last_tick_key_events.push(key);
83+
84+
// Check for multi-key combinations
85+
if let Some(action) = keymap.get(&self.last_tick_key_events) {
86+
log::info!("Got action: {action:?}");
87+
action_tx.send(action.clone())?;
88+
}
89+
}
90+
};
91+
}
92+
_ => {}
11693
}
117-
}
118-
})?;
119-
},
120-
Action::Render => {
121-
tui.draw(|f| {
122-
for component in self.components.iter_mut() {
123-
let r = component.draw(f, f.size());
124-
if let Err(e) = r {
125-
action_tx.send(Action::Error(format!("Failed to draw: {:?}", e))).unwrap();
94+
for component in self.components.iter_mut() {
95+
if let Some(action) = component.handle_events(Some(e.clone()))? {
96+
action_tx.send(action)?;
97+
}
12698
}
127-
}
128-
})?;
129-
},
130-
_ => {},
131-
}
132-
for component in self.components.iter_mut() {
133-
if let Some(action) = component.update(action.clone())? {
134-
action_tx.send(action)?
135-
};
99+
}
100+
101+
while let Ok(action) = action_rx.try_recv() {
102+
if action != Action::Tick && action != Action::Render {
103+
log::debug!("{action:?}");
104+
}
105+
match action {
106+
Action::Tick => {
107+
self.last_tick_key_events.drain(..);
108+
}
109+
Action::Quit => self.should_quit = true,
110+
Action::Suspend => self.should_suspend = true,
111+
Action::Resume => self.should_suspend = false,
112+
Action::Resize(w, h) => {
113+
tui.resize(Rect::new(0, 0, w, h))?;
114+
tui.draw(|f| {
115+
for component in self.components.iter_mut() {
116+
let r = component.draw(f, f.size());
117+
if let Err(e) = r {
118+
action_tx
119+
.send(Action::Error(format!("Failed to draw: {:?}", e)))
120+
.unwrap();
121+
}
122+
}
123+
})?;
124+
}
125+
Action::Render => {
126+
tui.draw(|f| {
127+
for component in self.components.iter_mut() {
128+
let r = component.draw(f, f.size());
129+
if let Err(e) = r {
130+
action_tx
131+
.send(Action::Error(format!("Failed to draw: {:?}", e)))
132+
.unwrap();
133+
}
134+
}
135+
})?;
136+
}
137+
_ => {}
138+
}
139+
for component in self.components.iter_mut() {
140+
if let Some(action) = component.update(action.clone())? {
141+
action_tx.send(action)?
142+
};
143+
}
144+
}
145+
if self.should_suspend {
146+
tui.suspend()?;
147+
action_tx.send(Action::Resume)?;
148+
tui = tui::Tui::new()?
149+
.tick_rate(self.tick_rate)
150+
.frame_rate(self.frame_rate);
151+
// tui.mouse(true);
152+
tui.enter()?;
153+
} else if self.should_quit {
154+
tui.stop()?;
155+
break;
156+
}
136157
}
137-
}
138-
if self.should_suspend {
139-
tui.suspend()?;
140-
action_tx.send(Action::Resume)?;
141-
tui = tui::Tui::new()?.tick_rate(self.tick_rate).frame_rate(self.frame_rate);
142-
// tui.mouse(true);
143-
tui.enter()?;
144-
} else if self.should_quit {
145-
tui.stop()?;
146-
break;
147-
}
158+
tui.exit()?;
159+
Ok(())
148160
}
149-
tui.exit()?;
150-
Ok(())
151-
}
152161
}

src/components.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::{
1111

1212
pub mod home;
1313
pub mod wifiscan;
14+
pub mod interfaces;
1415

1516
/// `Component` is a trait that represents a visual and interactive element of the user interface.
1617
/// Implementors of this trait can be registered with the main application loop and will be able to receive events,

src/components/home.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ impl Component for Home {
4545
}
4646

4747
fn draw(&mut self, f: &mut Frame<'_>, area: Rect) -> Result<()> {
48-
f.render_widget(Paragraph::new(" Network scanner"), area);
48+
let rect = Rect::new(0, 0, f.size().width, 1);
49+
let version: &str = env!("CARGO_PKG_VERSION");
50+
let title = format!(" Network Scanner (v{})", version);
51+
f.render_widget(Paragraph::new(title), rect);
4952
Ok(())
5053
}
5154
}

0 commit comments

Comments
 (0)