diff options
| -rw-r--r-- | src/app.rs | 10 | ||||
| -rw-r--r-- | src/input.rs | 85 | ||||
| -rw-r--r-- | src/main.rs | 46 | ||||
| -rw-r--r-- | src/ui.rs | 29 | ||||
| -rw-r--r-- | src/unit_of_measurement.rs | 36 |
5 files changed, 111 insertions, 95 deletions
@@ -1,9 +1,14 @@ -use crate::input::{InputParam, Row}; +use crate::{ + input::{InputParam, Row}, + unit_of_measurement::pressure, +}; pub struct App { rows: Vec<Row>, selected_row: usize, selected_column: InputParam, + + pub pressure_unit: pressure::Unit, } impl App { @@ -72,7 +77,8 @@ impl Default for App { App { rows: vec![Row::default()], selected_row: 0, - selected_column: InputParam::Rpm(String::new()), + selected_column: InputParam::Rpm(0), + pressure_unit: pressure::Unit::KiloPascal, } } } diff --git a/src/input.rs b/src/input.rs index 6507986..00cf410 100644 --- a/src/input.rs +++ b/src/input.rs @@ -1,62 +1,17 @@ +use crate::unit_of_measurement::{ + pressure::{Pressure, Unit::KiloPascal}, + UnitOfMeasurement, +}; + // A row in the inputs table has one of each variation. #[derive(Clone)] pub enum InputParam { - Rpm(String), // Revolutions per minute - Ve(String), // Volumetric efficiency - Map(String), // Manifold absolute pressure + Rpm(u32), // Revolutions per minute + Ve(u32), // Volumetric efficiency + Map(Pressure), // Manifold absolute pressure } impl InputParam { - /* Acts like the push() method of a Vec. - * Appends the given char to the end of the string contained by the - * InputParam. - */ - pub fn push(&mut self, c: char) { - match self { - Self::Rpm(rpm) => { - rpm.push(c); - *self = Self::Rpm(rpm.to_string()); - } - Self::Ve(ve) => { - ve.push(c); - *self = Self::Ve(ve.to_string()); - } - Self::Map(map) => { - map.push(c); - *self = Self::Map(map.to_string()); - } - } - } - - /* Acts like the pop() method of a Vec. - * Removes the last char from the string contained by the InputParam. - */ - pub fn pop(&mut self) { - match self { - Self::Rpm(rpm) => { - rpm.pop(); - *self = Self::Rpm(rpm.to_string()); - } - Self::Ve(ve) => { - ve.pop(); - *self = Self::Rpm(ve.to_string()); - } - Self::Map(map) => { - map.pop(); - *self = Self::Map(map.to_string()); - } - } - } - - // Return a copy of the string contained by the InputParam. - pub fn string(&self) -> String { - match self { - Self::Rpm(rpm) => rpm.to_string(), - Self::Ve(ve) => ve.to_string(), - Self::Map(map) => map.to_string(), - } - } - /* next() and previous() allow InputParam to act as a circular iterator of * sorts. next() will return the next variation as they are defined. When * it reaches the end, the first variation will be returned: @@ -66,17 +21,17 @@ impl InputParam { */ pub fn next(&self) -> Self { match self { - Self::Rpm(_) => Self::Ve(String::new()), - Self::Ve(_) => Self::Map(String::new()), - Self::Map(_) => Self::Rpm(String::new()), + Self::Rpm(_) => Self::Ve(0), + Self::Ve(_) => Self::Map(Pressure::default()), + Self::Map(_) => Self::Rpm(0), } } pub fn previous(&self) -> Self { match self { - Self::Rpm(_) => Self::Map(String::new()), - Self::Ve(_) => Self::Rpm(String::new()), - Self::Map(_) => Self::Ve(String::new()), + Self::Rpm(_) => Self::Map(Pressure::default()), + Self::Ve(_) => Self::Rpm(0), + Self::Map(_) => Self::Ve(0), } } } @@ -98,9 +53,9 @@ impl Row { impl Default for Row { fn default() -> Self { Self { - rpm: InputParam::Rpm(String::from("7000")), - ve: InputParam::Ve(String::from("95")), - map: InputParam::Map(String::from("200")), + rpm: InputParam::Rpm(7000), + ve: InputParam::Ve(95), + map: InputParam::Map(Pressure::from_unit(KiloPascal, 200)), } } } @@ -114,7 +69,7 @@ impl<'a> RowIter<'a> { fn from_row(row: &'a Row) -> Self { Self { row: row, - iter_state: Some(InputParam::Rpm(String::new())), + iter_state: Some(InputParam::Rpm(0)), } } } @@ -125,11 +80,11 @@ impl<'a> Iterator for RowIter<'a> { fn next(&mut self) -> Option<Self::Item> { match self.iter_state { Some(InputParam::Rpm(_)) => { - self.iter_state = Some(InputParam::Ve(String::new())); + self.iter_state = Some(InputParam::Ve(0)); Some(&self.row.rpm) } Some(InputParam::Ve(_)) => { - self.iter_state = Some(InputParam::Map(String::new())); + self.iter_state = Some(InputParam::Map(Pressure::default())); Some(&self.row.ve) } Some(InputParam::Map(_)) => { diff --git a/src/main.rs b/src/main.rs index d3901da..60b1fed 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,7 +9,12 @@ use tui::{ layout::{Constraint, Direction, Layout}, Frame, Terminal, }; -use volute::{app::App, ui}; +use volute::{ + app::App, + input::InputParam, + ui, + unit_of_measurement::{pressure::Pressure, UnitOfMeasurement}, +}; fn main() -> Result<(), Box<dyn Error>> { // setup terminal @@ -53,14 +58,45 @@ fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App) -> io::Result<( KeyCode::Char('k') => app.previous_row(), KeyCode::Char('l') => app.next_column(), KeyCode::Char('h') => app.previous_column(), - KeyCode::Char('p') => app.insert_row(), + KeyCode::Char('y') => app.insert_row(), KeyCode::Char('d') => app.remove_row(), + KeyCode::Char('p') => app.pressure_unit.next(), KeyCode::Char(c) => { - if ('0'..'a').contains(&c) { - app.selected_input_param_mut().push(c); + if ('0'..':').contains(&c) { + // 0 to 9 inclusive + let digit = c.to_digit(10).unwrap(); + match app.selected_input_param() { + InputParam::Rpm(rpm) => { + *app.selected_input_param_mut() = + InputParam::Rpm(*rpm * 10 + digit); + } + InputParam::Ve(ve) => { + *app.selected_input_param_mut() = InputParam::Ve(*ve * 10 + digit); + } + InputParam::Map(p) => { + *app.selected_input_param_mut() = + InputParam::Map(Pressure::from_unit( + app.pressure_unit, + p.as_unit(app.pressure_unit) * 10 + digit as i32, + )) + } + } } } - KeyCode::Backspace => app.selected_input_param_mut().pop(), + KeyCode::Backspace => match app.selected_input_param() { + InputParam::Rpm(rpm) => { + *app.selected_input_param_mut() = InputParam::Rpm(*rpm / 10); + } + InputParam::Ve(ve) => { + *app.selected_input_param_mut() = InputParam::Ve(*ve / 10); + } + InputParam::Map(p) => { + *app.selected_input_param_mut() = InputParam::Map(Pressure::from_unit( + app.pressure_unit, + p.as_unit(app.pressure_unit) / 10, + )) + } + }, _ => {} } } @@ -1,10 +1,4 @@ -use crate::{ - app::App, - unit_of_measurement::{ - pressure::{self, Pressure}, - UnitOfMeasurement, - }, -}; +use crate::{app::App, input::InputParam, unit_of_measurement::UnitOfMeasurement}; use std::ptr; use tui::{ layout::Constraint, @@ -15,10 +9,15 @@ use tui::{ pub fn input_table(app: &App) -> impl Widget { let rows = app.rows().iter().map(|row| { let cells = row.iter().map(|item| { + let item_str = match item { + InputParam::Rpm(rpm) => rpm.to_string(), + InputParam::Ve(ve) => ve.to_string(), + InputParam::Map(p) => p.as_unit(app.pressure_unit).to_string(), + }; if ptr::eq(item, app.selected_input_param()) { - Cell::from(item.string()).style(Style::default().fg(Color::Yellow)) + Cell::from(item_str).style(Style::default().fg(Color::Yellow)) } else { - Cell::from(item.string()) + Cell::from(item_str) } }); widgets::Row::new(cells) @@ -35,10 +34,10 @@ pub fn input_table(app: &App) -> impl Widget { } pub fn output_table(app: &App) -> impl Widget { - let map = match app.rows()[0].map.string().parse::<i32>() { - Ok(p) => Pressure::from_unit(pressure::Unit::KiloPascal, p), - Err(_) => Pressure::default(), - }; - Paragraph::new(map.as_unit(pressure::Unit::KiloPascal).to_string()) - .block(Block::default().title("map").borders(Borders::ALL)) + if let InputParam::Map(p) = &app.rows()[0].map { + Paragraph::new(p.as_unit(app.pressure_unit).to_string()) + .block(Block::default().title("map").borders(Borders::ALL)) + } else { + Paragraph::new("err").block(Block::default().title("map").borders(Borders::ALL)) + } } diff --git a/src/unit_of_measurement.rs b/src/unit_of_measurement.rs index a3b4b77..ce459bf 100644 --- a/src/unit_of_measurement.rs +++ b/src/unit_of_measurement.rs @@ -8,27 +8,47 @@ pub trait UnitOfMeasurement { pub mod pressure { use super::UnitOfMeasurement; - #[derive(Default)] - pub struct Pressure { - val: i32, - } + #[derive(Default, Clone)] + pub struct Pressure(i32); + #[derive(Copy, Clone)] pub enum Unit { Pascal = 1, KiloPascal = 1000, } + impl Unit { + // Pseudo iter::Cycle behavior. + pub fn next(&mut self) { + match self { + Unit::Pascal => { + *self = Unit::KiloPascal; + } + Unit::KiloPascal => { + *self = Unit::Pascal; + } + } + } + } + + impl ToString for Unit { + fn to_string(&self) -> String { + match self { + Self::Pascal => String::from("Pa"), + Self::KiloPascal => String::from("kPa"), + } + } + } + impl UnitOfMeasurement for Pressure { type Unit = Unit; fn from_unit(unit: Self::Unit, n: i32) -> Self { - Self { - val: n * unit as i32, - } + Self(n * unit as i32) } fn as_unit(&self, unit: Self::Unit) -> i32 { - self.val / unit as i32 + self.0 / unit as i32 } } } |