From bfa93c095a8b68181fdd8d1e9957bc5e98c0722c Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Mon, 24 Nov 2025 08:45:56 +0200 Subject: [PATCH] chore: remove tui module --- Cargo.toml | 2 +- tui/Cargo.toml | 17 ------ tui/src/app.rs | 96 ---------------------------------- tui/src/event.rs | 131 ----------------------------------------------- tui/src/main.rs | 13 ----- tui/src/ui.rs | 35 ------------- 6 files changed, 1 insertion(+), 293 deletions(-) delete mode 100644 tui/Cargo.toml delete mode 100644 tui/src/app.rs delete mode 100644 tui/src/event.rs delete mode 100644 tui/src/main.rs delete mode 100644 tui/src/ui.rs diff --git a/Cargo.toml b/Cargo.toml index 8780c1b..4efd94b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] resolver = "2" -members = ["aes", "cipher-core", "cli", "des", "tui"] +members = ["aes", "cipher-core", "cli", "des"] [workspace.dependencies] aes = { path = "aes" } diff --git a/tui/Cargo.toml b/tui/Cargo.toml deleted file mode 100644 index ea29329..0000000 --- a/tui/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "tui" -version = "0.1.0" -authors = ["Kristofers Solo "] -edition = "2024" - -[dependencies] -aes.workspace = true -cipher-core.workspace = true -color-eyre.workspace = true -crossterm = "0.28" -des.workspace = true -ratatui = "0.29" -thiserror.workspace = true - -[lints] -workspace = true diff --git a/tui/src/app.rs b/tui/src/app.rs deleted file mode 100644 index 0add324..0000000 --- a/tui/src/app.rs +++ /dev/null @@ -1,96 +0,0 @@ -use crate::event::{AppEvent, Event, EventHandler}; -use color_eyre::Result; -use ratatui::{ - DefaultTerminal, - crossterm::event::{KeyCode, KeyEvent, KeyModifiers}, -}; - -/// Application. -#[derive(Debug)] -pub struct App { - /// Is the application running? - pub running: bool, - /// Counter. - pub counter: u8, - /// Event handler. - pub events: EventHandler, -} - -impl Default for App { - fn default() -> Self { - Self { - running: true, - counter: 0, - events: EventHandler::new(), - } - } -} - -impl App { - /// Constructs a new instance of [`App`]. - pub fn new() -> Self { - Self::default() - } - - /// Run the application's main loop. - pub fn run(mut self, mut terminal: DefaultTerminal) -> Result<()> { - while self.running { - terminal.draw(|frame| frame.render_widget(&self, frame.area()))?; - self.handle_events()?; - } - Ok(()) - } - - pub fn handle_events(&mut self) -> Result<()> { - match self.events.next()? { - Event::Tick => self.tick(), - Event::Crossterm(event) => match event { - crossterm::event::Event::Key(key_event) - if key_event.kind == crossterm::event::KeyEventKind::Press => - { - self.handle_key_event(key_event); - } - _ => {} - }, - Event::App(app_event) => match app_event { - AppEvent::Increment => self.increment_counter(), - AppEvent::Decrement => self.decrement_counter(), - AppEvent::Quit => self.quit(), - }, - } - Ok(()) - } - - /// Handles the key events and updates the state of [`App`]. - pub fn handle_key_event(&self, key_event: KeyEvent) { - match key_event.code { - KeyCode::Esc | KeyCode::Char('q') => self.events.send(AppEvent::Quit), - KeyCode::Char('c' | 'C') if key_event.modifiers == KeyModifiers::CONTROL => { - self.events.send(AppEvent::Quit); - } - KeyCode::Right => self.events.send(AppEvent::Increment), - KeyCode::Left => self.events.send(AppEvent::Decrement), - // Other handlers you could add here. - _ => {} - } - } - - /// Handles the tick event of the terminal. - /// - /// The tick event is where you can update the state of your application with any logic that - /// needs to be updated at a fixed frame rate. E.g. polling a server, updating an animation. - pub const fn tick(&self) {} - - /// Set running to false to quit the application. - pub const fn quit(&mut self) { - self.running = false; - } - - pub const fn increment_counter(&mut self) { - self.counter = self.counter.saturating_add(1); - } - - pub const fn decrement_counter(&mut self) { - self.counter = self.counter.saturating_sub(1); - } -} diff --git a/tui/src/event.rs b/tui/src/event.rs deleted file mode 100644 index 44f57ee..0000000 --- a/tui/src/event.rs +++ /dev/null @@ -1,131 +0,0 @@ -use color_eyre::eyre::WrapErr; -use ratatui::crossterm::event::{self, Event as CrosstermEvent}; -use std::{ - sync::mpsc, - thread, - time::{Duration, Instant}, -}; - -/// The frequency at which tick events are emitted. -const TICK_FPS: f64 = 30.0; - -/// Representation of all possible events. -#[derive(Clone, Debug)] -pub enum Event { - /// An event that is emitted on a regular schedule. - /// - /// Use this event to run any code which has to run outside of being a direct response to a user - /// event. e.g. polling exernal systems, updating animations, or rendering the UI based on a - /// fixed frame rate. - Tick, - /// Crossterm events. - /// - /// These events are emitted by the terminal. - Crossterm(CrosstermEvent), - /// Application events. - /// - /// Use this event to emit custom events that are specific to your application. - App(AppEvent), -} - -/// Application events. -/// -/// You can extend this enum with your own custom events. -#[derive(Clone, Debug)] -pub enum AppEvent { - /// Increment the counter. - Increment, - /// Decrement the counter. - Decrement, - /// Quit the application. - Quit, -} - -/// Terminal event handler. -#[derive(Debug)] -pub struct EventHandler { - /// Event sender channel. - sender: mpsc::Sender, - /// Event receiver channel. - receiver: mpsc::Receiver, -} - -impl EventHandler { - /// Constructs a new instance of [`EventHandler`] and spawns a new thread to handle events. - pub fn new() -> Self { - let (sender, receiver) = mpsc::channel(); - let actor = EventThread::new(sender.clone()); - thread::spawn(|| actor.run()); - Self { sender, receiver } - } - - /// Receives an event from the sender. - /// - /// This function blocks until an event is received. - /// - /// # Errors - /// - /// This function returns an error if the sender channel is disconnected. This can happen if an - /// error occurs in the event thread. In practice, this should not happen unless there is a - /// problem with the underlying terminal. - pub fn next(&self) -> color_eyre::Result { - Ok(self.receiver.recv()?) - } - - /// Queue an app event to be sent to the event receiver. - /// - /// This is useful for sending events to the event handler which will be processed by the next - /// iteration of the application's event loop. - pub fn send(&self, app_event: AppEvent) { - // Ignore the result as the reciever cannot be dropped while this struct still has a - // reference to it - let _ = self.sender.send(Event::App(app_event)); - } -} - -/// A thread that handles reading crossterm events and emitting tick events on a regular schedule. -struct EventThread { - /// Event sender channel. - sender: mpsc::Sender, -} - -impl EventThread { - /// Constructs a new instance of [`EventThread`]. - const fn new(sender: mpsc::Sender) -> Self { - Self { sender } - } - - /// Runs the event thread. - /// - /// This function emits tick events at a fixed rate and polls for crossterm events in between. - fn run(self) -> color_eyre::Result<()> { - let tick_interval = Duration::from_secs_f64(1.0 / TICK_FPS); - let mut last_tick = Instant::now(); - loop { - // emit tick events at a fixed rate - let timeout = tick_interval.saturating_sub(last_tick.elapsed()); - if timeout == Duration::ZERO { - last_tick = Instant::now(); - self.send(Event::Tick); - } - // poll for crossterm events, ensuring that we don't block the tick interval - if event::poll(timeout).wrap_err("failed to poll for crossterm events")? { - let event = event::read().wrap_err("failed to read crossterm event")?; - self.send(Event::Crossterm(event)); - } - } - } - - /// Sends an event to the receiver. - fn send(&self, event: Event) { - // Ignores the result because shutting down the app drops the receiver, which causes the send - // operation to fail. This is expected behavior and should not panic. - let _ = self.sender.send(event); - } -} - -impl Default for EventHandler { - fn default() -> Self { - Self::new() - } -} diff --git a/tui/src/main.rs b/tui/src/main.rs deleted file mode 100644 index d4f1695..0000000 --- a/tui/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -use crate::app::App; - -mod app; -mod event; -mod ui; - -fn main() -> color_eyre::Result<()> { - color_eyre::install()?; - let terminal = ratatui::init(); - let result = App::new().run(terminal); - ratatui::restore(); - result -} diff --git a/tui/src/ui.rs b/tui/src/ui.rs deleted file mode 100644 index b111ff4..0000000 --- a/tui/src/ui.rs +++ /dev/null @@ -1,35 +0,0 @@ -use ratatui::{ - buffer::Buffer, - layout::{Alignment, Rect}, - style::{Color, Stylize}, - widgets::{Block, BorderType, Paragraph, Widget}, -}; - -use crate::app::App; - -impl Widget for &App { - /// Renders the user interface widgets. - /// - // This is where you add new widgets. - // See the following resources: - // - https://docs.rs/ratatui/latest/ratatui/widgets/index.html - // - https://github.com/ratatui/ratatui/tree/master/examples - fn render(self, area: Rect, buf: &mut Buffer) { - let block = Block::bordered() - .title("event-driven-generated") - .title_alignment(Alignment::Center) - .border_type(BorderType::Rounded); - - let text = format!( - "This is a tui template.\n\ - Press `Esc`, `Ctrl-C` or `q` to stop running.\n\ - Press left and right to increment and decrement the counter respectively.\n\ - Counter: {}", - self.counter - ); - - let paragraph = Paragraph::new(text).block(block).fg(Color::Cyan).centered(); - - paragraph.render(area, buf); - } -}