Cleaned up imports a bit and added rustfmt.toml

This commit is contained in:
2023-08-08 10:50:04 -06:00
parent 0d4e283c21
commit 155675b596
6 changed files with 182 additions and 179 deletions
+10
View File
@@ -0,0 +1,10 @@
tab_spaces=2
edition = "2021"
reorder_imports = true
imports_granularity = "Crate"
group_imports = "StdExternalCrate"
reorder_modules = true
merge_derives = true
use_field_init_shorthand = true
format_macro_matchers = true
format_macro_bodies = true
+57 -61
View File
@@ -7,93 +7,89 @@ use crate::app::radarr::RadarrData;
use super::network::RadarrEvent;
pub mod radarr;
pub(crate) mod key_binding;
pub mod radarr;
#[derive(Debug)]
pub struct App {
network_tx: Option<Sender<RadarrEvent>>,
pub client: Client,
pub title: &'static str,
pub tick_until_poll: u64,
pub tick_count: u64,
pub config: AppConfig,
pub data: Data,
network_tx: Option<Sender<RadarrEvent>>,
pub client: Client,
pub title: &'static str,
pub tick_until_poll: u64,
pub tick_count: u64,
pub config: AppConfig,
pub data: Data,
}
impl App {
pub fn new(
network_tx: Sender<RadarrEvent>,
tick_until_poll: u64,
config: AppConfig
) -> Self {
App {
network_tx: Some(network_tx),
tick_until_poll,
config,
..App::default()
}
pub fn new(network_tx: Sender<RadarrEvent>, tick_until_poll: u64, config: AppConfig) -> Self {
App {
network_tx: Some(network_tx),
tick_until_poll,
config,
..App::default()
}
}
pub async fn dispatch(&mut self, action: RadarrEvent) {
if let Some(network_tx) = &self.network_tx {
if let Err(e) = network_tx.send(action).await {
error!("Failed to send event. {:?}", e);
}
}
}
pub fn reset(&mut self) {
self.tick_count = 0;
// self.data = Data::default();
}
pub async fn on_tick(&mut self) {
if self.tick_count % self.tick_until_poll == 0 {
self.dispatch(RadarrEvent::GetOverview).await;
}
pub async fn dispatch(&mut self, action: RadarrEvent) {
if let Some(network_tx) = &self.network_tx {
if let Err(e) = network_tx.send(action).await {
error!("Failed to send event. {:?}", e);
}
}
}
pub fn reset(&mut self) {
self.tick_count = 0;
// self.data = Data::default();
}
pub async fn on_tick(&mut self) {
if self.tick_count % self.tick_until_poll == 0 {
self.dispatch(RadarrEvent::GetOverview).await;
}
self.tick_count += 1;
}
self.tick_count += 1;
}
}
impl Default for App {
fn default() -> Self {
App {
network_tx: None,
client: Client::new(),
title: "DevTools",
tick_until_poll: 0,
tick_count: 0,
config: AppConfig::default(),
data: Data::default()
}
fn default() -> Self {
App {
network_tx: None,
client: Client::new(),
title: "DevTools",
tick_until_poll: 0,
tick_count: 0,
config: AppConfig::default(),
data: Data::default(),
}
}
}
#[derive(Default, Debug)]
pub struct Data {
pub radarr_data: RadarrData,
pub radarr_data: RadarrData,
}
#[derive(Debug, Deserialize, Serialize, Default)]
pub struct AppConfig {
pub radarr: RadarrConfig,
pub radarr: RadarrConfig,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct RadarrConfig {
pub host: String,
pub port: Option<u16>,
pub api_token: String
pub host: String,
pub port: Option<u16>,
pub api_token: String,
}
impl Default for RadarrConfig {
fn default() -> Self {
RadarrConfig {
host: "localhost".to_string(),
port: Some(7878),
api_token: "".to_string()
}
fn default() -> Self {
RadarrConfig {
host: "localhost".to_string(),
port: Some(7878),
api_token: "".to_string(),
}
}
}
}
+32 -31
View File
@@ -9,44 +9,45 @@ use crossterm::event::Event as CrosstermEvent;
use crate::event::Key;
pub enum InputEvent<T> {
KeyEvent(T),
Tick
KeyEvent(T),
Tick,
}
pub struct Events {
_tx: Sender<InputEvent<Key>>,
rx: Receiver<InputEvent<Key>>
_tx: Sender<InputEvent<Key>>,
rx: Receiver<InputEvent<Key>>,
}
impl Events {
pub fn new() -> Self {
let (tx, rx) = mpsc::channel();
let tick_rate: Duration = Duration::from_millis(250);
pub fn new() -> Self {
let (tx, rx) = mpsc::channel();
let tick_rate: Duration = Duration::from_millis(250);
let event_tx = tx.clone();
thread::spawn(move || {
let mut last_tick = Instant::now();
loop {
let timeout = tick_rate.checked_sub(last_tick.elapsed())
.unwrap_or_else(|| Duration::from_secs(0));
if event::poll(timeout).unwrap() {
if let CrosstermEvent::Key(key) = event::read().unwrap() {
let key = Key::from(key);
event_tx.send(InputEvent::KeyEvent(key)).unwrap();
}
}
let event_tx = tx.clone();
thread::spawn(move || {
let mut last_tick = Instant::now();
loop {
let timeout = tick_rate
.checked_sub(last_tick.elapsed())
.unwrap_or_else(|| Duration::from_secs(0));
if event::poll(timeout).unwrap() {
if let CrosstermEvent::Key(key) = event::read().unwrap() {
let key = Key::from(key);
event_tx.send(InputEvent::KeyEvent(key)).unwrap();
}
}
if last_tick.elapsed() >= tick_rate {
event_tx.send(InputEvent::Tick).unwrap();
last_tick = Instant::now();
}
}
});
if last_tick.elapsed() >= tick_rate {
event_tx.send(InputEvent::Tick).unwrap();
last_tick = Instant::now();
}
}
});
Events { _tx: tx, rx }
}
Events { _tx: tx, rx }
}
pub fn next(&self) -> Result<InputEvent<Key>, mpsc::RecvError> {
self.rx.recv()
}
}
pub fn next(&self) -> Result<InputEvent<Key>, mpsc::RecvError> {
self.rx.recv()
}
}
+29 -26
View File
@@ -5,44 +5,47 @@ use crossterm::event::{KeyCode, KeyEvent};
#[derive(Debug, PartialEq, Eq)]
pub enum Key {
Char(char),
Unknown
Char(char),
Unknown,
}
impl Display for Key {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match *self {
Key::Char(c) => write!(f, "<{}>", c),
_ => write!(f, "<{:?}>", self)
}
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match *self {
Key::Char(c) => write!(f, "<{}>", c),
_ => write!(f, "<{:?}>", self),
}
}
}
impl From<KeyEvent> for Key {
fn from(key_event: KeyEvent) -> Self {
match key_event {
KeyEvent {
code: KeyCode::Char(c),
..
} => Key::Char(c),
_ => Key::Unknown
}
fn from(key_event: KeyEvent) -> Self {
match key_event {
KeyEvent {
code: KeyCode::Char(c),
..
} => Key::Char(c),
_ => Key::Unknown,
}
}
}
#[cfg(test)]
mod tests {
use crossterm::event::{KeyCode, KeyEvent};
use crossterm::event::{KeyCode, KeyEvent};
use crate::event::key::Key;
use crate::event::key::Key;
#[test]
fn test_key_formatter() {
assert_eq!(format!("{}", Key::Char('q')), "<q>");
}
#[test]
fn test_key_formatter() {
assert_eq!(format!("{}", Key::Char('q')), "<q>");
}
#[test]
fn test_key_from() {
assert_eq!(Key::from(KeyEvent::from(KeyCode::Char('q'))), Key::Char('q'))
}
}
#[test]
fn test_key_from() {
assert_eq!(
Key::from(KeyEvent::from(KeyCode::Char('q'))),
Key::Char('q')
)
}
}
+46 -53
View File
@@ -1,16 +1,17 @@
use std::io;
use std::sync::Arc;
use std::time::{Duration, Instant};
use anyhow::Result;
use clap::Parser;
use crossterm::execute;
use crossterm::terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen};
use crossterm::terminal::{
disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen,
};
use log::{debug, info};
use tokio::sync::{mpsc, Mutex};
use tokio::sync::mpsc::Receiver;
use tui::Terminal;
use tokio::sync::{mpsc, Mutex};
use tui::backend::CrosstermBackend;
use tui::Terminal;
use utils::init_logging_config;
@@ -29,78 +30,70 @@ mod utils;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
}
struct Cli {}
#[tokio::main]
async fn main() -> Result<()> {
log4rs::init_config(init_logging_config())?;
Cli::parse();
log4rs::init_config(init_logging_config())?;
Cli::parse();
let config = confy::load("managarr", "config")?;
let (sync_network_tx, sync_network_rx) = mpsc::channel(500);
let config = confy::load("managarr", "config")?;
let (sync_network_tx, sync_network_rx) = mpsc::channel(500);
let app = Arc::new(Mutex::new(App::new(
sync_network_tx,
5000 / 250,
config
)));
let app = Arc::new(Mutex::new(App::new(sync_network_tx, 5000 / 250, config)));
let app_nw = Arc::clone(&app);
let app_nw = Arc::clone(&app);
std::thread::spawn(move || start_networking(sync_network_rx, &app_nw));
std::thread::spawn(move || start_networking(sync_network_rx, &app_nw));
info!("Checking if Radarr server is up and running...");
app.lock().await.dispatch(RadarrEvent::HealthCheck).await;
info!("Checking if Radarr server is up and running...");
app.lock().await.dispatch(RadarrEvent::HealthCheck).await;
simple_ui(&app).await?;
simple_ui(&app).await?;
Ok(())
Ok(())
}
#[tokio::main]
async fn start_networking(mut network_rx: Receiver<RadarrEvent>, app: &Arc<Mutex<App>>) {
let network = Network::new(reqwest::Client::new(), app);
let network = Network::new(reqwest::Client::new(), app);
while let Some(network_event) = network_rx.recv().await {
debug!("Received network event: {:?}", network_event);
network.handle_radarr_event(network_event).await;
}
while let Some(network_event) = network_rx.recv().await {
debug!("Received network event: {:?}", network_event);
network.handle_radarr_event(network_event).await;
}
}
async fn simple_ui(app: &Arc<Mutex<App>>) -> Result<()> {
let mut stdout = io::stdout();
enable_raw_mode()?;
let mut stdout = io::stdout();
enable_raw_mode()?;
execute!(stdout, EnterAlternateScreen)?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
terminal.clear()?;
terminal.hide_cursor()?;
execute!(stdout, EnterAlternateScreen)?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
terminal.clear()?;
terminal.hide_cursor()?;
let input_events = Events::new();
let input_events = Events::new();
loop {
let mut app = app.lock().await;
terminal.draw(|f| ui(f, &app))?;
loop {
let mut app = app.lock().await;
terminal.draw(|f| ui(f, &app))?;
match input_events.next()? {
InputEvent::KeyEvent(key) => {
if key == Key::Char('q') {
break;
}
}
InputEvent::Tick => {
app.on_tick().await
}
match input_events.next()? {
InputEvent::KeyEvent(key) => {
if key == Key::Char('q') {
break;
}
}
InputEvent::Tick => app.on_tick().await,
}
}
terminal.show_cursor()?;
disable_raw_mode()?;
execute!(terminal.backend_mut(), LeaveAlternateScreen)?;
terminal.show_cursor()?;
terminal.show_cursor()?;
disable_raw_mode()?;
execute!(terminal.backend_mut(), LeaveAlternateScreen)?;
terminal.show_cursor()?;
Ok(())
}
Ok(())
}
+8 -8
View File
@@ -9,18 +9,18 @@ pub(crate) mod radarr;
#[derive(Debug, Eq, PartialEq, Hash)]
pub enum RadarrEvent {
HealthCheck,
GetOverview
HealthCheck,
GetOverview,
}
pub struct Network<'a> {
pub client: Client,
pub client: Client,
pub app: &'a Arc<Mutex<App>>
pub app: &'a Arc<Mutex<App>>,
}
impl<'a> Network<'a> {
pub fn new(client: Client, app: &'a Arc<Mutex<App>>) -> Self {
Network { client, app }
}
}
pub fn new(client: Client, app: &'a Arc<Mutex<App>>) -> Self {
Network { client, app }
}
}