Skip to content

Commit 93d0806

Browse files
committed
refactor: many new modules
1 parent a078ea5 commit 93d0806

File tree

8 files changed

+98
-93
lines changed

8 files changed

+98
-93
lines changed

src/app/config.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use super::connection::Connection;
2+
use serde::Deserialize;
3+
use std::{io::Read, path::PathBuf};
4+
5+
#[derive(Clone, Debug, Deserialize)]
6+
struct ConfigFile {
7+
connection: Vec<Connection>,
8+
}
9+
10+
pub fn read_config() -> Vec<Connection> {
11+
let home = std::env::var("HOME").unwrap();
12+
13+
// Full path to the toml config file.
14+
let toml_path = PathBuf::from(format!("{home}/.config/lanturn/config.toml"));
15+
16+
let mut f = std::fs::File::open(&toml_path).unwrap();
17+
18+
let mut buf = String::new();
19+
f.read_to_string(&mut buf)
20+
.expect("Failed to read contents of TOML config file.");
21+
22+
let c: ConfigFile = toml::from_str(&buf).unwrap();
23+
24+
c.connection
25+
}

src/app/connection/conn_type.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use serde::Deserialize;
2+
3+
#[derive(Clone, Debug, Deserialize)]
4+
pub enum ConnectionType {
5+
Remote { url: String },
6+
Local { ip: std::net::IpAddr },
7+
}
8+
9+
impl Default for ConnectionType {
10+
fn default() -> Self {
11+
Self::Local {
12+
ip: std::net::Ipv4Addr::LOCALHOST.into(),
13+
}
14+
}
15+
}
Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
use serde::{Deserialize, Deserializer};
2-
use std::borrow::Cow;
3-
use std::collections::VecDeque;
2+
use std::{borrow::Cow, collections::VecDeque};
43

54
pub const MAX_STATUSES: usize = 50;
65

6+
mod conn_type;
7+
8+
pub use conn_type::ConnectionType;
9+
710
#[derive(Clone, Debug, Deserialize)]
811
pub struct Connection {
912
pub name: String,
@@ -16,36 +19,8 @@ pub struct Connection {
1619
log: VecDeque<Result<u16, ()>>,
1720
}
1821

19-
pub(super) fn deserialize_conn<'de, D>(deserializer: D) -> Result<ConnectionType, D::Error>
20-
where
21-
D: Deserializer<'de>,
22-
{
23-
let buf = Cow::<'de, str>::deserialize(deserializer)?;
24-
25-
Ok(buf.parse().map_or_else(
26-
|_| ConnectionType::Web {
27-
url: buf.to_string(),
28-
},
29-
|ip| ConnectionType::Local { ip },
30-
))
31-
}
32-
33-
#[derive(Clone, Debug, Deserialize)]
34-
pub enum ConnectionType {
35-
Web { url: String },
36-
Local { ip: std::net::IpAddr },
37-
}
38-
39-
impl Default for ConnectionType {
40-
fn default() -> Self {
41-
Self::Local {
42-
ip: std::net::Ipv4Addr::LOCALHOST.into(),
43-
}
44-
}
45-
}
46-
4722
impl Connection {
48-
pub fn push_status_code(&mut self, code: Result<u16, ()>) {
23+
pub fn push_status(&mut self, code: Result<u16, ()>) {
4924
if self.log.len() == MAX_STATUSES {
5025
self.log.pop_back();
5126
}
@@ -57,10 +32,25 @@ impl Connection {
5732
&self.log
5833
}
5934

35+
/// Returns the effective address.
6036
pub fn addr(&self) -> Cow<'_, str> {
6137
match &self.conn_type {
62-
ConnectionType::Web { url } => Cow::Borrowed(url),
38+
ConnectionType::Remote { url } => Cow::Borrowed(url),
6339
ConnectionType::Local { ip } => Cow::Owned(ip.to_string()),
6440
}
6541
}
6642
}
43+
44+
fn deserialize_conn<'de, D>(deserializer: D) -> Result<ConnectionType, D::Error>
45+
where
46+
D: Deserializer<'de>,
47+
{
48+
let buf = Cow::<'de, str>::deserialize(deserializer)?;
49+
50+
Ok(buf.parse().map_or_else(
51+
|_| ConnectionType::Remote {
52+
url: buf.to_string(),
53+
},
54+
|ip| ConnectionType::Local { ip },
55+
))
56+
}

src/app/mod.rs

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
use self::{
22
cli::generate_matches, connection::Connection, output_fmt::OutputFmt, selected_tab::SelectedTab,
33
};
4-
use serde::Deserialize;
5-
use std::{
6-
io::Read,
7-
path::PathBuf,
8-
sync::{Arc, Mutex},
9-
};
4+
use std::sync::{Arc, Mutex};
105

116
pub mod cli;
7+
mod config;
128
pub mod connection;
139
pub mod output_fmt;
1410
pub mod selected_tab;
@@ -22,16 +18,11 @@ pub struct App {
2218
is_closing: bool,
2319
}
2420

25-
#[derive(Clone, Debug, Deserialize)]
26-
struct ConfigFile {
27-
connection: Vec<Connection>,
28-
}
29-
3021
impl App {
3122
pub fn generate() -> Self {
3223
let matches: clap::ArgMatches = generate_matches();
3324

34-
let conns = Self::read_config();
25+
let conns = config::read_config();
3526

3627
let output_fmt = match matches.get_one::<OutputFmt>("output_fmt") {
3728
Some(&fmt) => fmt,
@@ -45,23 +36,6 @@ impl App {
4536
}
4637
}
4738

48-
fn read_config() -> Vec<Connection> {
49-
let home = std::env::var("HOME").unwrap();
50-
51-
// Full path to the toml config file.
52-
let toml_path = PathBuf::from(format!("{home}/.config/lanturn/config.toml"));
53-
54-
let mut f = std::fs::File::open(&toml_path).unwrap();
55-
56-
let mut buf = String::new();
57-
f.read_to_string(&mut buf)
58-
.expect("Failed to read contents of TOML config file.");
59-
60-
let c: ConfigFile = toml::from_str(&buf).unwrap();
61-
62-
c.connection
63-
}
64-
6539
pub fn next_tab(&mut self) {
6640
self.selected_tab = self.selected_tab.next();
6741
}

src/app/output_fmt.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
use clap::builder::PossibleValue;
2-
use clap::ValueEnum;
1+
use clap::{ValueEnum, builder::PossibleValue};
32

43
#[derive(Default, Copy, Clone)]
54
pub enum OutputFmt {
@@ -8,6 +7,7 @@ pub enum OutputFmt {
87
Bullet,
98
}
109

10+
// Define CLI controls.
1111
impl ValueEnum for OutputFmt {
1212
fn value_variants<'a>() -> &'a [Self] {
1313
&[Self::Bullet, Self::Line]

src/main.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@ fn main() -> io::Result<()> {
3838
// Create app and run it.
3939
let ui_refresh_rate = Duration::from_millis(200);
4040

41-
let res = commence_application(&mut terminal, ui_refresh_rate, &mut app);
41+
let res = start_app(&mut terminal, ui_refresh_rate, &mut app);
4242

43-
// Restore terminal.
43+
// App is quitting!
44+
// Restore terminal and environment to normal.
4445
disable_raw_mode()?;
4546
execute!(
4647
terminal.backend_mut(),
@@ -56,7 +57,7 @@ fn main() -> io::Result<()> {
5657
Ok(())
5758
}
5859

59-
fn commence_application<B: Backend>(
60+
fn start_app<B: Backend>(
6061
terminal: &mut Terminal<B>,
6162
ui_refresh_rate: Duration,
6263
app: &mut App,
@@ -100,6 +101,7 @@ fn commence_application<B: Backend>(
100101
}
101102
}
102103

104+
/// Handles user input.
103105
fn handle_events(app: &mut App) -> io::Result<()> {
104106
if let Event::Key(key) = event::read()? {
105107
match key.code {
@@ -123,7 +125,7 @@ fn test_conn(conns: &Arc<Mutex<Vec<Connection>>>, idx: usize) {
123125
let conn_type = conns.lock().unwrap().get(idx).unwrap().conn_type.clone();
124126

125127
let code = match conn_type {
126-
ConnectionType::Web { url } => {
128+
ConnectionType::Remote { url } => {
127129
let client = reqwest::blocking::Client::new()
128130
.get(url)
129131
.timeout(Duration::from_secs(3));
@@ -145,5 +147,5 @@ fn test_conn(conns: &Arc<Mutex<Vec<Connection>>>, idx: usize) {
145147
.unwrap()
146148
.get_mut(idx)
147149
.unwrap()
148-
.push_status_code(code);
150+
.push_status(code);
149151
}

src/ui/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use crate::app::{App, selected_tab::SelectedTab};
2+
use ratatui::{Frame, layout::Rect, widgets::Tabs};
3+
use strum::IntoEnumIterator;
4+
5+
mod tab;
6+
7+
pub fn ui(f: &mut Frame, app: &App) {
8+
let titles = SelectedTab::iter().map(SelectedTab::title);
9+
10+
let tabs = Tabs::new(titles).select(app.selected_tab as usize);
11+
12+
f.render_widget(tabs, Rect::new(0, 0, f.area().width, f.area().height));
13+
14+
match app.selected_tab {
15+
SelectedTab::Live => tab::render_tab_live(f, app),
16+
SelectedTab::Log => tab::render_tab_log(f, app),
17+
}
18+
}

src/ui.rs renamed to src/ui/tab.rs

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,13 @@
1-
use crate::app::{
2-
App, connection::ConnectionType, output_fmt::OutputFmt, selected_tab::SelectedTab,
3-
};
1+
use crate::app::{App, connection::ConnectionType, output_fmt::OutputFmt};
42
use ratatui::{
53
Frame,
64
layout::Rect,
75
style::{Color, Modifier, Style, Stylize},
86
text::{Line, Span},
9-
widgets::{Block, List, Paragraph, Tabs},
7+
widgets::{Block, List, Paragraph},
108
};
11-
use strum::IntoEnumIterator;
12-
13-
pub fn ui(f: &mut Frame, app: &App) {
14-
// Render tabs at the top.
15-
16-
let titles = SelectedTab::iter().map(SelectedTab::title);
17-
18-
let tabs = Tabs::new(titles).select(app.selected_tab as usize);
19-
20-
f.render_widget(tabs, Rect::new(0, 0, f.area().width, f.area().height));
21-
22-
// Render contents of selected tab.
23-
match app.selected_tab {
24-
SelectedTab::Live => render_tab_live(f, app),
25-
SelectedTab::Log => render_tab_log(f, app),
26-
}
27-
}
289

29-
fn render_tab_live(f: &mut Frame, app: &App) {
10+
pub fn render_tab_live(f: &mut Frame, app: &App) {
3011
let mut list_items: Vec<Line<'_>> = Vec::new();
3112

3213
for conn in app.connections.lock().unwrap().iter() {
@@ -39,7 +20,7 @@ fn render_tab_live(f: &mut Frame, app: &App) {
3920

4021
let conn_output: Line<'_> = match app.output_fmt {
4122
OutputFmt::Bullet => Line::from(vec![
42-
Span::from(" ").style(color),
23+
Span::from(" 󰝤 ").style(color),
4324
Span::from(format!("{} ({})", conn.name, url)),
4425
]),
4526
OutputFmt::Line => Line::from(Span::from(format!(" {} ({})", conn.name, url))).style(
@@ -66,7 +47,7 @@ fn render_tab_live(f: &mut Frame, app: &App) {
6647
);
6748
}
6849

69-
fn render_tab_log(f: &mut Frame, app: &App) {
50+
pub fn render_tab_log(f: &mut Frame, app: &App) {
7051
let (idx, conn) = app.log_conn();
7152

7253
let block =
@@ -115,7 +96,7 @@ const fn status_to_color(status: Result<u16, ()>, conn_type: &ConnectionType) ->
11596
};
11697

11798
match conn_type {
118-
ConnectionType::Web { .. } => match code {
99+
ConnectionType::Remote { .. } => match code {
119100
200 => Color::Green,
120101
_ => Color::Yellow,
121102
},

0 commit comments

Comments
 (0)