#![recursion_limit = "1024"]
use std::io;
#[path = "../custom/mod.rs"]
pub mod custom;
use self::custom::app::{set_main_view, App, DashViewMain};
use self::custom::ui::draw_dashboard;
#[macro_use]
extern crate log;
extern crate env_logger;
#[path = "../mod.rs"]
pub mod shared;
use shared::event::{Event, Events};
use termion::{event::Key, input::MouseTerminal, raw::IntoRawMode, screen::AlternateScreen};
use tui::{
backend::TermionBackend,
Terminal,
};
use std::{
time::{Duration, SystemTime, UNIX_EPOCH},
};
use chrono::Utc;
use futures::{
future::FutureExt, pin_mut,
select,
};
use tokio_stream::StreamExt;
#[tokio::main]
pub async fn main() -> std::io::Result<()> {
env_logger::init();
info!("Started");
match terminal_main().await {
Ok(()) => (),
Err(e) => println!("{}", e),
}
Ok(())
}
async fn terminal_main() -> std::io::Result<()> {
let mut app = match App::new().await {
Ok(app) => app,
Err(e) => {
return Err(e);
}
};
let mut events = Events::new();
info!("Intialising terminal (termion backend)");
let stdout = io::stdout().into_raw_mode()?;
let stdout = MouseTerminal::from(stdout);
let stdout = AlternateScreen::from(stdout);
let backend = TermionBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
info!("Processing started");
let start = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards");
let mut next_update = start - Duration::from_secs(2);
loop {
if next_update < SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards") {
terminal.draw(|f| draw_dashboard(f, &mut app))?;
next_update += Duration::from_secs(1);
}
let events_future = events.rx.recv().fuse();
let logfiles_future = app.logfiles.next().fuse();
pin_mut!(events_future, logfiles_future);
select! {
e = events_future => {
match e {
Some(Event::Input(input)) => {
match input {
Key::Char('~') => app.dash_state._debug_window(format!("Event::Input({:#?})", input).as_str()),
Key::Char('q')|
Key::Char('Q') => return Ok(()),
Key::Char('v')|
Key::Char('V') => set_main_view(DashViewMain::DashNode, &mut app),
Key::Char('+')|
Key::Char('i')|
Key::Char('I') => app.scale_timeline_up(),
Key::Char('-')|
Key::Char('o')|
Key::Char('O') => app.scale_timeline_down(),
Key::Char('m')|
Key::Char('M') => app.bump_mmm_ui_mode(),
Key::Char('t') => app.top_timeline_next(),
Key::Char('T') => app.top_timeline_previous(),
Key::Down => app.handle_arrow_down(),
Key::Up => app.handle_arrow_up(),
Key::Right|
Key::Char('\t') => app.change_focus_next(),
Key::Left => app.change_focus_previous(),
Key::Char('g') => set_main_view(DashViewMain::DashDebug, &mut app),
_ => {},
};
match terminal.draw(|f| draw_dashboard(f, &mut app)) {
Ok(_) => {},
Err(e) => {
error!("terminal.draw() '{:#?}'", e);
return Err(e);
}
};
}
Some(Event::Tick) => {
trace!("Event::Tick");
app.update_timelines(&Utc::now());
match terminal.draw(|f| draw_dashboard(f, &mut app)) {
Ok(_) => {},
Err(e) => {
error!("terminal.draw() '{:#?}'", e);
return Err(e);
}
};
trace!("Event::Tick DONE");
}
None => (),
}
},
line = logfiles_future => {
trace!("logfiles_future line");
match line {
Some(Ok(line)) => {
let source_str = line.source().to_str().unwrap();
let source = String::from(source_str);
match app.get_monitor_for_file_path(&source) {
Some(monitor) => {
trace!("APPENDING: {}", line.line());
monitor.append_to_content(line.line())?;
if monitor.is_debug_dashboard_log {
app.dash_state._debug_window(line.line());
}
},
None => (),
}
},
Some(Err(e)) => {
app.dash_state._debug_window(format!("logfile error: {:#?}", e).as_str());
error!("logfiles error '{:#?}'", e);
return Err(e)
},
None => {
app.dash_state._debug_window(format!("logfile error: None").as_str());
()
}
}
},
}
}
}