Compare commits
2 Commits
052828c89c
...
077b53f6ff
| Author | SHA1 | Date | |
|---|---|---|---|
| 077b53f6ff | |||
| 0c78e7834b |
@@ -18,7 +18,7 @@ use ratatui::{
|
|||||||
use crate::app::{
|
use crate::app::{
|
||||||
clipboard::Clipboard,
|
clipboard::Clipboard,
|
||||||
error_msg::StatusMessage,
|
error_msg::StatusMessage,
|
||||||
logic::{self, calc::{Grid, get_header_size}, cell::CellType},
|
logic::{calc::{Grid, get_header_size}, cell::CellType},
|
||||||
mode::Mode,
|
mode::Mode,
|
||||||
screen::ScreenSpace,
|
screen::ScreenSpace,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -851,6 +851,19 @@ fn parse_csv() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn invalid_ranges() {
|
||||||
|
let mut grid = Grid::new();
|
||||||
|
|
||||||
|
grid.set_cell("A0", 2.);
|
||||||
|
grid.set_cell("A1", 1.);
|
||||||
|
// ASCII to number conversion needs to not overflow
|
||||||
|
grid.set_cell("B0", "=sum($:A)".to_string());
|
||||||
|
|
||||||
|
let cell = grid.get_cell("B0").as_ref().expect("Just set it");
|
||||||
|
let _ = grid.evaluate(&cell.to_string()).expect("Should evaluate.");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ranges() {
|
fn ranges() {
|
||||||
let mut grid = Grid::new();
|
let mut grid = Grid::new();
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ impl<'a> CallbackContext<'a> {
|
|||||||
let as_index = |s: &str| {
|
let as_index = |s: &str| {
|
||||||
s.char_indices()
|
s.char_indices()
|
||||||
// .filter(|f| f.1 as u8 >= 97) // prevent sub with overflow errors
|
// .filter(|f| f.1 as u8 >= 97) // prevent sub with overflow errors
|
||||||
.map(|(idx, c)| (c.to_ascii_lowercase() as usize - 97) + (26 * idx))
|
.map(|(idx, c)| ((c.to_ascii_lowercase() as usize).saturating_sub(97)) + (26 * idx))
|
||||||
.fold(0, |a, b| a + b)
|
.fold(0, |a, b| a + b)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -162,8 +162,8 @@ impl<'a> Context for CallbackContext<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(mut trail) = self.eval_breadcrumbs.write() {
|
if let Ok(mut trail) = self.eval_breadcrumbs.write() {
|
||||||
let find = trail.iter().filter(|id| *id == identifier).collect::<Vec<&String>>();
|
let find = trail.iter().filter(|id| *id == identifier).count();
|
||||||
if find.len() > 0 {
|
if find > 0 {
|
||||||
// recursion detected
|
// recursion detected
|
||||||
return None;
|
return None;
|
||||||
} else {
|
} else {
|
||||||
@@ -195,7 +195,7 @@ impl<'a> Context for CallbackContext<'a> {
|
|||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
match e {
|
match e {
|
||||||
EvalexprError::VariableIdentifierNotFound(_) => {
|
EvalexprError::VariableIdentifierNotFound(_err) => {
|
||||||
// If the variable isn't found, that's ~~probably~~ because
|
// If the variable isn't found, that's ~~probably~~ because
|
||||||
// of recursive reference, considering all references
|
// of recursive reference, considering all references
|
||||||
// are grabbed straight from the table.
|
// are grabbed straight from the table.
|
||||||
@@ -217,8 +217,14 @@ impl<'a> Context for CallbackContext<'a> {
|
|||||||
CellType::Number(e) => vals.push(Value::Float(*e)),
|
CellType::Number(e) => vals.push(Value::Float(*e)),
|
||||||
CellType::String(s) => vals.push(Value::String(s.to_owned())),
|
CellType::String(s) => vals.push(Value::String(s.to_owned())),
|
||||||
CellType::Equation(eq) => {
|
CellType::Equation(eq) => {
|
||||||
if let Ok(val) = eval_with_context(&eq[1..], self) {
|
match eval_with_context(&eq[1..], self) {
|
||||||
vals.push(val);
|
Ok(val) => vals.push(val),
|
||||||
|
Err(_err) => {
|
||||||
|
// At this point we are getting an error because
|
||||||
|
// recursion protection made this equation return
|
||||||
|
// None. We now don't get any evaluation.
|
||||||
|
return None
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -272,6 +278,7 @@ impl ExtractionContext {
|
|||||||
pub fn dump_vars(&self) -> Vec<String> {
|
pub fn dump_vars(&self) -> Vec<String> {
|
||||||
if let Ok(r) = self.var_registry.read() { r.clone() } else { Vec::new() }
|
if let Ok(r) = self.var_registry.read() { r.clone() } else { Vec::new() }
|
||||||
}
|
}
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn dump_fns(&self) -> Vec<String> {
|
pub fn dump_fns(&self) -> Vec<String> {
|
||||||
if let Ok(r) = self.fn_registry.read() { r.clone() } else { Vec::new() }
|
if let Ok(r) = self.fn_registry.read() { r.clone() } else { Vec::new() }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use crate::app::{
|
|||||||
app::App,
|
app::App,
|
||||||
error_msg::StatusMessage,
|
error_msg::StatusMessage,
|
||||||
logic::{
|
logic::{
|
||||||
calc::{CSV_EXT, CUSTOM_EXT, Grid, LEN},
|
calc::{Grid, LEN},
|
||||||
cell::CellType,
|
cell::CellType,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::{collections::HashMap, sync::RwLock};
|
|||||||
|
|
||||||
use ratatui::prelude;
|
use ratatui::prelude;
|
||||||
|
|
||||||
use crate::app::logic::calc::{self, LEN};
|
use crate::app::logic::calc::LEN;
|
||||||
|
|
||||||
pub struct ScreenSpace {
|
pub struct ScreenSpace {
|
||||||
/// This is measured in cells.
|
/// This is measured in cells.
|
||||||
|
|||||||
Reference in New Issue
Block a user