From 6e6e7581b4c8575dd379f20a786108ce4edcd9c8 Mon Sep 17 00:00:00 2001 From: Sam Anthony Date: Wed, 1 Feb 2023 19:50:32 -0330 Subject: refactor --- src/input.rs | 45 ++++++++++++++++++++++++ src/lib.rs | 40 +++++++++++++++++++++ src/main.rs | 112 ++--------------------------------------------------------- src/ui.rs | 30 +++++++++++++++- 4 files changed, 117 insertions(+), 110 deletions(-) create mode 100644 src/input.rs diff --git a/src/input.rs b/src/input.rs new file mode 100644 index 0000000..5ffaec8 --- /dev/null +++ b/src/input.rs @@ -0,0 +1,45 @@ +use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; + +use crate::{Calculator, Operator, Signal}; + +impl Calculator { + pub fn handle_input(&mut self, key: KeyEvent) -> Signal { + match key.modifiers { + KeyModifiers::CONTROL => match key.code { + KeyCode::Char('c') => { + return Signal::Exit; + } + _ => {} + }, + KeyModifiers::NONE => match key.code { + KeyCode::Char('q') => { + return Signal::Exit; + } + KeyCode::Char(c) => { + if c.is_ascii_digit() { + self.input_buffer.push(c); + } else if c == '.' && !self.input_buffer.contains('.') { + if self.input_buffer.len() == 0 { + self.input_buffer.push('0'); + } + self.input_buffer.push(c); + } else if let Ok(op) = Operator::parse(c) { + if self.input_buffer.len() > 0 { + self.push_buffer_to_stack(); + } + self.perform_operation(op); + } + } + KeyCode::Enter if self.input_buffer.len() > 0 => { + self.push_buffer_to_stack(); + } + KeyCode::Backspace => { + self.input_buffer.pop(); + } + _ => {} + }, + _ => {} + } + return Signal::None; + } +} diff --git a/src/lib.rs b/src/lib.rs index e08796d..79210fc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,40 @@ +mod input; pub mod ui; +#[derive(Default)] +pub struct Calculator { + stack: Vec, + input_buffer: String, +} + +impl Calculator { + fn push_buffer_to_stack(&mut self) { + self.stack.push(self.input_buffer.parse::().unwrap()); + self.input_buffer = String::new(); + } + + fn perform_operation(&mut self, op: Operator) { + let rhs = match self.stack.pop() { + Some(f) => f, + None => { + return; + } + }; + let lhs = match self.stack.pop() { + Some(f) => f, + None => { + return; + } + }; + match op { + Operator::Add => self.stack.push(lhs + rhs), + Operator::Sub => self.stack.push(lhs - rhs), + Operator::Mul => self.stack.push(lhs * rhs), + Operator::Div => self.stack.push(lhs / rhs), + } + } +} + pub enum Operator { Add, Sub, @@ -20,3 +55,8 @@ impl Operator { } pub struct ParseOperatorError(char); + +pub enum Signal { + None, + Exit, +} diff --git a/src/main.rs b/src/main.rs index 89c47aa..be9f440 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,114 +1,8 @@ -use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyModifiers}; +use crossterm::event::{self, Event}; use std::io; -use tui::{ - backend::Backend, - layout::{Constraint, Direction, Layout}, - widgets::{List, ListItem, Paragraph}, - Frame, Terminal, -}; +use tui::{backend::Backend, Terminal}; -use pfc::{ui, Operator}; - -enum Signal { - None, - Exit, -} - -#[derive(Default)] -struct Calculator { - stack: Vec, - input_buffer: String, -} - -impl Calculator { - fn handle_input(&mut self, key: KeyEvent) -> Signal { - match key.modifiers { - KeyModifiers::CONTROL => match key.code { - KeyCode::Char('c') => { - return Signal::Exit; - } - _ => {} - }, - KeyModifiers::NONE => match key.code { - KeyCode::Char('q') => { - return Signal::Exit; - } - KeyCode::Char(c) => { - if c.is_ascii_digit() { - self.input_buffer.push(c); - } else if c == '.' && !self.input_buffer.contains('.') { - if self.input_buffer.len() == 0 { - self.input_buffer.push('0'); - } - self.input_buffer.push(c); - } else if let Ok(op) = Operator::parse(c) { - if self.input_buffer.len() > 0 { - self.push_buffer_to_stack(); - } - self.perform_operation(op); - } - } - KeyCode::Enter if self.input_buffer.len() > 0 => { - self.push_buffer_to_stack(); - } - KeyCode::Backspace => { - self.input_buffer.pop(); - } - _ => {} - }, - _ => {} - } - return Signal::None; - } - - fn draw(&self, f: &mut Frame) { - let chunks = Layout::default() - .direction(Direction::Vertical) - .constraints( - [ - Constraint::Max(u16::MAX), - Constraint::Length(self.stack.len() as u16), - Constraint::Length(1), - ] - .as_ref(), - ) - .split(f.size()); - - let items: Vec = (self.stack) - .iter() - .map(|f| ListItem::new(format!("{}", f))) - .collect(); - f.render_widget(List::new(items), chunks[1]); - - f.render_widget(Paragraph::new(self.input_buffer.as_str()), chunks[2]); - } - - fn perform_operation(&mut self, op: Operator) { - let rhs = match self.stack.pop() { - Some(f) => f, - None => { - return; - } - }; - let lhs = match self.stack.pop() { - Some(f) => f, - None => { - return; - } - }; - match op { - Operator::Add => self.stack.push(lhs + rhs), - Operator::Sub => self.stack.push(lhs - rhs), - Operator::Mul => self.stack.push(lhs * rhs), - Operator::Div => self.stack.push(lhs / rhs), - } - } - - fn push_buffer_to_stack(&mut self) { - self.stack.push(self.input_buffer.parse::().unwrap()); - self.input_buffer = String::new(); - } -} +use pfc::{ui, Calculator, Signal}; fn main() -> io::Result<()> { let calculator = Calculator::default(); diff --git a/src/ui.rs b/src/ui.rs index 9133f1c..bb5057d 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -6,9 +6,37 @@ use crossterm::{ use std::io; use tui::{ backend::{Backend, CrosstermBackend}, - Terminal, + layout::{Constraint, Direction, Layout}, + widgets::{List, ListItem, Paragraph}, + Frame, Terminal, }; +use crate::Calculator; + +impl Calculator { + pub fn draw(&self, f: &mut Frame) { + let chunks = Layout::default() + .direction(Direction::Vertical) + .constraints( + [ + Constraint::Max(u16::MAX), + Constraint::Length(self.stack.len() as u16), + Constraint::Length(1), + ] + .as_ref(), + ) + .split(f.size()); + + let items: Vec = (self.stack) + .iter() + .map(|f| ListItem::new(format!("{}", f))) + .collect(); + f.render_widget(List::new(items), chunks[1]); + + f.render_widget(Paragraph::new(self.input_buffer.as_str()), chunks[2]); + } +} + pub fn init_terminal() -> Result>, io::Error> { enable_raw_mode()?; let mut stdout = io::stdout(); -- cgit v1.2.3