code improvements
This commit is contained in:
112
parsing/src/autocomplete.rs
Normal file
112
parsing/src/autocomplete.rs
Normal file
@@ -0,0 +1,112 @@
|
||||
use std::intrinsics::assume;
|
||||
|
||||
use crate::{generate_hint, Hint, HINT_EMPTY};
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub enum Movement {
|
||||
Complete,
|
||||
#[allow(dead_code)]
|
||||
Down,
|
||||
#[allow(dead_code)]
|
||||
Up,
|
||||
None,
|
||||
}
|
||||
|
||||
impl Movement {
|
||||
pub const fn is_none(&self) -> bool { matches!(&self, &Self::None) }
|
||||
|
||||
pub const fn is_complete(&self) -> bool { matches!(&self, &Self::Complete) }
|
||||
}
|
||||
|
||||
impl const Default for Movement {
|
||||
fn default() -> Self { Self::None }
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct AutoComplete<'a> {
|
||||
pub i: usize,
|
||||
pub hint: &'a Hint<'a>,
|
||||
pub string: String,
|
||||
}
|
||||
|
||||
impl<'a> const Default for AutoComplete<'a> {
|
||||
fn default() -> AutoComplete<'a> { AutoComplete::EMPTY }
|
||||
}
|
||||
|
||||
impl<'a> AutoComplete<'a> {
|
||||
const EMPTY: AutoComplete<'a> = Self {
|
||||
i: 0,
|
||||
hint: &HINT_EMPTY,
|
||||
string: String::new(),
|
||||
};
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn update_string(&mut self, string: &str) {
|
||||
if self.string != string {
|
||||
// catch empty strings here to avoid call to `generate_hint` and unnecessary logic
|
||||
if string.is_empty() {
|
||||
*self = Self::EMPTY;
|
||||
} else {
|
||||
self.string = string.to_owned();
|
||||
self.do_update_logic();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Runs update logic assuming that a change to `self.string` has been made
|
||||
fn do_update_logic(&mut self) {
|
||||
self.i = 0;
|
||||
self.hint = generate_hint(&self.string);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn register_movement(&mut self, movement: &Movement) {
|
||||
if movement.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
match self.hint {
|
||||
Hint::Many(hints) => {
|
||||
// Impossible for plural hints to be singular or non-existant
|
||||
unsafe {
|
||||
assume(hints.len() > 1);
|
||||
assume(!hints.is_empty());
|
||||
}
|
||||
|
||||
match movement {
|
||||
Movement::Up => {
|
||||
// if self.i is below 1, it's at
|
||||
match self.i {
|
||||
0 => self.i = hints.len() - 1,
|
||||
_ => self.i -= 1,
|
||||
}
|
||||
}
|
||||
Movement::Down => {
|
||||
// add one, if resulting value is above maximum i value, set i to 0
|
||||
self.i += 1;
|
||||
if self.i > (hints.len() - 1) {
|
||||
self.i = 0;
|
||||
}
|
||||
}
|
||||
Movement::Complete => {
|
||||
unsafe { assume(hints.len() >= (self.i + 1)) }
|
||||
|
||||
self.apply_hint(hints[self.i]);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
Hint::Single(hint) => {
|
||||
if movement.is_complete() {
|
||||
self.apply_hint(hint);
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_hint(&mut self, hint: &str) {
|
||||
self.string.push_str(hint);
|
||||
self.do_update_logic();
|
||||
}
|
||||
}
|
||||
@@ -3,15 +3,17 @@
|
||||
#![feature(const_default_impls)]
|
||||
#![feature(const_mut_refs)]
|
||||
|
||||
mod autocomplete_helper;
|
||||
mod autocomplete;
|
||||
mod autocomplete_hashmap;
|
||||
mod parsing;
|
||||
mod suggestions;
|
||||
|
||||
pub use crate::{
|
||||
autocomplete_helper::compile_hashmap,
|
||||
autocomplete::{AutoComplete, Movement},
|
||||
autocomplete_hashmap::compile_hashmap,
|
||||
parsing::{process_func_str, BackingFunction},
|
||||
suggestions::{
|
||||
generate_hint, get_last_term, split_function, split_function_chars, AutoComplete, Hint,
|
||||
Movement, HINT_EMPTY, SUPPORTED_FUNCTIONS,
|
||||
generate_hint, get_last_term, split_function, split_function_chars, Hint, HINT_EMPTY,
|
||||
SUPPORTED_FUNCTIONS,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use exmex::prelude::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub(crate) struct FlatExWrapper {
|
||||
func: Option<FlatEx<f64>>,
|
||||
}
|
||||
@@ -45,7 +45,7 @@ impl const Default for FlatExWrapper {
|
||||
}
|
||||
|
||||
/// Function that includes f(x), f'(x), f'(x)'s string representation, and f''(x)
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct BackingFunction {
|
||||
/// f(x)
|
||||
function: FlatExWrapper,
|
||||
@@ -73,7 +73,7 @@ impl BackingFunction {
|
||||
nth_derivative: None,
|
||||
};
|
||||
|
||||
pub fn is_none(&self) -> bool { self.function.is_none() }
|
||||
pub const fn is_none(&self) -> bool { self.function.is_none() }
|
||||
|
||||
/// Create new [`BackingFunction`] instance
|
||||
pub fn new(func_str: &str) -> Result<Self, String> {
|
||||
|
||||
@@ -205,15 +205,16 @@ pub fn generate_hint<'a>(input: &str) -> &'a Hint<'a> {
|
||||
pub fn get_last_term(chars: &[char]) -> String {
|
||||
assert!(!chars.is_empty());
|
||||
|
||||
let result = split_function_chars(chars, SplitType::Term);
|
||||
unsafe {
|
||||
split_function_chars(chars, SplitType::Term)
|
||||
.last()
|
||||
.unwrap_unchecked()
|
||||
.to_owned()
|
||||
assume(!result.is_empty());
|
||||
assume(result.len() > 0);
|
||||
result.last().unwrap_unchecked()
|
||||
}
|
||||
.to_owned()
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
#[derive(PartialEq, Clone, Copy)]
|
||||
pub enum Hint<'a> {
|
||||
Single(&'a str),
|
||||
Many(&'a [&'a str]),
|
||||
@@ -253,110 +254,3 @@ impl<'a> Hint<'a> {
|
||||
}
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub enum Movement {
|
||||
Complete,
|
||||
#[allow(dead_code)]
|
||||
Down,
|
||||
#[allow(dead_code)]
|
||||
Up,
|
||||
None,
|
||||
}
|
||||
|
||||
impl Movement {
|
||||
pub const fn is_none(&self) -> bool { matches!(&self, Self::None) }
|
||||
}
|
||||
|
||||
impl const Default for Movement {
|
||||
fn default() -> Self { Self::None }
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AutoComplete<'a> {
|
||||
pub i: usize,
|
||||
pub hint: &'a Hint<'a>,
|
||||
pub string: String,
|
||||
}
|
||||
|
||||
impl<'a> const Default for AutoComplete<'a> {
|
||||
fn default() -> AutoComplete<'a> { AutoComplete::EMPTY }
|
||||
}
|
||||
|
||||
impl<'a> AutoComplete<'a> {
|
||||
const EMPTY: AutoComplete<'a> = Self {
|
||||
i: 0,
|
||||
hint: &HINT_EMPTY,
|
||||
string: String::new(),
|
||||
};
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn update_string(&mut self, string: &str) {
|
||||
if self.string != string {
|
||||
// catch empty strings here to avoid call to `generate_hint` and unnecessary logic
|
||||
if string.is_empty() {
|
||||
*self = Self::EMPTY;
|
||||
} else {
|
||||
self.string = string.to_owned();
|
||||
self.do_update_logic();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Runs update logic assuming that a change to `self.string` has been made
|
||||
fn do_update_logic(&mut self) {
|
||||
self.i = 0;
|
||||
self.hint = generate_hint(&self.string);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn register_movement(&mut self, movement: &Movement) {
|
||||
if movement.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
match self.hint {
|
||||
Hint::Many(hints) => {
|
||||
// Impossible for plural hints to be singular or non-existant
|
||||
unsafe {
|
||||
assume(hints.len() > 1);
|
||||
assume(!hints.is_empty());
|
||||
}
|
||||
|
||||
match movement {
|
||||
Movement::Up => {
|
||||
// if self.i is below 1, it's at
|
||||
match self.i {
|
||||
0 => self.i = hints.len() - 1,
|
||||
_ => self.i -= 1,
|
||||
}
|
||||
}
|
||||
Movement::Down => {
|
||||
// add one, if resulting value is above maximum i value, set i to 0
|
||||
self.i += 1;
|
||||
if self.i > (hints.len() - 1) {
|
||||
self.i = 0;
|
||||
}
|
||||
}
|
||||
Movement::Complete => {
|
||||
unsafe { assume(hints.len() >= (self.i + 1)) }
|
||||
|
||||
self.apply_hint(hints[self.i]);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
Hint::Single(hint) => {
|
||||
if movement == &Movement::Complete {
|
||||
self.apply_hint(hint);
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_hint(&mut self, hint: &str) {
|
||||
self.string.push_str(hint);
|
||||
self.do_update_logic();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user