MAJOR refactoring

This commit is contained in:
Simon Gardling 2022-05-03 11:50:13 -04:00
parent 8952552eef
commit 13a47ec30b
12 changed files with 243 additions and 218 deletions

View File

@ -42,3 +42,8 @@ jobs:
crate: cargo-all-features
version: latest
- run: cargo test-all-features
- name: Test Parsing
uses: actions-rs/cargo@v1
with:
command: check --package parsing

164
Cargo.lock generated
View File

@ -484,20 +484,28 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
[[package]]
name = "eframe"
version = "0.17.0"
source = "git+https://github.com/Titaniumtown/egui.git#0e8e8b76a042115498449c9da8e0f2ccae87df82"
version = "0.18.0"
source = "git+https://github.com/Titaniumtown/egui.git#f2321e8a7cbfb11e0f076edbdd62e95528409ca1"
dependencies = [
"bytemuck",
"egui",
"egui-winit",
"egui_glow",
"egui_web",
"epi",
"glow",
"glutin",
"js-sys",
"percent-encoding",
"tracing",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"winit",
]
[[package]]
name = "egui"
version = "0.17.0"
source = "git+https://github.com/Titaniumtown/egui.git#0e8e8b76a042115498449c9da8e0f2ccae87df82"
version = "0.18.1"
source = "git+https://github.com/Titaniumtown/egui.git#f2321e8a7cbfb11e0f076edbdd62e95528409ca1"
dependencies = [
"ahash",
"epaint",
@ -507,13 +515,11 @@ dependencies = [
[[package]]
name = "egui-winit"
version = "0.17.0"
source = "git+https://github.com/Titaniumtown/egui.git#0e8e8b76a042115498449c9da8e0f2ccae87df82"
version = "0.18.0"
source = "git+https://github.com/Titaniumtown/egui.git#f2321e8a7cbfb11e0f076edbdd62e95528409ca1"
dependencies = [
"arboard",
"egui",
"epi",
"glow",
"instant",
"tracing",
"webbrowser",
@ -522,38 +528,18 @@ dependencies = [
[[package]]
name = "egui_glow"
version = "0.17.0"
source = "git+https://github.com/Titaniumtown/egui.git#0e8e8b76a042115498449c9da8e0f2ccae87df82"
version = "0.18.0"
source = "git+https://github.com/Titaniumtown/egui.git#f2321e8a7cbfb11e0f076edbdd62e95528409ca1"
dependencies = [
"bytemuck",
"egui",
"egui-winit",
"epi",
"glow",
"glutin",
"memoffset",
"tracing",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "egui_web"
version = "0.17.0"
source = "git+https://github.com/Titaniumtown/egui.git#0e8e8b76a042115498449c9da8e0f2ccae87df82"
dependencies = [
"bytemuck",
"egui",
"egui_glow",
"epi",
"js-sys",
"percent-encoding",
"tracing",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]]
name = "either"
version = "1.6.1"
@ -562,16 +548,16 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "emath"
version = "0.17.0"
source = "git+https://github.com/Titaniumtown/egui.git#0e8e8b76a042115498449c9da8e0f2ccae87df82"
version = "0.18.0"
source = "git+https://github.com/Titaniumtown/egui.git#f2321e8a7cbfb11e0f076edbdd62e95528409ca1"
dependencies = [
"bytemuck",
]
[[package]]
name = "epaint"
version = "0.17.0"
source = "git+https://github.com/Titaniumtown/egui.git#0e8e8b76a042115498449c9da8e0f2ccae87df82"
version = "0.18.1"
source = "git+https://github.com/Titaniumtown/egui.git#f2321e8a7cbfb11e0f076edbdd62e95528409ca1"
dependencies = [
"ab_glyph",
"ahash",
@ -582,16 +568,6 @@ dependencies = [
"parking_lot 0.12.0",
]
[[package]]
name = "epi"
version = "0.17.0"
source = "git+https://github.com/Titaniumtown/egui.git#0e8e8b76a042115498449c9da8e0f2ccae87df82"
dependencies = [
"egui",
"glow",
"tracing",
]
[[package]]
name = "error-code"
version = "2.3.1"
@ -610,8 +586,8 @@ checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71"
[[package]]
name = "exmex"
version = "0.15.0"
source = "git+https://github.com/bertiqwerty/exmex.git?branch=main#4f34fb927246009b6b716b5ba8e35f045d27c239"
version = "0.16.0"
source = "git+https://github.com/bertiqwerty/exmex.git?branch=main#a854d7af15d2bb65ec0c62b60f104640c70da5b3"
dependencies = [
"lazy_static",
"num",
@ -681,7 +657,7 @@ dependencies = [
"cfg-if 1.0.0",
"js-sys",
"libc",
"wasi 0.10.2+wasi-snapshot-preview1",
"wasi 0.10.0+wasi-snapshot-preview1",
"wasm-bindgen",
]
@ -904,9 +880,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.124"
version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50"
checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
[[package]]
name = "libgit2-sys"
@ -954,9 +930,9 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.16"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if 1.0.0",
]
@ -978,9 +954,9 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]]
name = "memchr"
version = "2.4.1"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "memmap2"
@ -1190,18 +1166,18 @@ dependencies = [
[[package]]
name = "num-complex"
version = "0.4.0"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085"
checksum = "97fbc387afefefd5e9e39493299f3069e14a140dd34dc19b4c1c1a8fddb6a790"
dependencies = [
"num-traits",
]
[[package]]
name = "num-integer"
version = "0.1.44"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
dependencies = [
"autocfg",
"num-traits",
@ -1232,9 +1208,9 @@ dependencies = [
[[package]]
name = "num-traits"
version = "0.2.14"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [
"autocfg",
]
@ -1351,7 +1327,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58"
dependencies = [
"lock_api",
"parking_lot_core 0.9.2",
"parking_lot_core 0.9.3",
]
[[package]]
@ -1370,9 +1346,9 @@ dependencies = [
[[package]]
name = "parking_lot_core"
version = "0.9.2"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37"
checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929"
dependencies = [
"cfg-if 1.0.0",
"libc",
@ -1573,7 +1549,7 @@ checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "ruzstd"
version = "0.2.4"
source = "git+https://github.com/KillingSpark/zstd-rs.git#66d02e41e8f88aac3f39e6f6a9ef4320073d9431"
source = "git+https://github.com/Titaniumtown/zstd-rs.git?branch=ringbuffer#d7f5caaf23146cd525a2a215241661ecf0aa073a"
dependencies = [
"byteorder",
"twox-hash",
@ -1608,15 +1584,15 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
version = "1.0.136"
version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
[[package]]
name = "serde_json"
version = "1.0.79"
version = "1.0.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95"
checksum = "f972498cf015f7c0746cac89ebe1d6ef10c293b94175a243a2d9442c163d9944"
dependencies = [
"itoa",
"ryu",
@ -1714,9 +1690,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "1.0.91"
version = "1.0.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d"
checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52"
dependencies = [
"proc-macro2",
"quote",
@ -1736,18 +1712,18 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.30"
version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.30"
version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
dependencies = [
"proc-macro2",
"quote",
@ -1765,11 +1741,12 @@ dependencies = [
[[package]]
name = "time"
version = "0.1.43"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
"wasi 0.10.0+wasi-snapshot-preview1",
"winapi",
]
@ -1899,9 +1876,9 @@ dependencies = [
[[package]]
name = "unicode-xid"
version = "0.2.2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
[[package]]
name = "url"
@ -1956,9 +1933,9 @@ dependencies = [
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "wasi"
@ -2199,9 +2176,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.34.0"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825"
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
dependencies = [
"windows_aarch64_msvc",
"windows_i686_gnu",
@ -2212,33 +2189,33 @@ dependencies = [
[[package]]
name = "windows_aarch64_msvc"
version = "0.34.0"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d"
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
[[package]]
name = "windows_i686_gnu"
version = "0.34.0"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed"
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
[[package]]
name = "windows_i686_msvc"
version = "0.34.0"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956"
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
[[package]]
name = "windows_x86_64_gnu"
version = "0.34.0"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4"
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
[[package]]
name = "windows_x86_64_msvc"
version = "0.34.0"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9"
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
[[package]]
name = "winit"
@ -2333,7 +2310,6 @@ dependencies = [
"egui",
"emath",
"epaint",
"epi",
"instant",
"itertools",
"lazy_static",

View File

@ -17,7 +17,7 @@ debug = false
codegen-units = 1
opt-level = "z" #optimize for size
#lto = "fat" #causes issues with wasm, disabling for the time being
strip = true
strip = false
panic = "abort"
[profile.dev]
@ -33,7 +33,6 @@ parsing = { path = "./parsing" }
eframe = { git = "https://github.com/Titaniumtown/egui.git", default-features = false }
egui = { git = "https://github.com/Titaniumtown/egui.git", default-features = false }
epaint = { git = "https://github.com/Titaniumtown/egui.git", default-features = false }
epi = { git = "https://github.com/Titaniumtown/egui.git", default-features = false }
emath = { git = "https://github.com/Titaniumtown/egui.git", default-features = false }
shadow-rs = { version = "0.11", default-features = false }
@ -41,7 +40,7 @@ const_format = { version = "0.2", default-features = false, features = ["fmt"] }
cfg-if = "1"
lazy_static = "1"
tar = "0.4"
ruzstd = { git = "https://github.com/KillingSpark/zstd-rs.git" }
ruzstd = { git = "https://github.com/Titaniumtown/zstd-rs.git", branch = "ringbuffer" }
serde_json = "1.0"
tracing = "0.1"
itertools = "0.10"

View File

@ -1,2 +1,4 @@
#![feature(const_trait_impl)]
pub mod parsing;
pub mod suggestions;

View File

@ -150,95 +150,11 @@ pub fn is_number(c: &char) -> bool { NUMBERS.contains(&c) }
/// In the future I may want to completely rewrite this or implement this natively in exmex.
// TODO: use `split_function` here instead of this janky code
pub fn process_func_str(function_in: &str) -> String {
let function = function_in
.replace("log10(", "log(") // log10 -> log
.replace("pi", "π") // pi -> π
.replace("exp", "\u{1fc93}") // replace 'exp' with this random unicode character because it can't be parsed correctly
.replace("**", "^"); // alternate exponential representation
let function_chars: Vec<char> = function.chars().collect();
let mut output_string: String = String::new();
for (i, c) in function_chars.iter().enumerate() {
let mut add_asterisk: bool = false;
let prev_prev_prev_char = if i > 2 {
*function_chars.get(i - 3).unwrap()
} else {
' '
};
let prev_prev_char = if i > 1 {
*function_chars.get(i - 2).unwrap()
} else {
' '
};
let prev_char = if i > 0 {
*function_chars.get(i - 1).unwrap()
} else {
' '
};
let c_is_number = is_number(c);
let c_is_letter = is_letter(c);
let c_is_variable = is_variable(c);
let prev_char_is_variable = is_variable(&prev_char);
let prev_char_is_number = is_number(&prev_char);
// makes special case for log with base of a 1-2 digit number
if ((prev_prev_prev_char == 'l')
&& (prev_prev_char == 'o')
&& (prev_char == 'g')
&& c_is_number)
| ((prev_prev_char == 'c') && (prev_char == 'e') && (*c == 'i'))
{
output_string += &c.to_string();
continue;
}
let c_letters_var = c_is_letter | c_is_variable;
let prev_letters_var = prev_char_is_variable | is_letter(&prev_char);
if prev_char == ')' {
// cases like `)x`, `)2`, and `)(`
if c_letters_var | c_is_number | (*c == '(') {
add_asterisk = true;
}
} else if *c == '(' {
// cases like `x(` and `2(`
if (prev_char_is_variable | prev_char_is_number) && !is_letter(&prev_prev_char) {
add_asterisk = true;
}
} else if prev_char_is_number {
// cases like `2x` and `2sin(x)`
if c_letters_var {
add_asterisk = true;
}
} else if c_is_letter {
// cases like `e2` and `xx`
if prev_char_is_number
| (prev_char_is_variable && c_is_variable)
| prev_char_is_variable
| (prev_char == 'π')
{
add_asterisk = true;
}
} else if (c_is_number | c_letters_var) && prev_letters_var {
// cases like `x2` and `xx`
add_asterisk = true;
}
// if add_asterisk is true, add the asterisk
if add_asterisk {
output_string += "*";
}
// push current char to `output_string` (which is eventually returned)
output_string += &c.to_string();
if function_in.is_empty() {
return String::new();
}
output_string
.replace("log(", "log10(")
.replace('\u{1fc93}', "exp")
crate::suggestions::split_function(&function_in).join("*")
}
#[cfg(test)]
@ -326,6 +242,7 @@ mod tests {
("pisin(x)", "π*sin(x)"),
("e^sin(x)", "e^sin(x)"),
("x**2", "x^2"),
("(x+1)(x-3)", "(x+1)*(x-3)"),
]);
for (key, value) in values {

View File

@ -1,4 +1,4 @@
use crate::parsing::is_number;
use crate::parsing::{is_letter, is_number, is_variable};
pub const HINT_EMPTY: Hint = Hint::Single("x^2");
const HINT_CLOSED_PARENS: Hint = Hint::Single(")");
@ -13,7 +13,17 @@ macro_rules! test_print {
}
pub fn split_function(input: &str) -> Vec<String> {
split_function_chars(&input.chars().collect::<Vec<char>>())
split_function_chars(
&input
.replace("pi", "π")
.replace("**", "^")
.replace("exp", "\u{1fc93}")
.chars()
.collect::<Vec<char>>(),
)
.iter()
.map(|x| x.replace("\u{1fc93}", "exp"))
.collect::<Vec<String>>()
}
fn split_function_chars(chars: &[char]) -> Vec<String> {
@ -22,19 +32,120 @@ fn split_function_chars(chars: &[char]) -> Vec<String> {
let mut split: Vec<String> = Vec::new();
let mut buffer: Vec<char> = Vec::new();
#[derive(Default)]
struct BoolSlice {
closing_parens: bool,
number: bool,
letter: bool,
variable: bool,
masked_num: bool,
masked_var: bool,
exists: bool,
}
impl BoolSlice {
#[inline]
fn is_variable(&self) -> bool { self.variable && !self.masked_var }
#[inline]
fn is_number(&self) -> bool { self.number && !self.masked_num }
}
let mut prev_char: BoolSlice = BoolSlice::default();
for c in chars {
buffer.push(*c);
if *c == ')' {
split.push(buffer.iter().collect::<String>());
buffer.clear();
continue;
}
let mut curr_c = BoolSlice {
closing_parens: c == &')',
number: is_number(c),
letter: is_letter(c),
variable: is_variable(c),
masked_num: if is_number(c) {
prev_char.masked_num
} else {
false
},
masked_var: if is_variable(c) {
prev_char.masked_var
} else {
false
},
exists: true,
};
let buffer_string = buffer.iter().collect::<String>();
if ((&buffer_string == "log") | (&buffer_string == "log1")) && is_number(&c) {
continue;
// Check if prev_char is valid
if prev_char.exists {
// if previous char was a masked number, and current char is a number, mask current char's variable status
if prev_char.masked_num && curr_c.number {
curr_c.masked_num = true;
}
// if previous char was a masked variable, and current char is a variable, mask current char's variable status
if prev_char.masked_var && curr_c.variable {
curr_c.masked_var = true;
}
// if letter and not a variable (or a masked variable)
if prev_char.letter && !(prev_char.variable && !prev_char.masked_var) {
// mask number status if current char is number
if curr_c.number {
curr_c.masked_num = true;
}
// mask variable status if current char is a variable
if curr_c.variable {
curr_c.masked_var = true;
}
}
}
let mut do_split = false;
if prev_char.closing_parens {
// cases like `)x`, `)2`, and `)(`
if (c == &'(')
| (curr_c.letter && !curr_c.is_variable())
| curr_c.is_variable()
| curr_c.is_number()
{
do_split = true;
}
} else if c == &'(' {
// cases like `x(` and `2(`
if (prev_char.is_variable() | prev_char.is_number()) && !prev_char.letter {
do_split = true;
}
} else if prev_char.is_number() {
// cases like `2x` and `2sin(x)`
if curr_c.is_variable() | curr_c.letter {
do_split = true;
}
} else if curr_c.is_variable() | curr_c.letter {
// cases like `e2` and `xx`
if prev_char.is_number()
| (prev_char.is_variable() && curr_c.is_variable())
| prev_char.is_variable()
{
do_split = true;
}
} else if (curr_c.is_number() | curr_c.letter | curr_c.is_variable())
&& (prev_char.is_number() | prev_char.letter)
{
// cases like `x2` and `xx`
do_split = true;
} else if curr_c.is_number() && prev_char.is_variable() {
do_split = true;
}
// split and append buffer
if do_split {
split.push(buffer_string);
buffer.clear();
}
buffer.push(*c);
prev_char = curr_c;
}
if !buffer.is_empty() {
@ -75,10 +186,6 @@ pub enum Hint<'a> {
None,
}
impl<'a> std::fmt::Debug for Hint<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self) }
}
impl<'a> std::fmt::Display for Hint<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
@ -95,6 +202,12 @@ impl<'a> std::fmt::Display for Hint<'a> {
}
}
impl<'a> std::fmt::Debug for Hint<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::Display::fmt(self, f)
}
}
impl<'a> Hint<'a> {
pub fn is_none(&self) -> bool { matches!(self, Hint::None) }
@ -163,11 +276,17 @@ mod tests {
.flatten()
.filter(|func| !SUPPORTED_FUNCTIONS.contains(&func.as_str()))
.for_each(|key| {
println!("{}", key);
if super::generate_hint(&key).is_none() {
let split = super::split_function(&key);
if split.len() != 1 {
panic!("failed: {} (len: {}, split: {:?})", key, split.len(), split);
}
let generated_hint = super::generate_hint(&key);
if generated_hint.is_none() {
println!("success: {}", key);
} else {
panic!("failed: {}", key);
panic!("failed: {} (Hint: '{}')", key, generated_hint.to_string());
}
});
}
@ -179,6 +298,7 @@ mod tests {
("cos(", vec!["cos("]),
("cos(x)sin(x)", vec!["cos(x)", "sin(x)"]),
("aaaaaaaaaaa", vec!["aaaaaaaaaaa"]),
("emax(x)", vec!["e", "max(x)"]),
]);
for (key, value) in values {

View File

@ -1,7 +1,7 @@
use crate::consts::is_mobile;
use crate::function_entry::{FunctionEntry, DEFAULT_FUNCTION_ENTRY};
use crate::widgets::{move_cursor_to_end, widgets_ontop, Movement};
use egui::{Button, Key, Modifiers};
use egui::{Button, Key, Modifiers, RichText, WidgetText};
use emath::vec2;
use parsing::suggestions::Hint;
use std::ops::BitXorAssign;
@ -128,8 +128,8 @@ impl FunctionManager {
}
/// Function that creates button that's used with the `button_area`
fn button_area_button(text: impl Into<egui::WidgetText>) -> Button {
Button::new(text.into()).frame(false)
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
@ -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(""))
.add_enabled(can_remove, button_area_button("".to_owned()))
.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(""))
ui.add(button_area_button("".to_owned()))
.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"))
ui.add(button_area_button("d/dx".to_owned()))
.on_hover_text(match function.derivative {
true => "Don't Differentiate",
false => "Differentiate",
@ -172,7 +172,7 @@ impl FunctionManager {
);
function.settings_opened.bitxor_assign(
ui.add(button_area_button(""))
ui.add(button_area_button("".to_owned()))
.on_hover_text(match function.settings_opened {
true => "Close Settings",
false => "Open Settings",

View File

@ -1,6 +1,7 @@
#![feature(const_mut_refs)]
#![feature(let_chains)]
#![feature(stmt_expr_attributes)]
#![feature(const_trait_impl)]
#[macro_use]
extern crate static_assertions;

View File

@ -1,6 +1,7 @@
#![feature(const_mut_refs)]
#![feature(let_chains)]
#![feature(stmt_expr_attributes)]
#![feature(const_trait_impl)]
#[macro_use]
extern crate static_assertions;

View File

@ -2,6 +2,7 @@ use crate::consts::*;
use crate::function_entry::Riemann;
use crate::function_manager::FunctionManager;
use crate::misc::{dyn_mut_iter, option_vec_printer, TextData};
use eframe::App;
use egui::{
plot::Plot, style::Margin, vec2, Button, CentralPanel, Color32, ComboBox, Context, FontData,
FontDefinitions, FontFamily, Frame, Key, RichText, SidePanel, Slider, TopBottomPanel, Vec2,
@ -136,8 +137,6 @@ impl MathApp {
#[cfg(not(threading))]
tracing::info!("Threading: Disabled");
tracing::info!("Integration name: {}", cc.integration_info.name);
if let Some(web_info) = &cc.integration_info.web_info {
tracing::info!("Web Info: {:?}", web_info);
}
@ -382,9 +381,9 @@ impl MathApp {
}
}
impl epi::App for MathApp {
impl App for MathApp {
/// Called each time the UI needs repainting.
fn update(&mut self, ctx: &Context, _frame: &mut epi::Frame) {
fn update(&mut self, ctx: &Context, _frame: &mut eframe::Frame) {
// start timer
let start = if self.opened.info {
Some(instant::Instant::now())

View File

@ -298,7 +298,7 @@ where
.map(|x| {
x.as_ref()
.map(|x_1| x_1.to_string())
.unwrap_or_else(|| "None".to_string())
.unwrap_or_else(|| "None".to_owned())
})
.enumerate()
.map(|(i, x)| {

View File

@ -10,7 +10,7 @@ pub enum Movement {
None,
}
impl Default for Movement {
impl const Default for Movement {
fn default() -> Self { Self::None }
}
@ -21,7 +21,7 @@ pub struct AutoComplete<'a> {
pub string: String,
}
impl<'a> Default for AutoComplete<'a> {
impl<'a> const Default for AutoComplete<'a> {
fn default() -> AutoComplete<'a> {
AutoComplete {
i: 0,
@ -34,9 +34,14 @@ impl<'a> Default for AutoComplete<'a> {
impl<'a> AutoComplete<'a> {
pub fn update_string(&mut self, string: &str) {
if self.string != string {
self.i = 0;
self.string = string.to_string();
self.hint = generate_hint(string);
// catch empty strings here to avoid call to `generate_hint` and unnecessary logic
if string.is_empty() {
*self = Self::default();
} else {
self.i = 0;
self.string = string.to_string();
self.hint = generate_hint(string);
}
}
}