From 3ec20688c2618f7a224732f669e4812087140d7d Mon Sep 17 00:00:00 2001 From: Simon Rupf Date: Mon, 25 Dec 2023 12:03:35 +0100 Subject: [PATCH] lints, typo, internalized list mode state --- CHANGELOG.md | 3 +- src/main.rs | 120 ++++++++++++++++++++++++++++----------------------- 2 files changed, 69 insertions(+), 54 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d0fdd0..f9b8da2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,12 @@ Change Log of Atari Portfolio address file reader ================================================= -Version 0.2.0 / 2023-07-01 +Version 0.2.0 / 2023-12-25 -------------------------- - updated dependencies, increased Rust edition & version - added this Change Log - added GitHub actions for dependency updates, linting and release builds +- applied lints, corrected typo, internalized list mode state Version 0.1.0 / 2020-09-20 -------------------------- diff --git a/src/main.rs b/src/main.rs index 9e919a6..ff7564b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ use std::{env::args, fs::read, io::stdout, process::exit}; use chrono::Local; -use codepage_437::{CP437_CONTROL, BorrowFromCp437}; +use codepage_437::{BorrowFromCp437, CP437_CONTROL}; use crossterm::{ event::{self, Event, KeyCode}, @@ -14,19 +14,20 @@ use tui::{ layout::Rect, style::{Color, Style}, text::{Span, Text}, - widgets::{Block, Borders, BorderType, List, ListItem, ListState, Paragraph}, + widgets::{Block, BorderType, Borders, List, ListItem, ListState, Paragraph}, Frame, Terminal, }; -struct Adresses<'a> { +struct Addresses<'a> { path: String, addresses: Vec<&'a str>, headers: Vec>, + is_list_mode: bool, state: ListState, } -impl<'a> Adresses<'a> { - pub fn new(path: String, content: &'a str) -> Adresses<'a> { +impl<'a> Addresses<'a> { + pub fn new(path: String, content: &'a str) -> Addresses<'a> { // content can be zero terminated and ends in a final CR+LF+CR+LF to be trimmed, before we split on that pattern let addresses: Vec<&str> = content .trim_matches('\0') @@ -38,10 +39,11 @@ impl<'a> Adresses<'a> { .map(|address| ListItem::new(address.split("\r\n").next().unwrap())) .collect(); let state = ListState::default(); - Adresses { + Addresses { path, addresses, headers, + is_list_mode: true, state, } } @@ -80,26 +82,30 @@ impl<'a> Adresses<'a> { Rect::new(size.x + 2, size.y + 1, size.width - 3, size.height - 2) } - pub fn draw_list(&mut self, f: &mut Frame) { - let items = List::new(self.headers.clone()) - .style(Style::default().fg(Color::White)) - .highlight_style(Style::default().fg(Color::Black).bg(Color::White)); - let inner_size = self.draw_block(f); - f.render_stateful_widget(items, inner_size, &mut self.state); + pub fn draw(&mut self, f: &mut Frame) { + if self.is_list_mode { + let items = List::new(self.headers.clone()) + .style(Style::default().fg(Color::White)) + .highlight_style(Style::default().fg(Color::Black).bg(Color::White)); + let inner_size = self.draw_block(f); + f.render_stateful_widget(items, inner_size, &mut self.state); + } else { + let address = Paragraph::new(Text::from( + self.addresses[match self.state.selected() { + Some(i) => i, + None => { + self.state.select(Some(0)); + 0 + } + }], + )); + let inner_size = self.draw_block(f); + f.render_widget(address, inner_size); + } } - pub fn draw_selected(&mut self, f: &mut Frame) { - let address = Paragraph::new(Text::from( - self.addresses[match self.state.selected() { - Some(i) => i, - None => { - self.state.select(Some(0)); - 0 - } - }], - )); - let inner_size = self.draw_block(f); - f.render_widget(address, inner_size); + pub fn is_list_mode(&mut self) -> bool { + self.is_list_mode } pub fn next(&mut self) { @@ -129,47 +135,60 @@ impl<'a> Adresses<'a> { }; self.state.select(Some(i)); } + + pub fn toggle_mode(&mut self) { + self.is_list_mode = !self.is_list_mode; + } } fn main() { - let path = match args().nth(1) { - Some(path) => path, - None => { - eprintln!("Missing argument: no path to file given"); - exit(255); - } - }; - - let dos_content = match read(path.clone()) { - Ok(content) => content, - Err(error) => { - eprintln!("Error reading file {}", path); - eprintln!("{}", error); - exit(254); - } - }; - let utf8_content = String::borrow_from_cp437(&dos_content, &CP437_CONTROL); - let mut addresses = Adresses::new(path, &utf8_content); - let mut is_list_mode = true; + // stores parsed string slices of addresses and descriptions, tracks + // position in the list, draws frame + let mut addresses; + // parsed string, borrowed to addresses for tracking the offsets into it for + // the string slices of addresses and descriptions + let utf8_content; + + // closure to drop parsing state is when done + { + let path = match args().nth(1) { + Some(path) => path, + None => { + eprintln!("Missing argument: no path to file given"); + exit(255); + } + }; + + let dos_content = match read(&path) { + Ok(content) => content, + Err(error) => { + eprintln!("Error reading file {}", path); + eprintln!("{}", error); + exit(254); + } + }; + utf8_content = String::borrow_from_cp437(&dos_content, &CP437_CONTROL); + addresses = Addresses::new(path, &utf8_content); + } enable_raw_mode().unwrap(); // prevent key presses reaching stdout let mut terminal = Terminal::new(CrosstermBackend::new(stdout())).unwrap(); terminal.clear().unwrap(); - terminal.draw(|f| addresses.draw_list(f)).unwrap(); + terminal.draw(|f| addresses.draw(f)).unwrap(); loop { if let Event::Key(key) = event::read().unwrap() { - if is_list_mode { + if addresses.is_list_mode() { match key.code { KeyCode::Esc => break, - KeyCode::Enter => is_list_mode = !is_list_mode, + KeyCode::Enter => addresses.toggle_mode(), KeyCode::Down => addresses.next(), KeyCode::Up => addresses.previous(), _ => continue, } } else { match key.code { - KeyCode::Esc => is_list_mode = !is_list_mode, + KeyCode::Esc => addresses.toggle_mode(), KeyCode::PageDown => addresses.next(), KeyCode::PageUp => addresses.previous(), _ => continue, @@ -177,12 +196,7 @@ fn main() { } terminal .draw(|f| { - // mode might have changed, check it again - if is_list_mode { - addresses.draw_list(f); - } else { - addresses.draw_selected(f); - } + addresses.draw(f); }) .unwrap(); }