diff --git a/Cargo.toml b/Cargo.toml index 924f6fb..8424085 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,6 @@ members = [ "candid_server", "candid_client", - "candid_tui", ] [workspace.package] diff --git a/candid_tui/Cargo.toml b/candid_tui/Cargo.toml deleted file mode 100644 index cd0ba2b..0000000 --- a/candid_tui/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "candid_tui" -version = "0.1.0" -authors = ["Alex van de Sandt "] -edition = "2018" -description = "" -license = "MIT" -readme = "README" -documentation = "https://docs.rs/crate/candid_client/" -repository = "https://gitlab.com/avandesa/candid-rs" -keywords = ["CAN", "SocketCAN"] -publish = false - -[dependencies] -candid_client = "0.3.2" -clap = "^2.32" -tui = "0.5" -termion = "^1.5" diff --git a/candid_tui/src/app.rs b/candid_tui/src/app.rs deleted file mode 100644 index 87d7bb6..0000000 --- a/candid_tui/src/app.rs +++ /dev/null @@ -1,40 +0,0 @@ -//! Module for maintaining app state - -use crate::util::{FrameInfo, ListState}; - -/// Container for everything related to application state -pub struct AppState<'a> { - /// The title to be displayed in the top left - pub title: &'a str, - - /// Whether or not the app should terminate - pub should_quit: bool, - - /// The frames that have been received from the server to this point - pub frame_history: ListState, -} - -impl<'a> AppState<'a> { - /// Initialize a new app - pub fn new(title: &'a str) -> AppState<'a> { - AppState { - title, - should_quit: false, - frame_history: ListState::new(), - } - } - - pub fn on_key(&mut self, c: char) { - match c { - 'q' => self.should_quit = true, - _ => {} - } - } - - pub fn on_up(&mut self) { - self.frame_history.previous(); - } - pub fn on_down(&mut self) { - self.frame_history.next(); - } -} diff --git a/candid_tui/src/event.rs b/candid_tui/src/event.rs deleted file mode 100644 index 4b5cb0a..0000000 --- a/candid_tui/src/event.rs +++ /dev/null @@ -1,81 +0,0 @@ -//! A module for configuring and executing event loops. An `Events` instance will listen to `stdin -//! for user input and read frames from the server, aggregating these events to be sent back to the -//! app itself. -//! -//! All code in this module is *heavily* inspired by [`tui-rs`'s demo -//! code](https://github.com/fdehau/tui-rs/blob/master/examples/util/event.rs) - -use crate::util::FrameInfo; - -use std::sync::mpsc; -use std::{io, thread}; - -use candid_client::*; - -use termion::event::Key; -use termion::input::TermRead; - -pub enum Event { - Input(I), - Frame(FrameInfo), -} - -/// An event handler that wraps termion input and tick events. -/// Each event thype is handled in its own thread and returned to a common `Receiver` -pub struct Events { - /// The receiver that aggregates all other events - rx: mpsc::Receiver>, - - /// Thread that reads input from the user - _input_handle: thread::JoinHandle<()>, - - /// Thread that reads frames from the remote CANdid server - _frame_handle: thread::JoinHandle<()>, -} - -impl Events { - /// Creates a new event handle - pub fn new(mut server: CandidConnection) -> Events { - let (tx, rx) = mpsc::channel(); - - let _input_handle = { - let tx = tx.clone(); - thread::spawn(move || { - let stdin = io::stdin(); - for evt in stdin.keys() { - match evt { - Ok(key) => { - if let Err(_) = tx.send(Event::Input(key)) { - return; - } - if key == Key::Char('q') { - return; - } - } - Err(_) => {} - } - } - }) - }; - - let _frame_handle = { - let tx = tx.clone(); - thread::spawn(move || loop { - let frame = server.read_frame().unwrap(); - let frame = FrameInfo(frame, format!("{:?}", frame).to_string()); - - tx.send(Event::Frame(frame)).unwrap(); - }) - }; - - Events { - rx, - _input_handle, - _frame_handle, - } - } - - pub fn next(&self) -> Result, mpsc::RecvError> { - self.rx.recv() - } -} diff --git a/candid_tui/src/lib.rs b/candid_tui/src/lib.rs deleted file mode 100644 index a188e6b..0000000 --- a/candid_tui/src/lib.rs +++ /dev/null @@ -1,8 +0,0 @@ -pub mod app; -pub mod event; -pub mod ui; -pub mod util; - -pub use app::AppState; -pub use event::{Event, Events}; -pub use ui::draw; diff --git a/candid_tui/src/main.rs b/candid_tui/src/main.rs deleted file mode 100644 index d9a8430..0000000 --- a/candid_tui/src/main.rs +++ /dev/null @@ -1,67 +0,0 @@ -use candid_tui::*; - -use candid_client::*; - -use std::io; - -use clap::{App, Arg}; - -use termion::event::Key; -use termion::raw::IntoRawMode; -use termion::screen::AlternateScreen; - -use tui::backend::TermionBackend; -use tui::Terminal; - -fn main() { - let matches = App::new("CANdid Client") - .version("0.1.0") - .author("Alex van de Sandt ") - .about("A client to read messages from a CANdid server") - .arg( - Arg::with_name("addr") - .value_name("ADDRESS") - .help("The address:port to connect to") - .takes_value(true) - .required(true), - ) - .get_matches(); - - let addr = matches.value_of("addr").unwrap(); - - let server = CandidConnection::new(addr).expect("Couldn't connect to server"); - - // Initialize tui - let stdout = io::stdout().into_raw_mode().unwrap(); - let stdout = AlternateScreen::from(stdout); - let backend = TermionBackend::new(stdout); - let mut terminal = Terminal::new(backend).unwrap(); - terminal.hide_cursor().unwrap(); - - // Initialize the app state - let mut app = AppState::new("CANdid TUI"); - - // Initialize the event aggregator - let events = Events::new(server); - - loop { - // Refresh the ui - candid_tui::draw(&mut terminal, &app).unwrap(); - - // Handle an incoming event - match events.next().unwrap() { - Event::Input(key) => match key { - Key::Char(c) => app.on_key(c), - Key::Up => app.on_up(), - Key::Down => app.on_down(), - _ => {} - }, - Event::Frame(frame) => app.frame_history.push(frame), - } - - // Exit if necessary, set in app.on_key(q) - if app.should_quit { - break; - } - } -} diff --git a/candid_tui/src/ui.rs b/candid_tui/src/ui.rs deleted file mode 100644 index 8b2be02..0000000 --- a/candid_tui/src/ui.rs +++ /dev/null @@ -1,22 +0,0 @@ -use crate::app::AppState; - -use std::io; - -use tui::backend::Backend; -use tui::style::{Color, Modifier, Style}; -use tui::widgets::{Block, Borders, SelectableList, Widget}; -use tui::Terminal; - -pub fn draw(terminal: &mut Terminal, app: &AppState) -> Result<(), io::Error> { - terminal.draw(|mut f| { - let size = f.size(); - // List all the frames received to this point - SelectableList::default() - .block(Block::default().borders(Borders::ALL).title(app.title)) - .items(&app.frame_history.items) - .select(Some(app.frame_history.selected)) - .highlight_style(Style::default().fg(Color::Yellow).modifier(Modifier::BOLD)) - .highlight_symbol(">") - .render(&mut f, size) - }) -} diff --git a/candid_tui/src/util.rs b/candid_tui/src/util.rs deleted file mode 100644 index d549f16..0000000 --- a/candid_tui/src/util.rs +++ /dev/null @@ -1,46 +0,0 @@ -use candid_client::Frame; - -/// Keeps track of the position in a list, ued for SelectableLists -pub struct ListState { - pub items: Vec, - pub selected: usize, -} - -impl ListState { - /// Initialize a new ListState with no items - pub fn new() -> ListState { - ListState { - items: Vec::new(), - selected: 0, - } - } - - /// Add an item to the end of the list - pub fn push(&mut self, item: I) { - self.items.push(item); - } - - /// Select the previous item in the list - pub fn previous(&mut self) { - if self.selected > 0 { - self.selected -= 1; - } - } - - /// Select the next item in the list - pub fn next(&mut self) { - if self.selected < self.items.len() - 1 { - self.selected += 1 - } - } -} - -/// Holds the Frame and its string representation -pub struct FrameInfo(pub Frame, pub String); - -impl AsRef for FrameInfo { - /// Allows the FrameInfo to be used in a SelectableList - fn as_ref(&self) -> &str { - &self.1 - } -}