diff --git a/Cargo.lock b/Cargo.lock index 9c531ab..3d93f61 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -663,7 +663,7 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "eframe" version = "0.18.0" -source = "git+https://github.com/Titaniumtown/egui.git#ffef46110abfe2d0c9891d3e457eccb1b8a75842" +source = "git+https://github.com/Titaniumtown/egui.git#16d09cfe61bd5c961d0eabdc964e91569d870979" dependencies = [ "bytemuck", "egui", @@ -683,7 +683,7 @@ dependencies = [ [[package]] name = "egui" version = "0.18.1" -source = "git+https://github.com/Titaniumtown/egui.git#ffef46110abfe2d0c9891d3e457eccb1b8a75842" +source = "git+https://github.com/Titaniumtown/egui.git#16d09cfe61bd5c961d0eabdc964e91569d870979" dependencies = [ "ahash", "epaint", @@ -694,7 +694,7 @@ dependencies = [ [[package]] name = "egui-winit" version = "0.18.0" -source = "git+https://github.com/Titaniumtown/egui.git#ffef46110abfe2d0c9891d3e457eccb1b8a75842" +source = "git+https://github.com/Titaniumtown/egui.git#16d09cfe61bd5c961d0eabdc964e91569d870979" dependencies = [ "arboard", "egui", @@ -707,7 +707,7 @@ dependencies = [ [[package]] name = "egui_glow" version = "0.18.0" -source = "git+https://github.com/Titaniumtown/egui.git#ffef46110abfe2d0c9891d3e457eccb1b8a75842" +source = "git+https://github.com/Titaniumtown/egui.git#16d09cfe61bd5c961d0eabdc964e91569d870979" dependencies = [ "bytemuck", "egui", @@ -727,7 +727,7 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "emath" version = "0.18.0" -source = "git+https://github.com/Titaniumtown/egui.git#ffef46110abfe2d0c9891d3e457eccb1b8a75842" +source = "git+https://github.com/Titaniumtown/egui.git#16d09cfe61bd5c961d0eabdc964e91569d870979" dependencies = [ "bytemuck", ] @@ -735,7 +735,7 @@ dependencies = [ [[package]] name = "epaint" version = "0.18.1" -source = "git+https://github.com/Titaniumtown/egui.git#ffef46110abfe2d0c9891d3e457eccb1b8a75842" +source = "git+https://github.com/Titaniumtown/egui.git#16d09cfe61bd5c961d0eabdc964e91569d870979" dependencies = [ "ab_glyph", "ahash", @@ -1959,7 +1959,7 @@ dependencies = [ [[package]] name = "ruzstd" version = "0.2.4" -source = "git+https://github.com/Titaniumtown/zstd-rs.git?branch=ringbuffer#d7f5caaf23146cd525a2a215241661ecf0aa073a" +source = "git+https://github.com/Titaniumtown/zstd-rs.git?branch=ringbuffer#5acbe502b4047eb1d02c8a338d725ead806635de" dependencies = [ "byteorder", "twox-hash", diff --git a/parsing/src/autocomplete_helper.rs b/parsing/src/autocomplete_helper.rs index 10e861d..ea6147d 100644 --- a/parsing/src/autocomplete_helper.rs +++ b/parsing/src/autocomplete_helper.rs @@ -11,7 +11,7 @@ fn compare_len_reverse_alpha(a: &String, b: &String) -> Ordering { /// Generates hashmap (well really a vector of tuple of strings that are then turned into a hashmap by phf) #[allow(dead_code)] -pub fn compile_hashmap(data: Vec) -> Vec<(String, String)> { +pub(crate) fn compile_hashmap(data: Vec) -> Vec<(String, String)> { let mut seen = HashSet::new(); let tuple_list_1: Vec<(String, String)> = data diff --git a/parsing/src/lib.rs b/parsing/src/lib.rs index 1b73b11..ee1b1fe 100644 --- a/parsing/src/lib.rs +++ b/parsing/src/lib.rs @@ -1,5 +1,6 @@ #![feature(const_trait_impl)] #![feature(core_intrinsics)] +#![feature(const_default_impls)] pub mod parsing; pub mod suggestions; diff --git a/parsing/src/parsing.rs b/parsing/src/parsing.rs index 32da2ca..6b9e42b 100644 --- a/parsing/src/parsing.rs +++ b/parsing/src/parsing.rs @@ -8,44 +8,33 @@ pub struct FlatExWrapper { impl FlatExWrapper { const EMPTY: FlatExWrapper = FlatExWrapper { func: None }; - fn new(f: FlatEx) -> Self { Self { func: Some(f) } } + const fn new(f: FlatEx) -> Self { Self { func: Some(f) } } fn eval(&self, x: &[f64]) -> f64 { - if let Some(ref f) = self.func { - f.eval(x).unwrap_or(f64::NAN) - } else { - f64::NAN - } + self.func + .as_ref() + .map(|f| f.eval(x).unwrap_or(f64::NAN)) + .unwrap_or(f64::NAN) } fn partial(&self, x: usize) -> Self { - if let Some(ref f) = self.func { - match f.partial(x) { - Ok(a) => Self::new(a), - Err(_) => Self::EMPTY, - } - } else { - Self::EMPTY - } + self.func + .as_ref() + .map(|f| f.partial(x).map(|a| Self::new(a)).unwrap_or(Self::EMPTY)) + .unwrap_or(Self::EMPTY) } - fn get_string(&self) -> &str { - if let Some(ref f) = self.func { - f.unparse() - } else { - "" - } - } + fn get_string(&self) -> &str { self.func.as_ref().map(|f| f.unparse()).unwrap_or("") } fn partial_iter(&self, x: &[usize]) -> Self { - if let Some(ref f) = self.func { - match f.partial_iter(x.iter()) { - Ok(a) => Self::new(a), - Err(_) => Self::EMPTY, - } - } else { - Self::EMPTY - } + self.func + .as_ref() + .map(|f| { + f.partial_iter(x.iter()) + .map(|a| Self::new(a)) + .unwrap_or(Self::EMPTY) + }) + .unwrap_or(Self::EMPTY) } } @@ -58,18 +47,23 @@ impl const Default for FlatExWrapper { pub struct BackingFunction { /// f(x) function: FlatExWrapper, + /// f'(x) derivative_1: FlatExWrapper, + /// Mathematical representation of f'(x) derivative_1_str: String, + /// f''(x) derivative_2: FlatExWrapper, + /// Temporary cache for nth derivative nth_derivative: Option<(usize, FlatExWrapper, String)>, } impl BackingFunction { - const EMPTY: BackingFunction = BackingFunction { + /// Empty [`BackingFunction`] instance + pub const EMPTY: BackingFunction = BackingFunction { function: FlatExWrapper::EMPTY, derivative_1: FlatExWrapper::EMPTY, derivative_1_str: String::new(), @@ -139,6 +133,7 @@ impl BackingFunction { /// Calculate f''(x) pub fn get_derivative_2(&self, x: f64) -> f64 { self.derivative_2.eval(&[x]) } + /// Get string relating to the nth derivative pub fn get_nth_derivative_str(&self) -> &str { &self.nth_derivative.as_ref().unwrap().2 } pub fn get_nth_derivative(&mut self, n: usize, x: f64) -> f64 { @@ -168,7 +163,7 @@ impl BackingFunction { } fn prettyify_function_str(func: &str) -> String { - let new_str = func.to_owned().replace("{x}", "x"); + let new_str = func.replace("{x}", "x"); if &new_str == "0/0" { "Undefined".to_owned() @@ -177,10 +172,10 @@ fn prettyify_function_str(func: &str) -> String { } } -pub const VALID_VARIABLES: [char; 5] = ['x', 'X', 'e', 'E', 'π']; +pub const VALID_VARIABLES: [char; 3] = ['x', 'e', 'π']; #[inline] -pub fn is_variable(c: &char) -> bool { VALID_VARIABLES.contains(&c) } +pub fn is_variable(c: &char) -> bool { VALID_VARIABLES.contains(&c.to_ascii_lowercase()) } /// Adds asterisks where needed in a function pub fn process_func_str(function_in: &str) -> String { diff --git a/parsing/src/suggestions.rs b/parsing/src/suggestions.rs index 103aa1b..ede714c 100644 --- a/parsing/src/suggestions.rs +++ b/parsing/src/suggestions.rs @@ -19,7 +19,7 @@ pub fn split_function(input: &str) -> Vec { &input .replace("pi", "π") // replace "pi" text with pi symbol .replace("**", "^") // support alternate manner of expressing exponents - .replace("exp", "\u{1fc93}") //stop-gap solution to fix the `exp` function + .replace("exp", "\u{1fc93}") // stop-gap solution to fix the `exp` function .chars() .collect::>(), ) @@ -64,7 +64,7 @@ pub fn split_function_chars(chars: &[char]) -> Vec { let isnumber = c.is_ascii_digit(); let isvariable = is_variable(c); Self { - closing_parens: c == &')', + closing_parens: *c == ')', number: isnumber, letter: c.is_ascii_alphabetic(), variable: isvariable, diff --git a/src/function_entry.rs b/src/function_entry.rs index 0a7934c..2a6b07e 100644 --- a/src/function_entry.rs +++ b/src/function_entry.rs @@ -30,11 +30,6 @@ impl fmt::Display for Riemann { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self) } } -lazy_static::lazy_static! { - /// Represents a "default" instance of `FunctionEntry` - pub static ref DEFAULT_FUNCTION_ENTRY: FunctionEntry = FunctionEntry::default(); -} - /// `FunctionEntry` is a function that can calculate values, integrals, derivatives, etc etc #[derive(Clone)] pub struct FunctionEntry { @@ -71,11 +66,11 @@ pub struct FunctionEntry { pub settings_opened: bool, } -impl Default for FunctionEntry { +impl const Default for FunctionEntry { /// Creates default FunctionEntry instance (which is empty) fn default() -> FunctionEntry { FunctionEntry { - function: BackingFunction::new("").unwrap(), + function: BackingFunction::EMPTY, raw_func_str: String::new(), min_x: -1.0, max_x: 1.0, diff --git a/src/function_manager.rs b/src/function_manager.rs index 35a6fa1..55ef612 100644 --- a/src/function_manager.rs +++ b/src/function_manager.rs @@ -1,7 +1,7 @@ use crate::consts::is_mobile; -use crate::function_entry::{FunctionEntry, DEFAULT_FUNCTION_ENTRY}; +use crate::function_entry::FunctionEntry; use crate::widgets::{move_cursor_to_end, widgets_ontop, Movement}; -use egui::{Button, Key, Modifiers, RichText, WidgetText}; +use egui::{Button, Key, Modifiers, WidgetText}; use emath::vec2; use parsing::suggestions::Hint; use std::ops::BitXorAssign; @@ -14,11 +14,16 @@ pub struct FunctionManager { impl Default for FunctionManager { fn default() -> Self { Self { - functions: vec![(Uuid::new_v4(), DEFAULT_FUNCTION_ENTRY.clone())], + functions: vec![(Uuid::new_v4(), FunctionEntry::default())], } } } +/// Function that creates button that's used with the `button_area` +const fn button_area_button(text: impl Into) -> Button { + Button::new(text).frame(false) +} + impl FunctionManager { pub fn display_entries(&mut self, ui: &mut egui::Ui) { // ui.label("Functions:"); @@ -127,11 +132,6 @@ impl FunctionManager { } } - /// Function that creates button that's used with the `button_area` - const fn button_area_button(text: String) -> Button { - Button::new_const(WidgetText::RichText(RichText::new_const(text))).frame(false) - } - /// The y offset multiplier of the `buttons_area` area const BUTTONS_Y_OFFSET: f32 = 1.32; @@ -144,7 +144,7 @@ impl FunctionManager { ui.horizontal(|ui| { // There's more than 1 function! Functions can now be deleted if ui - .add_enabled(can_remove, button_area_button("✖".to_owned())) + .add_enabled(can_remove, button_area_button("✖")) .on_hover_text("Delete Function") .clicked() { @@ -153,7 +153,7 @@ impl FunctionManager { // Toggle integral being enabled or not function.integral.bitxor_assign( - ui.add(button_area_button("∫".to_owned())) + ui.add(button_area_button("∫")) .on_hover_text(match function.integral { true => "Don't integrate", false => "Integrate", @@ -163,7 +163,7 @@ impl FunctionManager { // Toggle showing the derivative (even though it's already calculated this option just toggles if it's displayed or not) function.derivative.bitxor_assign( - ui.add(button_area_button("d/dx".to_owned())) + ui.add(button_area_button("d/dx")) .on_hover_text(match function.derivative { true => "Don't Differentiate", false => "Differentiate", @@ -194,7 +194,7 @@ impl FunctionManager { pub fn new_function(&mut self) { self.functions - .push((Uuid::new_v4(), DEFAULT_FUNCTION_ENTRY.clone())); + .push((Uuid::new_v4(), FunctionEntry::default())); } pub fn any_using_integral(&self) -> bool { diff --git a/src/lib.rs b/src/lib.rs index 06fcfa2..e04894f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,8 @@ #![feature(stmt_expr_attributes)] #![feature(const_trait_impl)] #![feature(core_intrinsics)] +#![feature(const_convert)] +#![feature(const_default_impls)] #[macro_use] extern crate static_assertions; diff --git a/src/math_app.rs b/src/math_app.rs index 1a95920..a99fac5 100644 --- a/src/math_app.rs +++ b/src/math_app.rs @@ -63,7 +63,7 @@ pub struct AppSettings { pub plot_width: usize, } -impl Default for AppSettings { +impl const Default for AppSettings { /// Default implementation of `AppSettings`, this is how the application /// starts up fn default() -> Self { @@ -88,7 +88,7 @@ struct Opened { pub welcome: bool, } -impl Default for Opened { +impl const Default for Opened { fn default() -> Opened { Self { help: false,