From 6f1d64ea02119a1225556a2a23ba8a2a6c286bb1 Mon Sep 17 00:00:00 2001 From: Simon Gardling Date: Tue, 5 Apr 2022 09:14:35 -0400 Subject: [PATCH] code cleanup --- build.rs | 2 +- src/consts.rs | 9 ++++++--- src/function.rs | 30 ++++++++++++++--------------- src/math_app.rs | 48 +++++++++++++++------------------------------- src/misc.rs | 14 ++++++++++---- src/suggestions.rs | 19 +++++++----------- src/widgets.rs | 6 +++--- 7 files changed, 56 insertions(+), 72 deletions(-) diff --git a/build.rs b/build.rs index 88d1742..0c229da 100644 --- a/build.rs +++ b/build.rs @@ -53,7 +53,7 @@ fn generate_hashmap() { .unwrap(); writeln!(&mut file, ";").unwrap(); - write!(&mut file, "const MAX_FUNC_LEN: usize = {};", max_len).unwrap(); + write!(&mut file, "const MAX_COMPLETION_LEN: usize = {};", max_len).unwrap(); } include!(concat!( diff --git a/src/consts.rs b/src/consts.rs index 5fecadb..10958b4 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -20,10 +20,11 @@ pub const BUILD_INFO: &str = formatc!( /// Range of acceptable input values for integral_num pub const INTEGRAL_NUM_RANGE: RangeInclusive = 1..=50000; + /// Minimum X value for calculating an Integral pub const INTEGRAL_X_MIN: f64 = -1000.0; -/// Maximum X value for calculating an Integral +/// Maximum X value for calculating an Integral pub const INTEGRAL_X_MAX: f64 = 1000.0; const_assert!(INTEGRAL_X_MAX > INTEGRAL_X_MIN); @@ -40,7 +41,6 @@ pub const DEFAULT_RIEMANN: Riemann = Riemann::Left; pub const DEFAULT_MIN_X: f64 = -10.0; /// Default Maxmimum X value to display - pub const DEFAULT_MAX_X: f64 = 10.0; const_assert!(DEFAULT_MAX_X > DEFAULT_MIN_X); @@ -48,7 +48,10 @@ const_assert!(DEFAULT_MAX_X > DEFAULT_MIN_X); /// Default number of integral boxes pub const DEFAULT_INTEGRAL_NUM: usize = 100; -pub const COLORS: &'static [Color32; 14] = &[ +/// Colors used for plotting +// Colors commented out are used elsewhere and are not included here for better +// user experience +pub const COLORS: &[Color32; 14] = &[ Color32::RED, // Color32::GREEN, // Color32::YELLOW, diff --git a/src/function.rs b/src/function.rs index f3485cb..3f2180f 100644 --- a/src/function.rs +++ b/src/function.rs @@ -90,14 +90,11 @@ impl Default for FunctionEntry { impl FunctionEntry { pub fn get_func_raw(&self) -> String { self.raw_func_str.to_string() } - pub fn auto_complete( - &mut self, ui: &mut egui::Ui, string: &mut String, i: i32, - ) -> (bool, bool, Option) { - let (output_string, in_focus) = self.autocomplete.ui(ui, string.to_string(), i); + pub fn auto_complete(&mut self, ui: &mut egui::Ui, i: i32) -> (bool, bool, Option) { + let (output_string, in_focus) = self.autocomplete.ui(ui, self.raw_func_str.clone(), i); - let changed = output_string != *string; + let changed = output_string != self.raw_func_str; if changed { - *string = output_string.clone(); self.update_string(&output_string); } @@ -390,17 +387,18 @@ impl FunctionEntry { } // Plot integral data - if let Some(integral_data) = &self.integral_data { - plot_ui.bar_chart( - BarChart::new(integral_data.0.clone()) - .color(Color32::BLUE) - .width(step), - ); + match &self.integral_data { + Some(integral_data) => { + plot_ui.bar_chart( + BarChart::new(integral_data.0.clone()) + .color(Color32::BLUE) + .width(step), + ); - // return value rounded to 8 decimal places - Some(crate::misc::decimal_round(integral_data.1, 8)) - } else { - None + // return value rounded to 8 decimal places + Some(crate::misc::decimal_round(integral_data.1, 8)) + } + _ => None, } } diff --git a/src/math_app.rs b/src/math_app.rs index 21064e7..072355e 100644 --- a/src/math_app.rs +++ b/src/math_app.rs @@ -276,6 +276,7 @@ impl Default for AppSettings { } } +/// Used to store the opened of windows/widgets struct Opened { pub help: bool, pub info: bool, @@ -299,13 +300,9 @@ pub struct MathApp { /// Stores vector of functions functions: Vec, - /// Stores vector containing the string representation of the functions. - /// This is used because of hacky reasons - func_strs: Vec, - /// Stores last error from parsing functions (used to display the same error /// when side panel is minimized) - func_errors: Vec>, + func_errors: Vec>, /// Stores whether or not an error is stored in `self.func_errors` exists_error: bool, @@ -331,7 +328,6 @@ impl Default for MathApp { fn default() -> Self { Self { functions: vec![DEFAULT_FUNCTION_ENTRY.clone()], - func_strs: vec![String::new()], func_errors: vec![None], exists_error: false, last_info: (vec![None], Duration::ZERO), @@ -502,41 +498,24 @@ impl MathApp { ); // Contains the function string in a text box that the user can edit - let (focused, changed, error) = - function.auto_complete(ui, &mut self.func_strs[i], i as i32); + let (focused, changed, error) = function.auto_complete(ui, i as i32); + if focused { self.text_boxes_focused = true; } - if error.is_some() { + if let Some(error_string) = error { self.exists_error = true; if changed { - self.func_errors[i] = - function.get_test_result().map(|error| (i, error)); + self.func_errors[i] = Some(error_string); } } }); - - // let func_failed = self.func_errors[i].is_some(); - // if func_failed { - // - // } - - // let update_result = function - // .update(&self.func_strs[i], integral_enabled, - // derivative_enabled) .map(|error| (i, error)); - - // if update_result.is_some() { - // self.exists_error = true; - // } - - // self.func_errors[i] = update_result } // Remove function if the user requests it if let Some(remove_i_unwrap) = remove_i { self.functions.remove(remove_i_unwrap); - self.func_strs.remove(remove_i_unwrap); self.func_errors.remove(remove_i_unwrap); } @@ -593,12 +572,14 @@ impl epi::App for MathApp { // Button to add a new function if ui - .add_enabled(14 > self.func_strs.len(), Button::new("Add Function")) + .add_enabled( + COLORS.len() > self.functions.len(), + Button::new("Add Function"), + ) .on_hover_text("Create and graph new function") .clicked() { self.functions.push(DEFAULT_FUNCTION_ENTRY.clone()); - self.func_strs.push(String::new()); self.func_errors.push(None); } @@ -713,10 +694,11 @@ impl epi::App for MathApp { ui.centered_and_justified(|ui| { self.func_errors .iter() - .filter(|ele| ele.is_some()) - .map(|ele| ele.as_ref().unwrap()) - .for_each(|ele| { - ui.heading(format!("(Function #{}) {}\n", ele.0, ele.1)); + .enumerate() + .filter(|(_, error)| error.is_some()) + .map(|(i, error)| (i, error.as_ref().unwrap())) + .for_each(|(i, error)| { + ui.heading(format!("(Function #{}) {}\n", i, error)); }) }); return; diff --git a/src/misc.rs b/src/misc.rs index 484c692..0e5d027 100644 --- a/src/misc.rs +++ b/src/misc.rs @@ -342,12 +342,18 @@ pub fn step_helper(max_i: usize, min_x: &f64, step: &f64) -> Vec { (0..max_i).map(|x| (x as f64 * step) + min_x).collect() } -pub fn chars_take(chars: &[char], i: usize) -> String { - if i > chars.len() { - panic!("chars_take: i is larget than chars.len()"); +pub fn chars_take(chars: &[char], take: usize) -> String { + let len = chars.len(); + assert!(len >= take); + if take == len { + // return `chars` turned into a string if `take == len` + return chars.iter().collect::(); + } else if take == 0 { + // return empty string if `take == 0` + return String::new(); } - chars.iter().rev().take(i).rev().collect::() + chars.iter().rev().take(take).rev().collect::() } #[cfg(test)] diff --git a/src/suggestions.rs b/src/suggestions.rs index bd015e8..f42e53a 100644 --- a/src/suggestions.rs +++ b/src/suggestions.rs @@ -6,7 +6,7 @@ pub fn generate_hint(input: &str) -> HintEnum<'static> { return HintEnum::Single("x^2"); } - let chars: Vec = input.chars().collect(); + let chars: Vec = input.chars().collect::>(); let mut open_parens: usize = 0; let mut closed_parens: usize = 0; @@ -22,8 +22,8 @@ pub fn generate_hint(input: &str) -> HintEnum<'static> { let len = chars.len(); - for i in (1..=MAX_FUNC_LEN).rev().filter(|i| len >= *i) { - if let Some(output) = get_completion(chars_take(&chars, i)) { + for i in (1..=MAX_COMPLETION_LEN).rev().filter(|i| len >= *i) { + if let Some(output) = get_completion(&chars_take(&chars, i)) { return output; } } @@ -72,13 +72,6 @@ impl ToString for HintEnum<'static> { } impl HintEnum<'static> { - pub fn get_single(&self) -> Option { - match self { - HintEnum::Single(x) => Some(x.to_string()), - _ => None, - } - } - pub fn is_some(&self) -> bool { !matches!(self, HintEnum::None) } pub fn is_none(&self) -> bool { !self.is_some() } @@ -87,12 +80,14 @@ impl HintEnum<'static> { include!(concat!(env!("OUT_DIR"), "/codegen.rs")); /// Gets completion from `COMPLETION_HASHMAP` -pub fn get_completion(key: String) -> Option> { +pub fn get_completion(key: &str) -> Option> { + // If key is empty, just return None if key.is_empty() { return None; } - COMPLETION_HASHMAP.get(&key).cloned() + // Get and clone the recieved data + COMPLETION_HASHMAP.get(key).cloned() } #[cfg(test)] diff --git a/src/widgets.rs b/src/widgets.rs index cda4a28..41adfea 100644 --- a/src/widgets.rs +++ b/src/widgets.rs @@ -55,9 +55,9 @@ impl AutoComplete { let enter_pressed = ui.input_mut().consume_key(Modifiers::NONE, Key::Enter); let tab_pressed = ui.input_mut().consume_key(Modifiers::NONE, Key::Tab); - if let Some(single_hint) = self.hint.get_single() { + if let HintEnum::Single(single_hint) = self.hint { let func_edit_2 = func_edit; - func_edit = func_edit_2.hint_text(&single_hint); + func_edit = func_edit_2.hint_text(single_hint); } let re = func_edit.id(te_id).ui(ui); @@ -71,7 +71,7 @@ impl AutoComplete { let push_cursor: bool = match self.hint { HintEnum::Single(hint) => { if apply_key { - new_string = string + &hint; + new_string += hint; true } else { false