aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorsam-anthony <samanthony6@protonmail.com>2022-03-08 19:55:08 -0330
committersam-anthony <samanthony6@protonmail.com>2022-03-08 19:55:08 -0330
commit90f42ad66feb6b77474d0da267d572eca16e2826 (patch)
treea35319f2457e2e65bf8ff4536e142b7211fb09b9 /src
parentd286ed3eb877365c01f7a7ec56de9a0dc84bab2e (diff)
downloadvolute-90f42ad66feb6b77474d0da267d572eca16e2826.zip
switchable pressure unit
Diffstat (limited to 'src')
-rw-r--r--src/app.rs10
-rw-r--r--src/input.rs85
-rw-r--r--src/main.rs46
-rw-r--r--src/ui.rs29
-rw-r--r--src/unit_of_measurement.rs36
5 files changed, 111 insertions, 95 deletions
diff --git a/src/app.rs b/src/app.rs
index dedb11e..1ca6196 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -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,
+ ))
+ }
+ },
_ => {}
}
}
diff --git a/src/ui.rs b/src/ui.rs
index 9411157..65b1ad0 100644
--- a/src/ui.rs
+++ b/src/ui.rs
@@ -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
}
}
}