diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/app.rs | 84 | ||||
| -rw-r--r-- | src/input.rs | 97 | ||||
| -rw-r--r-- | src/lib.rs | 4 | ||||
| -rw-r--r-- | src/main.rs | 113 | ||||
| -rw-r--r-- | src/ui.rs | 43 | ||||
| -rw-r--r-- | src/unit_of_measurement.rs | 54 |
6 files changed, 0 insertions, 395 deletions
diff --git a/src/app.rs b/src/app.rs deleted file mode 100644 index 1ca6196..0000000 --- a/src/app.rs +++ /dev/null @@ -1,84 +0,0 @@ -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 { - pub fn rows(&self) -> &Vec<Row> { - &self.rows - } - - pub fn next_row(&mut self) { - if self.selected_row < self.rows.len() - 1 { - self.selected_row += 1; - } else { - self.selected_row = 0; - } - } - - pub fn previous_row(&mut self) { - if self.selected_row > 0 { - self.selected_row -= 1; - } else { - self.selected_row = self.rows.len() - 1; - } - } - - pub fn next_column(&mut self) { - self.selected_column = self.selected_column.next(); - } - - pub fn previous_column(&mut self) { - self.selected_column = self.selected_column.previous(); - } - - pub fn insert_row(&mut self) { - let index = self.selected_row; - self.rows.insert(index, self.rows[index].clone()); - } - - pub fn remove_row(&mut self) { - if self.rows.len() > 1 { - self.rows.remove(self.selected_row); - // If we remove the last row, the selected row will be out of range. - if self.selected_row >= self.rows.len() { - self.selected_row = self.rows.len() - 1; - } - } - } - - pub fn selected_input_param(&self) -> &InputParam { - match self.selected_column { - InputParam::Rpm(_) => &self.rows[self.selected_row].rpm, - InputParam::Ve(_) => &self.rows[self.selected_row].ve, - InputParam::Map(_) => &self.rows[self.selected_row].map, - } - } - - pub fn selected_input_param_mut(&mut self) -> &mut InputParam { - match self.selected_column { - InputParam::Rpm(_) => &mut self.rows[self.selected_row].rpm, - InputParam::Ve(_) => &mut self.rows[self.selected_row].ve, - InputParam::Map(_) => &mut self.rows[self.selected_row].map, - } - } -} - -impl Default for App { - fn default() -> App { - App { - rows: vec![Row::default()], - selected_row: 0, - selected_column: InputParam::Rpm(0), - pressure_unit: pressure::Unit::KiloPascal, - } - } -} diff --git a/src/input.rs b/src/input.rs deleted file mode 100644 index 00cf410..0000000 --- a/src/input.rs +++ /dev/null @@ -1,97 +0,0 @@ -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(u32), // Revolutions per minute - Ve(u32), // Volumetric efficiency - Map(Pressure), // Manifold absolute pressure -} - -impl InputParam { - /* 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: - * RPM->VE->MAP->RPM->etc... - * previous() simply goes the opposite direction: - * MAP->VE->RPM->MAP->etc... - */ - pub fn next(&self) -> Self { - match self { - 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(Pressure::default()), - Self::Ve(_) => Self::Rpm(0), - Self::Map(_) => Self::Ve(0), - } - } -} - -// A row in the inputs table. Contains one of each variation of InputParam. -#[derive(Clone)] -pub struct Row { - pub rpm: InputParam, - pub ve: InputParam, - pub map: InputParam, -} - -impl Row { - pub fn iter(&self) -> RowIter { - RowIter::from_row(&self) - } -} - -impl Default for Row { - fn default() -> Self { - Self { - rpm: InputParam::Rpm(7000), - ve: InputParam::Ve(95), - map: InputParam::Map(Pressure::from_unit(KiloPascal, 200)), - } - } -} - -pub struct RowIter<'a> { - row: &'a Row, - iter_state: Option<InputParam>, -} - -impl<'a> RowIter<'a> { - fn from_row(row: &'a Row) -> Self { - Self { - row: row, - iter_state: Some(InputParam::Rpm(0)), - } - } -} - -impl<'a> Iterator for RowIter<'a> { - type Item = &'a InputParam; - - fn next(&mut self) -> Option<Self::Item> { - match self.iter_state { - Some(InputParam::Rpm(_)) => { - self.iter_state = Some(InputParam::Ve(0)); - Some(&self.row.rpm) - } - Some(InputParam::Ve(_)) => { - self.iter_state = Some(InputParam::Map(Pressure::default())); - Some(&self.row.ve) - } - Some(InputParam::Map(_)) => { - self.iter_state = None; - Some(&self.row.map) - } - None => None, - } - } -} diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index b33113b..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod app; -pub mod input; -pub mod ui; -pub mod unit_of_measurement; diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 60b1fed..0000000 --- a/src/main.rs +++ /dev/null @@ -1,113 +0,0 @@ -use crossterm::{ - event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode}, - execute, - terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, -}; -use std::{error::Error, io}; -use tui::{ - backend::{Backend, CrosstermBackend}, - layout::{Constraint, Direction, Layout}, - Frame, Terminal, -}; -use volute::{ - app::App, - input::InputParam, - ui, - unit_of_measurement::{pressure::Pressure, UnitOfMeasurement}, -}; - -fn main() -> Result<(), Box<dyn Error>> { - // setup terminal - enable_raw_mode()?; - let mut stdout = io::stdout(); - execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?; - let backend = CrosstermBackend::new(stdout); - let mut terminal = Terminal::new(backend)?; - - // create app and run it - let app = App::default(); - let res = run_app(&mut terminal, app); - - // restore terminal - disable_raw_mode()?; - execute!( - terminal.backend_mut(), - LeaveAlternateScreen, - DisableMouseCapture - )?; - terminal.show_cursor()?; - - if let Err(err) = res { - println!("{:?}", err) - } - - Ok(()) -} - -// Input handling -fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App) -> io::Result<()> { - loop { - terminal.draw(|f| ui(f, &app))?; - - if let Event::Key(key) = event::read()? { - match key.code { - KeyCode::Char('q') => { - return Ok(()); - } - KeyCode::Char('j') => app.next_row(), - KeyCode::Char('k') => app.previous_row(), - KeyCode::Char('l') => app.next_column(), - KeyCode::Char('h') => app.previous_column(), - KeyCode::Char('y') => app.insert_row(), - KeyCode::Char('d') => app.remove_row(), - KeyCode::Char('p') => app.pressure_unit.next(), - KeyCode::Char(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 => 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, - )) - } - }, - _ => {} - } - } - } -} - -fn ui<B: Backend>(f: &mut Frame<B>, app: &App) { - let layout = Layout::default() - .direction(Direction::Horizontal) - .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref()) - .split(f.size()); - f.render_widget(ui::input_table(app), layout[0]); - f.render_widget(ui::output_table(app), layout[1]); -} diff --git a/src/ui.rs b/src/ui.rs deleted file mode 100644 index 65b1ad0..0000000 --- a/src/ui.rs +++ /dev/null @@ -1,43 +0,0 @@ -use crate::{app::App, input::InputParam, unit_of_measurement::UnitOfMeasurement}; -use std::ptr; -use tui::{ - layout::Constraint, - style::{Color, Style}, - widgets::{self, Block, Borders, Cell, Paragraph, Table, Widget}, -}; - -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_str).style(Style::default().fg(Color::Yellow)) - } else { - Cell::from(item_str) - } - }); - widgets::Row::new(cells) - }); - - Table::new(rows) - .header(widgets::Row::new(vec!["rpm", "ve", "map"])) - .block(Block::default().borders(Borders::ALL).title("inputs")) - .widths(&[ - Constraint::Length(5), // rpm - Constraint::Length(3), // ve - Constraint::Length(3), // map - ]) -} - -pub fn output_table(app: &App) -> impl Widget { - 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 deleted file mode 100644 index ce459bf..0000000 --- a/src/unit_of_measurement.rs +++ /dev/null @@ -1,54 +0,0 @@ -pub trait UnitOfMeasurement { - type Unit; - - fn from_unit(unit: Self::Unit, n: i32) -> Self; - fn as_unit(&self, unit: Self::Unit) -> i32; -} - -pub mod pressure { - use super::UnitOfMeasurement; - - #[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(n * unit as i32) - } - - fn as_unit(&self, unit: Self::Unit) -> i32 { - self.0 / unit as i32 - } - } -} |