FIX: Consolidate two structs
This commit is contained in:
@@ -1,17 +1,10 @@
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use crate::expressions::token::Error;
|
use crate::expressions::{token::Error, types::CellReferenceIndex};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
|
|
||||||
pub struct CellReference {
|
|
||||||
pub sheet: u32,
|
|
||||||
pub column: i32,
|
|
||||||
pub row: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Range {
|
pub struct Range {
|
||||||
pub left: CellReference,
|
pub left: CellReferenceIndex,
|
||||||
pub right: CellReference,
|
pub right: CellReferenceIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -21,26 +14,26 @@ pub(crate) enum CalcResult {
|
|||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
Error {
|
Error {
|
||||||
error: Error,
|
error: Error,
|
||||||
origin: CellReference,
|
origin: CellReferenceIndex,
|
||||||
message: String,
|
message: String,
|
||||||
},
|
},
|
||||||
Range {
|
Range {
|
||||||
left: CellReference,
|
left: CellReferenceIndex,
|
||||||
right: CellReference,
|
right: CellReferenceIndex,
|
||||||
},
|
},
|
||||||
EmptyCell,
|
EmptyCell,
|
||||||
EmptyArg,
|
EmptyArg,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CalcResult {
|
impl CalcResult {
|
||||||
pub fn new_error(error: Error, origin: CellReference, message: String) -> CalcResult {
|
pub fn new_error(error: Error, origin: CellReferenceIndex, message: String) -> CalcResult {
|
||||||
CalcResult::Error {
|
CalcResult::Error {
|
||||||
error,
|
error,
|
||||||
origin,
|
origin,
|
||||||
message,
|
message,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn new_args_number_error(origin: CellReference) -> CalcResult {
|
pub fn new_args_number_error(origin: CellReferenceIndex) -> CalcResult {
|
||||||
CalcResult::Error {
|
CalcResult::Error {
|
||||||
error: Error::ERROR,
|
error: Error::ERROR,
|
||||||
origin,
|
origin,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
calc_result::{CalcResult, CellReference, Range},
|
calc_result::{CalcResult, Range},
|
||||||
expressions::{parser::Node, token::Error},
|
expressions::{parser::Node, token::Error, types::CellReferenceIndex},
|
||||||
implicit_intersection::implicit_intersection,
|
implicit_intersection::implicit_intersection,
|
||||||
model::Model,
|
model::Model,
|
||||||
};
|
};
|
||||||
@@ -9,7 +9,7 @@ impl Model {
|
|||||||
pub(crate) fn get_number(
|
pub(crate) fn get_number(
|
||||||
&mut self,
|
&mut self,
|
||||||
node: &Node,
|
node: &Node,
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
) -> Result<f64, CalcResult> {
|
) -> Result<f64, CalcResult> {
|
||||||
let result = self.evaluate_node_in_context(node, cell);
|
let result = self.evaluate_node_in_context(node, cell);
|
||||||
self.cast_to_number(result, cell)
|
self.cast_to_number(result, cell)
|
||||||
@@ -18,7 +18,7 @@ impl Model {
|
|||||||
fn cast_to_number(
|
fn cast_to_number(
|
||||||
&mut self,
|
&mut self,
|
||||||
result: CalcResult,
|
result: CalcResult,
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
) -> Result<f64, CalcResult> {
|
) -> Result<f64, CalcResult> {
|
||||||
match result {
|
match result {
|
||||||
CalcResult::Number(f) => Ok(f),
|
CalcResult::Number(f) => Ok(f),
|
||||||
@@ -58,7 +58,7 @@ impl Model {
|
|||||||
pub(crate) fn get_number_no_bools(
|
pub(crate) fn get_number_no_bools(
|
||||||
&mut self,
|
&mut self,
|
||||||
node: &Node,
|
node: &Node,
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
) -> Result<f64, CalcResult> {
|
) -> Result<f64, CalcResult> {
|
||||||
let result = self.evaluate_node_in_context(node, cell);
|
let result = self.evaluate_node_in_context(node, cell);
|
||||||
if matches!(result, CalcResult::Boolean(_)) {
|
if matches!(result, CalcResult::Boolean(_)) {
|
||||||
@@ -74,7 +74,7 @@ impl Model {
|
|||||||
pub(crate) fn get_string(
|
pub(crate) fn get_string(
|
||||||
&mut self,
|
&mut self,
|
||||||
node: &Node,
|
node: &Node,
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
) -> Result<String, CalcResult> {
|
) -> Result<String, CalcResult> {
|
||||||
let result = self.evaluate_node_in_context(node, cell);
|
let result = self.evaluate_node_in_context(node, cell);
|
||||||
self.cast_to_string(result, cell)
|
self.cast_to_string(result, cell)
|
||||||
@@ -83,7 +83,7 @@ impl Model {
|
|||||||
pub(crate) fn cast_to_string(
|
pub(crate) fn cast_to_string(
|
||||||
&mut self,
|
&mut self,
|
||||||
result: CalcResult,
|
result: CalcResult,
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
) -> Result<String, CalcResult> {
|
) -> Result<String, CalcResult> {
|
||||||
// FIXME: I think when casting a number we should convert it to_precision(x, 15)
|
// FIXME: I think when casting a number we should convert it to_precision(x, 15)
|
||||||
// See function Exact
|
// See function Exact
|
||||||
@@ -118,7 +118,7 @@ impl Model {
|
|||||||
pub(crate) fn get_boolean(
|
pub(crate) fn get_boolean(
|
||||||
&mut self,
|
&mut self,
|
||||||
node: &Node,
|
node: &Node,
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
) -> Result<bool, CalcResult> {
|
) -> Result<bool, CalcResult> {
|
||||||
let result = self.evaluate_node_in_context(node, cell);
|
let result = self.evaluate_node_in_context(node, cell);
|
||||||
self.cast_to_bool(result, cell)
|
self.cast_to_bool(result, cell)
|
||||||
@@ -127,7 +127,7 @@ impl Model {
|
|||||||
fn cast_to_bool(
|
fn cast_to_bool(
|
||||||
&mut self,
|
&mut self,
|
||||||
result: CalcResult,
|
result: CalcResult,
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
) -> Result<bool, CalcResult> {
|
) -> Result<bool, CalcResult> {
|
||||||
match result {
|
match result {
|
||||||
CalcResult::Number(f) => {
|
CalcResult::Number(f) => {
|
||||||
@@ -171,7 +171,7 @@ impl Model {
|
|||||||
pub(crate) fn get_reference(
|
pub(crate) fn get_reference(
|
||||||
&mut self,
|
&mut self,
|
||||||
node: &Node,
|
node: &Node,
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
) -> Result<Range, CalcResult> {
|
) -> Result<Range, CalcResult> {
|
||||||
match node {
|
match node {
|
||||||
Node::ReferenceKind {
|
Node::ReferenceKind {
|
||||||
@@ -182,7 +182,7 @@ impl Model {
|
|||||||
sheet_index,
|
sheet_index,
|
||||||
sheet_name: _,
|
sheet_name: _,
|
||||||
} => {
|
} => {
|
||||||
let left = CellReference {
|
let left = CellReferenceIndex {
|
||||||
sheet: *sheet_index,
|
sheet: *sheet_index,
|
||||||
row: if *absolute_row { *row } else { *row + cell.row },
|
row: if *absolute_row { *row } else { *row + cell.row },
|
||||||
column: if *absolute_column {
|
column: if *absolute_column {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ pub struct CellReferenceRC {
|
|||||||
pub row: i32,
|
pub row: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Copy)]
|
||||||
pub struct CellReferenceIndex {
|
pub struct CellReferenceIndex {
|
||||||
pub sheet: u32,
|
pub sheet: u32,
|
||||||
pub column: i32,
|
pub column: i32,
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use crate::{
|
use crate::{calc_result::CalcResult, expressions::types::CellReferenceIndex, model::Model};
|
||||||
calc_result::{CalcResult, CellReference},
|
|
||||||
model::Model,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::util::compare_values;
|
use super::util::compare_values;
|
||||||
|
|
||||||
@@ -144,8 +141,8 @@ impl Model {
|
|||||||
/// Returns an array with the list of cell values in the range
|
/// Returns an array with the list of cell values in the range
|
||||||
pub(crate) fn prepare_array(
|
pub(crate) fn prepare_array(
|
||||||
&mut self,
|
&mut self,
|
||||||
left: &CellReference,
|
left: &CellReferenceIndex,
|
||||||
right: &CellReference,
|
right: &CellReferenceIndex,
|
||||||
is_row_vector: bool,
|
is_row_vector: bool,
|
||||||
) -> Vec<CalcResult> {
|
) -> Vec<CalcResult> {
|
||||||
let n = if is_row_vector {
|
let n = if is_row_vector {
|
||||||
@@ -164,7 +161,7 @@ impl Model {
|
|||||||
column = left.column + index;
|
column = left.column + index;
|
||||||
row = left.row;
|
row = left.row;
|
||||||
}
|
}
|
||||||
let value = self.evaluate_cell(CellReference {
|
let value = self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -178,8 +175,8 @@ impl Model {
|
|||||||
pub(crate) fn binary_search(
|
pub(crate) fn binary_search(
|
||||||
&mut self,
|
&mut self,
|
||||||
target: &CalcResult,
|
target: &CalcResult,
|
||||||
left: &CellReference,
|
left: &CellReferenceIndex,
|
||||||
right: &CellReference,
|
right: &CellReferenceIndex,
|
||||||
is_row_vector: bool,
|
is_row_vector: bool,
|
||||||
) -> i32 {
|
) -> i32 {
|
||||||
let array = self.prepare_array(left, right, is_row_vector);
|
let array = self.prepare_array(left, right, is_row_vector);
|
||||||
|
|||||||
@@ -4,19 +4,16 @@ use chrono::NaiveDateTime;
|
|||||||
use chrono::TimeZone;
|
use chrono::TimeZone;
|
||||||
use chrono::Timelike;
|
use chrono::Timelike;
|
||||||
|
|
||||||
|
use crate::expressions::types::CellReferenceIndex;
|
||||||
use crate::formatter::dates::date_to_serial_number;
|
use crate::formatter::dates::date_to_serial_number;
|
||||||
use crate::model::get_milliseconds_since_epoch;
|
use crate::model::get_milliseconds_since_epoch;
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_result::{CalcResult, CellReference},
|
calc_result::CalcResult, constants::EXCEL_DATE_BASE, expressions::parser::Node,
|
||||||
constants::EXCEL_DATE_BASE,
|
expressions::token::Error, formatter::dates::from_excel_date, model::Model,
|
||||||
expressions::parser::Node,
|
|
||||||
expressions::token::Error,
|
|
||||||
formatter::dates::from_excel_date,
|
|
||||||
model::Model,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
pub(crate) fn fn_day(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_day(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let args_count = args.len();
|
let args_count = args.len();
|
||||||
if args_count != 1 {
|
if args_count != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -40,7 +37,7 @@ impl Model {
|
|||||||
CalcResult::Number(day)
|
CalcResult::Number(day)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_month(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_month(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let args_count = args.len();
|
let args_count = args.len();
|
||||||
if args_count != 1 {
|
if args_count != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -64,7 +61,7 @@ impl Model {
|
|||||||
CalcResult::Number(month)
|
CalcResult::Number(month)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_eomonth(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_eomonth(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let args_count = args.len();
|
let args_count = args.len();
|
||||||
if args_count != 2 {
|
if args_count != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -119,7 +116,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// year, month, day
|
// year, month, day
|
||||||
pub(crate) fn fn_date(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_date(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let args_count = args.len();
|
let args_count = args.len();
|
||||||
if args_count != 3 {
|
if args_count != 3 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -176,7 +173,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_year(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_year(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let args_count = args.len();
|
let args_count = args.len();
|
||||||
if args_count != 1 {
|
if args_count != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -201,7 +198,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// date, months
|
// date, months
|
||||||
pub(crate) fn fn_edate(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_edate(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let args_count = args.len();
|
let args_count = args.len();
|
||||||
if args_count != 2 {
|
if args_count != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -249,7 +246,7 @@ impl Model {
|
|||||||
CalcResult::Number(serial_number as f64)
|
CalcResult::Number(serial_number as f64)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_today(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_today(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let args_count = args.len();
|
let args_count = args.len();
|
||||||
if args_count != 0 {
|
if args_count != 0 {
|
||||||
return CalcResult::Error {
|
return CalcResult::Error {
|
||||||
@@ -280,7 +277,7 @@ impl Model {
|
|||||||
CalcResult::Number(days_from_1900 as f64)
|
CalcResult::Number(days_from_1900 as f64)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_now(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_now(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let args_count = args.len();
|
let args_count = args.len();
|
||||||
if args_count != 0 {
|
if args_count != 0 {
|
||||||
return CalcResult::Error {
|
return CalcResult::Error {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
calc_result::{CalcResult, CellReference},
|
calc_result::CalcResult,
|
||||||
expressions::{parser::Node, token::Error},
|
expressions::{parser::Node, token::Error, types::CellReferenceIndex},
|
||||||
model::Model,
|
model::Model,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ use super::transcendental::{bessel_i, bessel_j, bessel_k, bessel_y, erf};
|
|||||||
// EXCEL_BESSEL(x, n) => bessel(n, x)
|
// EXCEL_BESSEL(x, n) => bessel(n, x)
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
pub(crate) fn fn_besseli(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_besseli(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_besselj(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_besselj(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ impl Model {
|
|||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_besselk(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_besselk(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -90,7 +90,7 @@ impl Model {
|
|||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_bessely(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_bessely(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ impl Model {
|
|||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_erf(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_erf(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if !(1..=2).contains(&args.len()) {
|
if !(1..=2).contains(&args.len()) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -141,7 +141,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_erfprecise(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_erfprecise(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
};
|
};
|
||||||
@@ -152,7 +152,7 @@ impl Model {
|
|||||||
CalcResult::Number(erf(x))
|
CalcResult::Number(erf(x))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_erfc(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_erfc(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
};
|
};
|
||||||
@@ -163,7 +163,7 @@ impl Model {
|
|||||||
CalcResult::Number(1.0 - erf(x))
|
CalcResult::Number(1.0 - erf(x))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_erfcprecise(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_erfcprecise(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
calc_result::{CalcResult, CellReference},
|
calc_result::CalcResult,
|
||||||
expressions::parser::Node,
|
expressions::{parser::Node, token::Error, types::CellReferenceIndex},
|
||||||
expressions::token::Error,
|
|
||||||
model::Model,
|
model::Model,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -10,7 +9,7 @@ const MAX: f64 = 281474976710655.0;
|
|||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
// BITAND( number1, number2)
|
// BITAND( number1, number2)
|
||||||
pub(crate) fn fn_bitand(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_bitand(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -48,7 +47,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BITOR(number1, number2)
|
// BITOR(number1, number2)
|
||||||
pub(crate) fn fn_bitor(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_bitor(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -86,7 +85,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BITXOR(number1, number2)
|
// BITXOR(number1, number2)
|
||||||
pub(crate) fn fn_bitxor(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_bitxor(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -124,7 +123,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BITLSHIFT(number, shift_amount)
|
// BITLSHIFT(number, shift_amount)
|
||||||
pub(crate) fn fn_bitlshift(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_bitlshift(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -178,7 +177,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BITRSHIFT(number, shift_amount)
|
// BITRSHIFT(number, shift_amount)
|
||||||
pub(crate) fn fn_bitrshift(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_bitrshift(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_result::{CalcResult, CellReference},
|
calc_result::CalcResult,
|
||||||
expressions::{
|
expressions::{
|
||||||
lexer::util::get_tokens,
|
lexer::util::get_tokens,
|
||||||
parser::Node,
|
parser::Node,
|
||||||
token::{Error, OpSum, TokenType},
|
token::{Error, OpSum, TokenType},
|
||||||
|
types::CellReferenceIndex,
|
||||||
},
|
},
|
||||||
model::Model,
|
model::Model,
|
||||||
number_format::to_precision,
|
number_format::to_precision,
|
||||||
@@ -185,7 +186,7 @@ impl Model {
|
|||||||
fn get_complex_number(
|
fn get_complex_number(
|
||||||
&mut self,
|
&mut self,
|
||||||
node: &Node,
|
node: &Node,
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
) -> Result<(f64, f64, Suffix), CalcResult> {
|
) -> Result<(f64, f64, Suffix), CalcResult> {
|
||||||
let value = match self.get_string(node, cell) {
|
let value = match self.get_string(node, cell) {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
@@ -200,7 +201,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// COMPLEX(real_num, i_num, [suffix])
|
// COMPLEX(real_num, i_num, [suffix])
|
||||||
pub(crate) fn fn_complex(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_complex(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if !(2..=3).contains(&args.len()) {
|
if !(2..=3).contains(&args.len()) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -237,7 +238,7 @@ impl Model {
|
|||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_imabs(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imabs(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -248,7 +249,7 @@ impl Model {
|
|||||||
CalcResult::Number(f64::sqrt(x * x + y * y))
|
CalcResult::Number(f64::sqrt(x * x + y * y))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_imaginary(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imaginary(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -258,7 +259,7 @@ impl Model {
|
|||||||
};
|
};
|
||||||
CalcResult::Number(y)
|
CalcResult::Number(y)
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_imargument(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imargument(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -272,7 +273,7 @@ impl Model {
|
|||||||
let angle = f64::atan2(y, x);
|
let angle = f64::atan2(y, x);
|
||||||
CalcResult::Number(angle)
|
CalcResult::Number(angle)
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_imconjugate(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imconjugate(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -283,7 +284,7 @@ impl Model {
|
|||||||
let complex = Complex { x, y: -y, suffix };
|
let complex = Complex { x, y: -y, suffix };
|
||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_imcos(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imcos(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -303,7 +304,7 @@ impl Model {
|
|||||||
};
|
};
|
||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_imcosh(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imcosh(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -323,7 +324,7 @@ impl Model {
|
|||||||
};
|
};
|
||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_imcot(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imcot(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -367,7 +368,7 @@ impl Model {
|
|||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_imcsc(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imcsc(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -395,7 +396,7 @@ impl Model {
|
|||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_imcsch(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imcsch(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -423,7 +424,7 @@ impl Model {
|
|||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_imdiv(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imdiv(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -450,7 +451,7 @@ impl Model {
|
|||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_imexp(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imexp(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -466,7 +467,7 @@ impl Model {
|
|||||||
};
|
};
|
||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_imln(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imln(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -485,7 +486,7 @@ impl Model {
|
|||||||
};
|
};
|
||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_imlog10(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imlog10(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -504,7 +505,7 @@ impl Model {
|
|||||||
};
|
};
|
||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_imlog2(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imlog2(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -527,7 +528,7 @@ impl Model {
|
|||||||
// IMPOWER(imnumber, power)
|
// IMPOWER(imnumber, power)
|
||||||
// If $(r, \theta)$ is the polar representation the formula is:
|
// If $(r, \theta)$ is the polar representation the formula is:
|
||||||
// $$ x = r^n*\cos(n\dot\theta), y = r^n*\csin(n\dot\theta) $
|
// $$ x = r^n*\cos(n\dot\theta), y = r^n*\csin(n\dot\theta) $
|
||||||
pub(crate) fn fn_impower(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_impower(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -570,7 +571,7 @@ impl Model {
|
|||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_improduct(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_improduct(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -595,7 +596,7 @@ impl Model {
|
|||||||
};
|
};
|
||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_imreal(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imreal(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -605,7 +606,7 @@ impl Model {
|
|||||||
};
|
};
|
||||||
CalcResult::Number(x)
|
CalcResult::Number(x)
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_imsec(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imsec(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -628,7 +629,7 @@ impl Model {
|
|||||||
};
|
};
|
||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_imsech(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imsech(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -651,7 +652,7 @@ impl Model {
|
|||||||
};
|
};
|
||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_imsin(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imsin(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -667,7 +668,7 @@ impl Model {
|
|||||||
};
|
};
|
||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_imsinh(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imsinh(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -683,7 +684,7 @@ impl Model {
|
|||||||
};
|
};
|
||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_imsqrt(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imsqrt(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -702,7 +703,7 @@ impl Model {
|
|||||||
};
|
};
|
||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_imsub(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imsub(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -725,7 +726,7 @@ impl Model {
|
|||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_imsum(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imsum(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -748,7 +749,7 @@ impl Model {
|
|||||||
CalcResult::String(complex.to_string())
|
CalcResult::String(complex.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_imtan(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_imtan(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_result::{CalcResult, CellReference},
|
calc_result::CalcResult,
|
||||||
expressions::parser::Node,
|
expressions::{parser::Node, token::Error, types::CellReferenceIndex},
|
||||||
expressions::token::Error,
|
|
||||||
model::Model,
|
model::Model,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -44,7 +43,7 @@ fn convert_temperature(
|
|||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
// CONVERT(number, from_unit, to_unit)
|
// CONVERT(number, from_unit, to_unit)
|
||||||
pub(crate) fn fn_convert(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_convert(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 3 {
|
if args.len() != 3 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
calc_result::{CalcResult, CellReference},
|
calc_result::CalcResult,
|
||||||
expressions::parser::Node,
|
expressions::{parser::Node, types::CellReferenceIndex},
|
||||||
model::Model,
|
model::Model,
|
||||||
number_format::to_precision,
|
number_format::to_precision,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
// DELTA(number1, [number2])
|
// DELTA(number1, [number2])
|
||||||
pub(crate) fn fn_delta(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_delta(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if !(1..=2).contains(&arg_count) {
|
if !(1..=2).contains(&arg_count) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -33,7 +33,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GESTEP(number, [step])
|
// GESTEP(number, [step])
|
||||||
pub(crate) fn fn_gestep(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_gestep(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if !(1..=2).contains(&arg_count) {
|
if !(1..=2).contains(&arg_count) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
calc_result::{CalcResult, CellReference},
|
calc_result::CalcResult,
|
||||||
expressions::parser::Node,
|
expressions::{parser::Node, token::Error, types::CellReferenceIndex},
|
||||||
expressions::token::Error,
|
|
||||||
model::Model,
|
model::Model,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -34,7 +33,7 @@ fn from_binary_to_decimal(value: f64) -> Result<i64, String> {
|
|||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
// BIN2DEC(number)
|
// BIN2DEC(number)
|
||||||
pub(crate) fn fn_bin2dec(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_bin2dec(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -49,7 +48,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BIN2HEX(number, [places])
|
// BIN2HEX(number, [places])
|
||||||
pub(crate) fn fn_bin2hex(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_bin2hex(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if !(1..=2).contains(&args.len()) {
|
if !(1..=2).contains(&args.len()) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -93,7 +92,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BIN2OCT(number, [places])
|
// BIN2OCT(number, [places])
|
||||||
pub(crate) fn fn_bin2oct(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_bin2oct(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if !(1..=2).contains(&args.len()) {
|
if !(1..=2).contains(&args.len()) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -136,7 +135,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_dec2bin(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_dec2bin(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if !(1..=2).contains(&args.len()) {
|
if !(1..=2).contains(&args.len()) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -175,7 +174,7 @@ impl Model {
|
|||||||
CalcResult::String(result)
|
CalcResult::String(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_dec2hex(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_dec2hex(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if !(1..=2).contains(&args.len()) {
|
if !(1..=2).contains(&args.len()) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -214,7 +213,7 @@ impl Model {
|
|||||||
CalcResult::String(result)
|
CalcResult::String(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_dec2oct(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_dec2oct(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if !(1..=2).contains(&args.len()) {
|
if !(1..=2).contains(&args.len()) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -255,7 +254,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HEX2BIN(number, [places])
|
// HEX2BIN(number, [places])
|
||||||
pub(crate) fn fn_hex2bin(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_hex2bin(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if !(1..=2).contains(&args.len()) {
|
if !(1..=2).contains(&args.len()) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -314,7 +313,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HEX2DEC(number)
|
// HEX2DEC(number)
|
||||||
pub(crate) fn fn_hex2dec(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_hex2dec(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if !(1..=2).contains(&args.len()) {
|
if !(1..=2).contains(&args.len()) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -345,7 +344,7 @@ impl Model {
|
|||||||
CalcResult::Number(value as f64)
|
CalcResult::Number(value as f64)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_hex2oct(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_hex2oct(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if !(1..=2).contains(&args.len()) {
|
if !(1..=2).contains(&args.len()) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -403,7 +402,7 @@ impl Model {
|
|||||||
CalcResult::String(result)
|
CalcResult::String(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_oct2bin(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_oct2bin(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if !(1..=2).contains(&args.len()) {
|
if !(1..=2).contains(&args.len()) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -458,7 +457,7 @@ impl Model {
|
|||||||
CalcResult::String(result)
|
CalcResult::String(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_oct2dec(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_oct2dec(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if !(1..=2).contains(&args.len()) {
|
if !(1..=2).contains(&args.len()) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -486,7 +485,7 @@ impl Model {
|
|||||||
CalcResult::Number(value as f64)
|
CalcResult::Number(value as f64)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_oct2hex(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_oct2hex(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if !(1..=2).contains(&args.len()) {
|
if !(1..=2).contains(&args.len()) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
use chrono::Datelike;
|
use chrono::Datelike;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_result::{CalcResult, CellReference},
|
calc_result::CalcResult,
|
||||||
constants::{LAST_COLUMN, LAST_ROW},
|
constants::{LAST_COLUMN, LAST_ROW},
|
||||||
expressions::{parser::Node, token::Error},
|
expressions::{parser::Node, token::Error, types::CellReferenceIndex},
|
||||||
formatter::dates::from_excel_date,
|
formatter::dates::from_excel_date,
|
||||||
model::Model,
|
model::Model,
|
||||||
};
|
};
|
||||||
@@ -199,7 +199,7 @@ impl Model {
|
|||||||
fn get_array_of_numbers(
|
fn get_array_of_numbers(
|
||||||
&mut self,
|
&mut self,
|
||||||
arg: &Node,
|
arg: &Node,
|
||||||
cell: &CellReference,
|
cell: &CellReferenceIndex,
|
||||||
) -> Result<Vec<f64>, CalcResult> {
|
) -> Result<Vec<f64>, CalcResult> {
|
||||||
let mut values = Vec::new();
|
let mut values = Vec::new();
|
||||||
match self.evaluate_node_in_context(arg, *cell) {
|
match self.evaluate_node_in_context(arg, *cell) {
|
||||||
@@ -234,7 +234,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
for row in row1..row2 + 1 {
|
for row in row1..row2 + 1 {
|
||||||
for column in column1..(column2 + 1) {
|
for column in column1..(column2 + 1) {
|
||||||
match self.evaluate_cell(CellReference {
|
match self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -261,7 +261,7 @@ impl Model {
|
|||||||
fn get_array_of_numbers_xpnv(
|
fn get_array_of_numbers_xpnv(
|
||||||
&mut self,
|
&mut self,
|
||||||
arg: &Node,
|
arg: &Node,
|
||||||
cell: &CellReference,
|
cell: &CellReferenceIndex,
|
||||||
error: Error,
|
error: Error,
|
||||||
) -> Result<Vec<f64>, CalcResult> {
|
) -> Result<Vec<f64>, CalcResult> {
|
||||||
let mut values = Vec::new();
|
let mut values = Vec::new();
|
||||||
@@ -297,7 +297,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
for row in row1..row2 + 1 {
|
for row in row1..row2 + 1 {
|
||||||
for column in column1..(column2 + 1) {
|
for column in column1..(column2 + 1) {
|
||||||
match self.evaluate_cell(CellReference {
|
match self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -339,7 +339,7 @@ impl Model {
|
|||||||
fn get_array_of_numbers_xirr(
|
fn get_array_of_numbers_xirr(
|
||||||
&mut self,
|
&mut self,
|
||||||
arg: &Node,
|
arg: &Node,
|
||||||
cell: &CellReference,
|
cell: &CellReferenceIndex,
|
||||||
) -> Result<Vec<f64>, CalcResult> {
|
) -> Result<Vec<f64>, CalcResult> {
|
||||||
let mut values = Vec::new();
|
let mut values = Vec::new();
|
||||||
match self.evaluate_node_in_context(arg, *cell) {
|
match self.evaluate_node_in_context(arg, *cell) {
|
||||||
@@ -373,7 +373,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
for row in row1..row2 + 1 {
|
for row in row1..row2 + 1 {
|
||||||
for column in column1..(column2 + 1) {
|
for column in column1..(column2 + 1) {
|
||||||
match self.evaluate_cell(CellReference {
|
match self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -407,7 +407,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// PMT(rate, nper, pv, [fv], [type])
|
/// PMT(rate, nper, pv, [fv], [type])
|
||||||
pub(crate) fn fn_pmt(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_pmt(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if !(3..=5).contains(&arg_count) {
|
if !(3..=5).contains(&arg_count) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -455,7 +455,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PV(rate, nper, pmt, [fv], [type])
|
// PV(rate, nper, pmt, [fv], [type])
|
||||||
pub(crate) fn fn_pv(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_pv(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if !(3..=5).contains(&arg_count) {
|
if !(3..=5).contains(&arg_count) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -521,7 +521,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RATE(nper, pmt, pv, [fv], [type], [guess])
|
// RATE(nper, pmt, pv, [fv], [type], [guess])
|
||||||
pub(crate) fn fn_rate(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_rate(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if !(3..=5).contains(&arg_count) {
|
if !(3..=5).contains(&arg_count) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -577,7 +577,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NPER(rate,pmt,pv,[fv],[type])
|
// NPER(rate,pmt,pv,[fv],[type])
|
||||||
pub(crate) fn fn_nper(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_nper(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if !(3..=5).contains(&arg_count) {
|
if !(3..=5).contains(&arg_count) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -660,7 +660,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FV(rate, nper, pmt, [pv], [type])
|
// FV(rate, nper, pmt, [pv], [type])
|
||||||
pub(crate) fn fn_fv(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_fv(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if !(3..=5).contains(&arg_count) {
|
if !(3..=5).contains(&arg_count) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -708,7 +708,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IPMT(rate, per, nper, pv, [fv], [type])
|
// IPMT(rate, per, nper, pv, [fv], [type])
|
||||||
pub(crate) fn fn_ipmt(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_ipmt(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if !(4..=6).contains(&arg_count) {
|
if !(4..=6).contains(&arg_count) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -771,7 +771,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PPMT(rate, per, nper, pv, [fv], [type])
|
// PPMT(rate, per, nper, pv, [fv], [type])
|
||||||
pub(crate) fn fn_ppmt(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_ppmt(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if !(4..=6).contains(&arg_count) {
|
if !(4..=6).contains(&arg_count) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -836,7 +836,7 @@ impl Model {
|
|||||||
|
|
||||||
// NPV(rate, value1, [value2],...)
|
// NPV(rate, value1, [value2],...)
|
||||||
// npv = Sum[value[i]/(1+rate)^i, {i, 1, n}]
|
// npv = Sum[value[i]/(1+rate)^i, {i, 1, n}]
|
||||||
pub(crate) fn fn_npv(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_npv(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if arg_count < 2 {
|
if arg_count < 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -879,7 +879,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
for row in row1..row2 + 1 {
|
for row in row1..row2 + 1 {
|
||||||
for column in column1..(column2 + 1) {
|
for column in column1..(column2 + 1) {
|
||||||
match self.evaluate_cell(CellReference {
|
match self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -915,7 +915,7 @@ impl Model {
|
|||||||
// of payments (negative values) and income (positive values) that occur at regular periods
|
// of payments (negative values) and income (positive values) that occur at regular periods
|
||||||
|
|
||||||
// IRR(values, [guess])
|
// IRR(values, [guess])
|
||||||
pub(crate) fn fn_irr(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_irr(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if arg_count > 2 || arg_count == 0 {
|
if arg_count > 2 || arg_count == 0 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -943,7 +943,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// XNPV(rate, values, dates)
|
// XNPV(rate, values, dates)
|
||||||
pub(crate) fn fn_xnpv(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_xnpv(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if !(2..=3).contains(&arg_count) {
|
if !(2..=3).contains(&arg_count) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -1005,7 +1005,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// XIRR(values, dates, [guess])
|
// XIRR(values, dates, [guess])
|
||||||
pub(crate) fn fn_xirr(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_xirr(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if !(2..=3).contains(&arg_count) {
|
if !(2..=3).contains(&arg_count) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -1076,7 +1076,7 @@ impl Model {
|
|||||||
// $v_p$ the vector of positive values
|
// $v_p$ the vector of positive values
|
||||||
// $v_n$ the vector of negative values
|
// $v_n$ the vector of negative values
|
||||||
// and $y$ is dimension of $v$ - 1 (number of years)
|
// and $y$ is dimension of $v$ - 1 (number of years)
|
||||||
pub(crate) fn fn_mirr(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_mirr(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 3 {
|
if args.len() != 3 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -1168,7 +1168,7 @@ impl Model {
|
|||||||
// ISPMT(rate, per, nper, pv)
|
// ISPMT(rate, per, nper, pv)
|
||||||
// Formula is:
|
// Formula is:
|
||||||
// $$pv*rate*\left(\frac{per}{nper}-1\right)$$
|
// $$pv*rate*\left(\frac{per}{nper}-1\right)$$
|
||||||
pub(crate) fn fn_ispmt(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_ispmt(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 4 {
|
if args.len() != 4 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -1197,7 +1197,7 @@ impl Model {
|
|||||||
// RRI(nper, pv, fv)
|
// RRI(nper, pv, fv)
|
||||||
// Formula is
|
// Formula is
|
||||||
// $$ \left(\frac{fv}{pv}\right)^{\frac{1}{nper}}-1 $$
|
// $$ \left(\frac{fv}{pv}\right)^{\frac{1}{nper}}-1 $$
|
||||||
pub(crate) fn fn_rri(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_rri(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 3 {
|
if args.len() != 3 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -1234,7 +1234,7 @@ impl Model {
|
|||||||
// SLN(cost, salvage, life)
|
// SLN(cost, salvage, life)
|
||||||
// Formula is:
|
// Formula is:
|
||||||
// $$ \frac{cost-salvage}{life} $$
|
// $$ \frac{cost-salvage}{life} $$
|
||||||
pub(crate) fn fn_sln(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_sln(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 3 {
|
if args.len() != 3 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -1261,7 +1261,7 @@ impl Model {
|
|||||||
// SYD(cost, salvage, life, per)
|
// SYD(cost, salvage, life, per)
|
||||||
// Formula is:
|
// Formula is:
|
||||||
// $$ \frac{(cost-salvage)*(life-per+1)*2}{life*(life+1)} $$
|
// $$ \frac{(cost-salvage)*(life-per+1)*2}{life*(life+1)} $$
|
||||||
pub(crate) fn fn_syd(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_syd(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 4 {
|
if args.len() != 4 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -1298,7 +1298,7 @@ impl Model {
|
|||||||
// where:
|
// where:
|
||||||
// $r$ is the effective interest rate
|
// $r$ is the effective interest rate
|
||||||
// $n$ is the number of periods per year
|
// $n$ is the number of periods per year
|
||||||
pub(crate) fn fn_nominal(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_nominal(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -1330,7 +1330,7 @@ impl Model {
|
|||||||
// where:
|
// where:
|
||||||
// $r$ is the nominal interest rate
|
// $r$ is the nominal interest rate
|
||||||
// $n$ is the number of periods per year
|
// $n$ is the number of periods per year
|
||||||
pub(crate) fn fn_effect(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_effect(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -1363,7 +1363,7 @@ impl Model {
|
|||||||
// * $r$ is the interest rate per period
|
// * $r$ is the interest rate per period
|
||||||
// * $pv$ is the present value of the investment
|
// * $pv$ is the present value of the investment
|
||||||
// * $fv$ is the desired future value of the investment
|
// * $fv$ is the desired future value of the investment
|
||||||
pub(crate) fn fn_pduration(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_pduration(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 3 {
|
if args.len() != 3 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -1410,7 +1410,7 @@ impl Model {
|
|||||||
/// Together with the previous relation of $p$ and $v$ gives us a quadratic equation for $y$.
|
/// Together with the previous relation of $p$ and $v$ gives us a quadratic equation for $y$.
|
||||||
|
|
||||||
// TBILLEQ(settlement, maturity, discount)
|
// TBILLEQ(settlement, maturity, discount)
|
||||||
pub(crate) fn fn_tbilleq(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_tbilleq(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 3 {
|
if args.len() != 3 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -1474,7 +1474,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TBILLPRICE(settlement, maturity, discount)
|
// TBILLPRICE(settlement, maturity, discount)
|
||||||
pub(crate) fn fn_tbillprice(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_tbillprice(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 3 {
|
if args.len() != 3 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -1524,7 +1524,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TBILLYIELD(settlement, maturity, pr)
|
// TBILLYIELD(settlement, maturity, pr)
|
||||||
pub(crate) fn fn_tbillyield(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_tbillyield(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 3 {
|
if args.len() != 3 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -1567,7 +1567,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DOLLARDE(fractional_dollar, fraction)
|
// DOLLARDE(fractional_dollar, fraction)
|
||||||
pub(crate) fn fn_dollarde(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_dollarde(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -1596,7 +1596,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DOLLARFR(decimal_dollar, fraction)
|
// DOLLARFR(decimal_dollar, fraction)
|
||||||
pub(crate) fn fn_dollarfr(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_dollarfr(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -1625,7 +1625,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CUMIPMT(rate, nper, pv, start_period, end_period, type)
|
// CUMIPMT(rate, nper, pv, start_period, end_period, type)
|
||||||
pub(crate) fn fn_cumipmt(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_cumipmt(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 6 {
|
if args.len() != 6 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -1693,7 +1693,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CUMPRINC(rate, nper, pv, start_period, end_period, type)
|
// CUMPRINC(rate, nper, pv, start_period, end_period, type)
|
||||||
pub(crate) fn fn_cumprinc(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_cumprinc(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 6 {
|
if args.len() != 6 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -1761,7 +1761,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DDB(cost, salvage, life, period, [factor])
|
// DDB(cost, salvage, life, period, [factor])
|
||||||
pub(crate) fn fn_ddb(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_ddb(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if !(4..=5).contains(&arg_count) {
|
if !(4..=5).contains(&arg_count) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -1815,7 +1815,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DB(cost, salvage, life, period, [month])
|
// DB(cost, salvage, life, period, [month])
|
||||||
pub(crate) fn fn_db(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_db(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if !(4..=5).contains(&arg_count) {
|
if !(4..=5).contains(&arg_count) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
calc_result::{CalcResult, CellReference},
|
calc_result::CalcResult,
|
||||||
expressions::parser::Node,
|
expressions::{parser::Node, token::Error, types::CellReferenceIndex},
|
||||||
expressions::token::Error,
|
|
||||||
model::{Model, ParsedDefinedName},
|
model::{Model, ParsedDefinedName},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
pub(crate) fn fn_isnumber(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_isnumber(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 1 {
|
if args.len() == 1 {
|
||||||
match self.evaluate_node_in_context(&args[0], cell) {
|
match self.evaluate_node_in_context(&args[0], cell) {
|
||||||
CalcResult::Number(_) => return CalcResult::Boolean(true),
|
CalcResult::Number(_) => return CalcResult::Boolean(true),
|
||||||
@@ -17,7 +16,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
CalcResult::new_args_number_error(cell)
|
CalcResult::new_args_number_error(cell)
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_istext(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_istext(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 1 {
|
if args.len() == 1 {
|
||||||
match self.evaluate_node_in_context(&args[0], cell) {
|
match self.evaluate_node_in_context(&args[0], cell) {
|
||||||
CalcResult::String(_) => return CalcResult::Boolean(true),
|
CalcResult::String(_) => return CalcResult::Boolean(true),
|
||||||
@@ -28,7 +27,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
CalcResult::new_args_number_error(cell)
|
CalcResult::new_args_number_error(cell)
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_isnontext(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_isnontext(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 1 {
|
if args.len() == 1 {
|
||||||
match self.evaluate_node_in_context(&args[0], cell) {
|
match self.evaluate_node_in_context(&args[0], cell) {
|
||||||
CalcResult::String(_) => return CalcResult::Boolean(false),
|
CalcResult::String(_) => return CalcResult::Boolean(false),
|
||||||
@@ -39,7 +38,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
CalcResult::new_args_number_error(cell)
|
CalcResult::new_args_number_error(cell)
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_islogical(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_islogical(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 1 {
|
if args.len() == 1 {
|
||||||
match self.evaluate_node_in_context(&args[0], cell) {
|
match self.evaluate_node_in_context(&args[0], cell) {
|
||||||
CalcResult::Boolean(_) => return CalcResult::Boolean(true),
|
CalcResult::Boolean(_) => return CalcResult::Boolean(true),
|
||||||
@@ -50,7 +49,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
CalcResult::new_args_number_error(cell)
|
CalcResult::new_args_number_error(cell)
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_isblank(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_isblank(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 1 {
|
if args.len() == 1 {
|
||||||
match self.evaluate_node_in_context(&args[0], cell) {
|
match self.evaluate_node_in_context(&args[0], cell) {
|
||||||
CalcResult::EmptyCell => return CalcResult::Boolean(true),
|
CalcResult::EmptyCell => return CalcResult::Boolean(true),
|
||||||
@@ -61,7 +60,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
CalcResult::new_args_number_error(cell)
|
CalcResult::new_args_number_error(cell)
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_iserror(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_iserror(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 1 {
|
if args.len() == 1 {
|
||||||
match self.evaluate_node_in_context(&args[0], cell) {
|
match self.evaluate_node_in_context(&args[0], cell) {
|
||||||
CalcResult::Error { .. } => return CalcResult::Boolean(true),
|
CalcResult::Error { .. } => return CalcResult::Boolean(true),
|
||||||
@@ -72,7 +71,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
CalcResult::new_args_number_error(cell)
|
CalcResult::new_args_number_error(cell)
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_iserr(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_iserr(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 1 {
|
if args.len() == 1 {
|
||||||
match self.evaluate_node_in_context(&args[0], cell) {
|
match self.evaluate_node_in_context(&args[0], cell) {
|
||||||
CalcResult::Error { error, .. } => {
|
CalcResult::Error { error, .. } => {
|
||||||
@@ -89,7 +88,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
CalcResult::new_args_number_error(cell)
|
CalcResult::new_args_number_error(cell)
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_isna(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_isna(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 1 {
|
if args.len() == 1 {
|
||||||
match self.evaluate_node_in_context(&args[0], cell) {
|
match self.evaluate_node_in_context(&args[0], cell) {
|
||||||
CalcResult::Error { error, .. } => {
|
CalcResult::Error { error, .. } => {
|
||||||
@@ -109,7 +108,7 @@ impl Model {
|
|||||||
|
|
||||||
// Returns true if it is a reference or evaluates to a reference
|
// Returns true if it is a reference or evaluates to a reference
|
||||||
// But DOES NOT evaluate
|
// But DOES NOT evaluate
|
||||||
pub(crate) fn fn_isref(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_isref(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -122,7 +121,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_isodd(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_isodd(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -133,7 +132,7 @@ impl Model {
|
|||||||
CalcResult::Boolean(value % 2 == 1)
|
CalcResult::Boolean(value % 2 == 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_iseven(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_iseven(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -145,7 +144,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ISFORMULA arg needs to be a reference or something that evaluates to a reference
|
// ISFORMULA arg needs to be a reference or something that evaluates to a reference
|
||||||
pub(crate) fn fn_isformula(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_isformula(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -181,7 +180,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_errortype(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_errortype(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -220,7 +219,7 @@ impl Model {
|
|||||||
|
|
||||||
// Excel believes for some reason that TYPE(A1:A7) is an array formula
|
// Excel believes for some reason that TYPE(A1:A7) is an array formula
|
||||||
// Although we evaluate the same as Excel we cannot, ATM import this from excel
|
// Although we evaluate the same as Excel we cannot, ATM import this from excel
|
||||||
pub(crate) fn fn_type(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_type(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -237,7 +236,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_sheet(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_sheet(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if arg_count > 1 {
|
if arg_count > 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
calc_result::{CalcResult, CellReference},
|
calc_result::CalcResult,
|
||||||
expressions::parser::Node,
|
expressions::{parser::Node, token::Error, types::CellReferenceIndex},
|
||||||
expressions::token::Error,
|
|
||||||
model::Model,
|
model::Model,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::util::compare_values;
|
use super::util::compare_values;
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
pub(crate) fn fn_if(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_if(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 2 || args.len() == 3 {
|
if args.len() == 2 || args.len() == 3 {
|
||||||
let cond_result = self.get_boolean(&args[0], cell);
|
let cond_result = self.get_boolean(&args[0], cell);
|
||||||
let cond = match cond_result {
|
let cond = match cond_result {
|
||||||
@@ -28,7 +27,7 @@ impl Model {
|
|||||||
CalcResult::new_args_number_error(cell)
|
CalcResult::new_args_number_error(cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_iferror(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_iferror(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 2 {
|
if args.len() == 2 {
|
||||||
let value = self.evaluate_node_in_context(&args[0], cell);
|
let value = self.evaluate_node_in_context(&args[0], cell);
|
||||||
match value {
|
match value {
|
||||||
@@ -41,7 +40,7 @@ impl Model {
|
|||||||
CalcResult::new_args_number_error(cell)
|
CalcResult::new_args_number_error(cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_ifna(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_ifna(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 2 {
|
if args.len() == 2 {
|
||||||
let value = self.evaluate_node_in_context(&args[0], cell);
|
let value = self.evaluate_node_in_context(&args[0], cell);
|
||||||
if let CalcResult::Error { error, .. } = &value {
|
if let CalcResult::Error { error, .. } = &value {
|
||||||
@@ -54,7 +53,7 @@ impl Model {
|
|||||||
CalcResult::new_args_number_error(cell)
|
CalcResult::new_args_number_error(cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_not(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_not(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 1 {
|
if args.len() == 1 {
|
||||||
match self.get_boolean(&args[0], cell) {
|
match self.get_boolean(&args[0], cell) {
|
||||||
Ok(f) => return CalcResult::Boolean(!f),
|
Ok(f) => return CalcResult::Boolean(!f),
|
||||||
@@ -66,7 +65,7 @@ impl Model {
|
|||||||
CalcResult::new_args_number_error(cell)
|
CalcResult::new_args_number_error(cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_and(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_and(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let mut true_count = 0;
|
let mut true_count = 0;
|
||||||
for arg in args {
|
for arg in args {
|
||||||
match self.evaluate_node_in_context(arg, cell) {
|
match self.evaluate_node_in_context(arg, cell) {
|
||||||
@@ -95,7 +94,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
for row in left.row..(right.row + 1) {
|
for row in left.row..(right.row + 1) {
|
||||||
for column in left.column..(right.column + 1) {
|
for column in left.column..(right.column + 1) {
|
||||||
match self.evaluate_cell(CellReference {
|
match self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -136,7 +135,7 @@ impl Model {
|
|||||||
CalcResult::Boolean(true)
|
CalcResult::Boolean(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_or(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_or(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let mut result = false;
|
let mut result = false;
|
||||||
for arg in args {
|
for arg in args {
|
||||||
match self.evaluate_node_in_context(arg, cell) {
|
match self.evaluate_node_in_context(arg, cell) {
|
||||||
@@ -159,7 +158,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
for row in left.row..(right.row + 1) {
|
for row in left.row..(right.row + 1) {
|
||||||
for column in left.column..(right.column + 1) {
|
for column in left.column..(right.column + 1) {
|
||||||
match self.evaluate_cell(CellReference {
|
match self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -192,7 +191,7 @@ impl Model {
|
|||||||
/// XOR(logical1, [logical]*,...)
|
/// XOR(logical1, [logical]*,...)
|
||||||
/// Logical1 is required, subsequent logical values are optional. Can be logical values, arrays, or references.
|
/// Logical1 is required, subsequent logical values are optional. Can be logical values, arrays, or references.
|
||||||
/// The result of XOR is TRUE when the number of TRUE inputs is odd and FALSE when the number of TRUE inputs is even.
|
/// The result of XOR is TRUE when the number of TRUE inputs is odd and FALSE when the number of TRUE inputs is even.
|
||||||
pub(crate) fn fn_xor(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_xor(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let mut true_count = 0;
|
let mut true_count = 0;
|
||||||
let mut false_count = 0;
|
let mut false_count = 0;
|
||||||
for arg in args {
|
for arg in args {
|
||||||
@@ -221,7 +220,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
for row in left.row..(right.row + 1) {
|
for row in left.row..(right.row + 1) {
|
||||||
for column in left.column..(right.column + 1) {
|
for column in left.column..(right.column + 1) {
|
||||||
match self.evaluate_cell(CellReference {
|
match self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -255,7 +254,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// =SWITCH(expression, case1, value1, [case, value]*, [default])
|
/// =SWITCH(expression, case1, value1, [case, value]*, [default])
|
||||||
pub(crate) fn fn_switch(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_switch(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let args_count = args.len();
|
let args_count = args.len();
|
||||||
if args_count < 3 {
|
if args_count < 3 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -291,7 +290,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// =IFS(condition1, value, [condition, value]*)
|
/// =IFS(condition1, value, [condition, value]*)
|
||||||
pub(crate) fn fn_ifs(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_ifs(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let args_count = args.len();
|
let args_count = args.len();
|
||||||
if args_count < 2 {
|
if args_count < 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
use crate::constants::{LAST_COLUMN, LAST_ROW};
|
use crate::constants::{LAST_COLUMN, LAST_ROW};
|
||||||
|
use crate::expressions::types::CellReferenceIndex;
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_result::{CalcResult, CellReference},
|
calc_result::CalcResult, expressions::parser::Node, expressions::token::Error, model::Model,
|
||||||
expressions::parser::Node,
|
|
||||||
expressions::token::Error,
|
|
||||||
model::Model,
|
|
||||||
utils::ParsedReference,
|
utils::ParsedReference,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::util::{compare_values, from_wildcard_to_regex, result_matches_regex, values_are_equal};
|
use super::util::{compare_values, from_wildcard_to_regex, result_matches_regex, values_are_equal};
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
pub(crate) fn fn_index(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_index(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let row_num;
|
let row_num;
|
||||||
let col_num;
|
let col_num;
|
||||||
if args.len() == 3 {
|
if args.len() == 3 {
|
||||||
@@ -88,7 +86,7 @@ impl Model {
|
|||||||
message: "Wrong reference".to_string(),
|
message: "Wrong reference".to_string(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
self.evaluate_cell(CellReference {
|
self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -113,7 +111,7 @@ impl Model {
|
|||||||
// The match_type argument specifies how Excel matches lookup_value
|
// The match_type argument specifies how Excel matches lookup_value
|
||||||
// with values in lookup_array. The default value for this argument is 1.
|
// with values in lookup_array. The default value for this argument is 1.
|
||||||
// NOTE: Please read the caveat above in binary search
|
// NOTE: Please read the caveat above in binary search
|
||||||
pub(crate) fn fn_match(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_match(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() > 3 || args.len() < 2 {
|
if args.len() > 3 || args.len() < 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -174,7 +172,7 @@ impl Model {
|
|||||||
column = left.column + m;
|
column = left.column + m;
|
||||||
row = left.row;
|
row = left.row;
|
||||||
}
|
}
|
||||||
let value = self.evaluate_cell(CellReference {
|
let value = self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -238,7 +236,7 @@ impl Model {
|
|||||||
column = left.column + l;
|
column = left.column + l;
|
||||||
row = left.row;
|
row = left.row;
|
||||||
}
|
}
|
||||||
let value = self.evaluate_cell(CellReference {
|
let value = self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -294,7 +292,7 @@ impl Model {
|
|||||||
/// We look for `lookup_value` in the first row of table array
|
/// We look for `lookup_value` in the first row of table array
|
||||||
/// We return the value in row `row_index` of the same column in `table_array`
|
/// We return the value in row `row_index` of the same column in `table_array`
|
||||||
/// `is_sorted` is true by default and assumes that values in first row are ordered
|
/// `is_sorted` is true by default and assumes that values in first row are ordered
|
||||||
pub(crate) fn fn_hlookup(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_hlookup(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() > 4 || args.len() < 3 {
|
if args.len() > 4 || args.len() < 3 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -336,7 +334,7 @@ impl Model {
|
|||||||
message: "Invalid reference".to_string(),
|
message: "Invalid reference".to_string(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
self.evaluate_cell(CellReference {
|
self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -363,13 +361,13 @@ impl Model {
|
|||||||
Box::new(move |x| compare_values(x, &lookup_value) == 0)
|
Box::new(move |x| compare_values(x, &lookup_value) == 0)
|
||||||
};
|
};
|
||||||
for l in 0..n {
|
for l in 0..n {
|
||||||
let value = self.evaluate_cell(CellReference {
|
let value = self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row: left.row,
|
row: left.row,
|
||||||
column: left.column + l,
|
column: left.column + l,
|
||||||
});
|
});
|
||||||
if result_matches(&value) {
|
if result_matches(&value) {
|
||||||
return self.evaluate_cell(CellReference {
|
return self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column: left.column + l,
|
column: left.column + l,
|
||||||
@@ -401,7 +399,7 @@ impl Model {
|
|||||||
/// We look for `lookup_value` in the first column of table array
|
/// We look for `lookup_value` in the first column of table array
|
||||||
/// We return the value in column `column_index` of the same row in `table_array`
|
/// We return the value in column `column_index` of the same row in `table_array`
|
||||||
/// `is_sorted` is true by default and assumes that values in first column are ordered
|
/// `is_sorted` is true by default and assumes that values in first column are ordered
|
||||||
pub(crate) fn fn_vlookup(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_vlookup(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() > 4 || args.len() < 3 {
|
if args.len() > 4 || args.len() < 3 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -443,7 +441,7 @@ impl Model {
|
|||||||
message: "Invalid reference".to_string(),
|
message: "Invalid reference".to_string(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
self.evaluate_cell(CellReference {
|
self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -470,13 +468,13 @@ impl Model {
|
|||||||
Box::new(move |x| compare_values(x, &lookup_value) == 0)
|
Box::new(move |x| compare_values(x, &lookup_value) == 0)
|
||||||
};
|
};
|
||||||
for l in 0..n {
|
for l in 0..n {
|
||||||
let value = self.evaluate_cell(CellReference {
|
let value = self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row: left.row + l,
|
row: left.row + l,
|
||||||
column: left.column,
|
column: left.column,
|
||||||
});
|
});
|
||||||
if result_matches(&value) {
|
if result_matches(&value) {
|
||||||
return self.evaluate_cell(CellReference {
|
return self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row: left.row + l,
|
row: left.row + l,
|
||||||
column,
|
column,
|
||||||
@@ -512,7 +510,7 @@ impl Model {
|
|||||||
// TODO: Implement the other form of INDEX:
|
// TODO: Implement the other form of INDEX:
|
||||||
// INDEX(reference, row_num, [column_num], [area_num])
|
// INDEX(reference, row_num, [column_num], [area_num])
|
||||||
// NOTE: Please read the caveat above in binary search
|
// NOTE: Please read the caveat above in binary search
|
||||||
pub(crate) fn fn_lookup(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_lookup(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() > 3 || args.len() < 2 {
|
if args.len() > 3 || args.len() < 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -561,7 +559,7 @@ impl Model {
|
|||||||
column = l1.column + l;
|
column = l1.column + l;
|
||||||
row = l1.row;
|
row = l1.row;
|
||||||
}
|
}
|
||||||
self.evaluate_cell(CellReference {
|
self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -584,7 +582,7 @@ impl Model {
|
|||||||
column = left.column + l;
|
column = left.column + l;
|
||||||
row = left.row;
|
row = left.row;
|
||||||
}
|
}
|
||||||
self.evaluate_cell(CellReference {
|
self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -603,7 +601,7 @@ impl Model {
|
|||||||
// ROW([reference])
|
// ROW([reference])
|
||||||
// If reference is not present returns the row of the present cell.
|
// If reference is not present returns the row of the present cell.
|
||||||
// Otherwise returns the row number of reference
|
// Otherwise returns the row number of reference
|
||||||
pub(crate) fn fn_row(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_row(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() > 1 {
|
if args.len() > 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -618,7 +616,7 @@ impl Model {
|
|||||||
|
|
||||||
// ROWS(range)
|
// ROWS(range)
|
||||||
// Returns the number of rows in range
|
// Returns the number of rows in range
|
||||||
pub(crate) fn fn_rows(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_rows(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -631,7 +629,7 @@ impl Model {
|
|||||||
// COLUMN([reference])
|
// COLUMN([reference])
|
||||||
// If reference is not present returns the column of the present cell.
|
// If reference is not present returns the column of the present cell.
|
||||||
// Otherwise returns the column number of reference
|
// Otherwise returns the column number of reference
|
||||||
pub(crate) fn fn_column(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_column(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() > 1 {
|
if args.len() > 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -647,7 +645,7 @@ impl Model {
|
|||||||
|
|
||||||
/// CHOOSE(index_num, value1, [value2], ...)
|
/// CHOOSE(index_num, value1, [value2], ...)
|
||||||
/// Uses index_num to return a value from the list of value arguments.
|
/// Uses index_num to return a value from the list of value arguments.
|
||||||
pub(crate) fn fn_choose(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_choose(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() < 2 {
|
if args.len() < 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -670,7 +668,7 @@ impl Model {
|
|||||||
|
|
||||||
// COLUMNS(range)
|
// COLUMNS(range)
|
||||||
// Returns the number of columns in range
|
// Returns the number of columns in range
|
||||||
pub(crate) fn fn_columns(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_columns(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -682,7 +680,7 @@ impl Model {
|
|||||||
|
|
||||||
// INDIRECT(ref_tex)
|
// INDIRECT(ref_tex)
|
||||||
// Returns the reference specified by 'ref_text'
|
// Returns the reference specified by 'ref_text'
|
||||||
pub(crate) fn fn_indirect(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_indirect(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() > 2 || args.is_empty() {
|
if args.len() > 2 || args.is_empty() {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -731,7 +729,7 @@ impl Model {
|
|||||||
// Returns a reference to a range that is a specified number of rows and columns from a cell or range of cells.
|
// Returns a reference to a range that is a specified number of rows and columns from a cell or range of cells.
|
||||||
// The reference that is returned can be a single cell or a range of cells.
|
// The reference that is returned can be a single cell or a range of cells.
|
||||||
// You can specify the number of rows and the number of columns to be returned.
|
// You can specify the number of rows and the number of columns to be returned.
|
||||||
pub(crate) fn fn_offset(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_offset(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let l = args.len();
|
let l = args.len();
|
||||||
if !(3..=5).contains(&l) {
|
if !(3..=5).contains(&l) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -828,12 +826,12 @@ impl Model {
|
|||||||
message: "Invalid reference".to_string(),
|
message: "Invalid reference".to_string(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let left = CellReference {
|
let left = CellReferenceIndex {
|
||||||
sheet: reference.left.sheet,
|
sheet: reference.left.sheet,
|
||||||
row: row_start,
|
row: row_start,
|
||||||
column: column_start,
|
column: column_start,
|
||||||
};
|
};
|
||||||
let right = CellReference {
|
let right = CellReferenceIndex {
|
||||||
sheet: reference.right.sheet,
|
sheet: reference.right.sheet,
|
||||||
row: row_end,
|
row: row_end,
|
||||||
column: column_end,
|
column: column_end,
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
use crate::constants::{LAST_COLUMN, LAST_ROW};
|
use crate::constants::{LAST_COLUMN, LAST_ROW};
|
||||||
|
use crate::expressions::types::CellReferenceIndex;
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_result::{CalcResult, CellReference},
|
calc_result::CalcResult, expressions::parser::Node, expressions::token::Error, model::Model,
|
||||||
expressions::parser::Node,
|
|
||||||
expressions::token::Error,
|
|
||||||
model::Model,
|
|
||||||
};
|
};
|
||||||
use std::f64::consts::PI;
|
use std::f64::consts::PI;
|
||||||
|
|
||||||
@@ -19,7 +17,7 @@ pub fn random() -> f64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
pub(crate) fn fn_min(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_min(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let mut result = f64::NAN;
|
let mut result = f64::NAN;
|
||||||
for arg in args {
|
for arg in args {
|
||||||
match self.evaluate_node_in_context(arg, cell) {
|
match self.evaluate_node_in_context(arg, cell) {
|
||||||
@@ -34,7 +32,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
for row in left.row..(right.row + 1) {
|
for row in left.row..(right.row + 1) {
|
||||||
for column in left.column..(right.column + 1) {
|
for column in left.column..(right.column + 1) {
|
||||||
match self.evaluate_cell(CellReference {
|
match self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -62,7 +60,7 @@ impl Model {
|
|||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_max(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_max(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let mut result = f64::NAN;
|
let mut result = f64::NAN;
|
||||||
for arg in args {
|
for arg in args {
|
||||||
match self.evaluate_node_in_context(arg, cell) {
|
match self.evaluate_node_in_context(arg, cell) {
|
||||||
@@ -77,7 +75,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
for row in left.row..(right.row + 1) {
|
for row in left.row..(right.row + 1) {
|
||||||
for column in left.column..(right.column + 1) {
|
for column in left.column..(right.column + 1) {
|
||||||
match self.evaluate_cell(CellReference {
|
match self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -105,7 +103,7 @@ impl Model {
|
|||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_sum(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_sum(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -147,7 +145,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
for row in row1..row2 + 1 {
|
for row in row1..row2 + 1 {
|
||||||
for column in column1..(column2 + 1) {
|
for column in column1..(column2 + 1) {
|
||||||
match self.evaluate_cell(CellReference {
|
match self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -172,7 +170,7 @@ impl Model {
|
|||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_product(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_product(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -214,7 +212,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
for row in row1..row2 + 1 {
|
for row in row1..row2 + 1 {
|
||||||
for column in column1..(column2 + 1) {
|
for column in column1..(column2 + 1) {
|
||||||
match self.evaluate_cell(CellReference {
|
match self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -245,7 +243,7 @@ impl Model {
|
|||||||
|
|
||||||
/// SUMIF(criteria_range, criteria, [sum_range])
|
/// SUMIF(criteria_range, criteria, [sum_range])
|
||||||
/// if sum_rage is missing then criteria_range will be used
|
/// if sum_rage is missing then criteria_range will be used
|
||||||
pub(crate) fn fn_sumif(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_sumif(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 2 {
|
if args.len() == 2 {
|
||||||
let arguments = vec![args[0].clone(), args[0].clone(), args[1].clone()];
|
let arguments = vec![args[0].clone(), args[0].clone(), args[1].clone()];
|
||||||
self.fn_sumifs(&arguments, cell)
|
self.fn_sumifs(&arguments, cell)
|
||||||
@@ -258,7 +256,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// SUMIFS(sum_range, criteria_range1, criteria1, [criteria_range2, criteria2], ...)
|
/// SUMIFS(sum_range, criteria_range1, criteria1, [criteria_range2, criteria2], ...)
|
||||||
pub(crate) fn fn_sumifs(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_sumifs(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let mut total = 0.0;
|
let mut total = 0.0;
|
||||||
let sum = |value| total += value;
|
let sum = |value| total += value;
|
||||||
if let Err(e) = self.apply_ifs(args, cell, sum) {
|
if let Err(e) = self.apply_ifs(args, cell, sum) {
|
||||||
@@ -267,7 +265,7 @@ impl Model {
|
|||||||
CalcResult::Number(total)
|
CalcResult::Number(total)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_round(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_round(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
// Incorrect number of arguments
|
// Incorrect number of arguments
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -289,7 +287,7 @@ impl Model {
|
|||||||
let scale = 10.0_f64.powf(number_of_digits);
|
let scale = 10.0_f64.powf(number_of_digits);
|
||||||
CalcResult::Number((value * scale).round() / scale)
|
CalcResult::Number((value * scale).round() / scale)
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_roundup(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_roundup(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -314,7 +312,7 @@ impl Model {
|
|||||||
CalcResult::Number((value * scale).floor() / scale)
|
CalcResult::Number((value * scale).floor() / scale)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_rounddown(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_rounddown(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -340,7 +338,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_sin(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_sin(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -351,7 +349,7 @@ impl Model {
|
|||||||
let result = value.sin();
|
let result = value.sin();
|
||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_cos(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_cos(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -363,7 +361,7 @@ impl Model {
|
|||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_tan(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_tan(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -375,7 +373,7 @@ impl Model {
|
|||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_sinh(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_sinh(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -386,7 +384,7 @@ impl Model {
|
|||||||
let result = value.sinh();
|
let result = value.sinh();
|
||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_cosh(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_cosh(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -398,7 +396,7 @@ impl Model {
|
|||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_tanh(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_tanh(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -410,7 +408,7 @@ impl Model {
|
|||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_asin(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_asin(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -428,7 +426,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_acos(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_acos(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -447,7 +445,7 @@ impl Model {
|
|||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_atan(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_atan(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -466,7 +464,7 @@ impl Model {
|
|||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_asinh(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_asinh(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -484,7 +482,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_acosh(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_acosh(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -503,7 +501,7 @@ impl Model {
|
|||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_atanh(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_atanh(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -522,14 +520,14 @@ impl Model {
|
|||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_pi(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_pi(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if !args.is_empty() {
|
if !args.is_empty() {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
CalcResult::Number(PI)
|
CalcResult::Number(PI)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_abs(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_abs(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -540,7 +538,7 @@ impl Model {
|
|||||||
CalcResult::Number(value.abs())
|
CalcResult::Number(value.abs())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_sqrtpi(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_sqrtpi(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -558,7 +556,7 @@ impl Model {
|
|||||||
CalcResult::Number((value * PI).sqrt())
|
CalcResult::Number((value * PI).sqrt())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_sqrt(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_sqrt(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -576,7 +574,7 @@ impl Model {
|
|||||||
CalcResult::Number(value.sqrt())
|
CalcResult::Number(value.sqrt())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_atan2(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_atan2(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -598,7 +596,7 @@ impl Model {
|
|||||||
CalcResult::Number(f64::atan2(y, x))
|
CalcResult::Number(f64::atan2(y, x))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_power(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_power(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -639,7 +637,7 @@ impl Model {
|
|||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_rand(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_rand(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if !args.is_empty() {
|
if !args.is_empty() {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -647,7 +645,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add tests for RANDBETWEEN
|
// TODO: Add tests for RANDBETWEEN
|
||||||
pub(crate) fn fn_randbetween(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_randbetween(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_result::{CalcResult, CellReference},
|
calc_result::CalcResult,
|
||||||
expressions::{parser::Node, token::Error},
|
expressions::{parser::Node, token::Error, types::CellReferenceIndex},
|
||||||
model::Model,
|
model::Model,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -713,7 +713,7 @@ impl Model {
|
|||||||
&mut self,
|
&mut self,
|
||||||
kind: &Function,
|
kind: &Function,
|
||||||
args: &[Node],
|
args: &[Node],
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
) -> CalcResult {
|
) -> CalcResult {
|
||||||
match kind {
|
match kind {
|
||||||
// Logical
|
// Logical
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use crate::constants::{LAST_COLUMN, LAST_ROW};
|
use crate::constants::{LAST_COLUMN, LAST_ROW};
|
||||||
|
use crate::expressions::types::CellReferenceIndex;
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_result::{CalcResult, CellReference, Range},
|
calc_result::{CalcResult, Range},
|
||||||
expressions::parser::Node,
|
expressions::parser::Node,
|
||||||
expressions::token::Error,
|
expressions::token::Error,
|
||||||
model::Model,
|
model::Model,
|
||||||
@@ -9,7 +10,7 @@ use crate::{
|
|||||||
use super::util::build_criteria;
|
use super::util::build_criteria;
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
pub(crate) fn fn_average(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_average(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -38,7 +39,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
for row in left.row..(right.row + 1) {
|
for row in left.row..(right.row + 1) {
|
||||||
for column in left.column..(right.column + 1) {
|
for column in left.column..(right.column + 1) {
|
||||||
match self.evaluate_cell(CellReference {
|
match self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -90,7 +91,7 @@ impl Model {
|
|||||||
CalcResult::Number(sum / count)
|
CalcResult::Number(sum / count)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_averagea(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_averagea(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -108,7 +109,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
for row in left.row..(right.row + 1) {
|
for row in left.row..(right.row + 1) {
|
||||||
for column in left.column..(right.column + 1) {
|
for column in left.column..(right.column + 1) {
|
||||||
match self.evaluate_cell(CellReference {
|
match self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -176,7 +177,7 @@ impl Model {
|
|||||||
CalcResult::Number(sum / count)
|
CalcResult::Number(sum / count)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_count(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_count(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -206,7 +207,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
for row in left.row..(right.row + 1) {
|
for row in left.row..(right.row + 1) {
|
||||||
for column in left.column..(right.column + 1) {
|
for column in left.column..(right.column + 1) {
|
||||||
if let CalcResult::Number(_) = self.evaluate_cell(CellReference {
|
if let CalcResult::Number(_) = self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -224,7 +225,7 @@ impl Model {
|
|||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_counta(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_counta(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -242,7 +243,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
for row in left.row..(right.row + 1) {
|
for row in left.row..(right.row + 1) {
|
||||||
for column in left.column..(right.column + 1) {
|
for column in left.column..(right.column + 1) {
|
||||||
match self.evaluate_cell(CellReference {
|
match self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -263,7 +264,7 @@ impl Model {
|
|||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_countblank(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_countblank(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
// COUNTBLANK requires only one argument
|
// COUNTBLANK requires only one argument
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -287,7 +288,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
for row in left.row..(right.row + 1) {
|
for row in left.row..(right.row + 1) {
|
||||||
for column in left.column..(right.column + 1) {
|
for column in left.column..(right.column + 1) {
|
||||||
match self.evaluate_cell(CellReference {
|
match self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -309,7 +310,7 @@ impl Model {
|
|||||||
CalcResult::Number(result)
|
CalcResult::Number(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_countif(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_countif(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 2 {
|
if args.len() == 2 {
|
||||||
let arguments = vec![args[0].clone(), args[1].clone()];
|
let arguments = vec![args[0].clone(), args[1].clone()];
|
||||||
self.fn_countifs(&arguments, cell)
|
self.fn_countifs(&arguments, cell)
|
||||||
@@ -320,7 +321,7 @@ impl Model {
|
|||||||
|
|
||||||
/// AVERAGEIF(criteria_range, criteria, [average_range])
|
/// AVERAGEIF(criteria_range, criteria, [average_range])
|
||||||
/// if average_rage is missing then criteria_range will be used
|
/// if average_rage is missing then criteria_range will be used
|
||||||
pub(crate) fn fn_averageif(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_averageif(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 2 {
|
if args.len() == 2 {
|
||||||
let arguments = vec![args[0].clone(), args[0].clone(), args[1].clone()];
|
let arguments = vec![args[0].clone(), args[0].clone(), args[1].clone()];
|
||||||
self.fn_averageifs(&arguments, cell)
|
self.fn_averageifs(&arguments, cell)
|
||||||
@@ -333,7 +334,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: This function shares a lot of code with apply_ifs. Can we merge them?
|
// FIXME: This function shares a lot of code with apply_ifs. Can we merge them?
|
||||||
pub(crate) fn fn_countifs(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_countifs(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let args_count = args.len();
|
let args_count = args.len();
|
||||||
if args_count < 2 || args_count % 2 == 1 {
|
if args_count < 2 || args_count % 2 == 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -428,7 +429,7 @@ impl Model {
|
|||||||
// We check if value in range n meets criterion n
|
// We check if value in range n meets criterion n
|
||||||
let range = &ranges[case_index];
|
let range = &ranges[case_index];
|
||||||
let fn_criterion = &fn_criteria[case_index];
|
let fn_criterion = &fn_criteria[case_index];
|
||||||
let value = self.evaluate_cell(CellReference {
|
let value = self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: range.left.sheet,
|
sheet: range.left.sheet,
|
||||||
row: range.left.row + row - first_range.left.row,
|
row: range.left.row + row - first_range.left.row,
|
||||||
column: range.left.column + column - first_range.left.column,
|
column: range.left.column + column - first_range.left.column,
|
||||||
@@ -449,7 +450,7 @@ impl Model {
|
|||||||
pub(crate) fn apply_ifs<F>(
|
pub(crate) fn apply_ifs<F>(
|
||||||
&mut self,
|
&mut self,
|
||||||
args: &[Node],
|
args: &[Node],
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
mut apply: F,
|
mut apply: F,
|
||||||
) -> Result<(), CalcResult>
|
) -> Result<(), CalcResult>
|
||||||
where
|
where
|
||||||
@@ -548,7 +549,7 @@ impl Model {
|
|||||||
// We check if value in range n meets criterion n
|
// We check if value in range n meets criterion n
|
||||||
let range = &ranges[case_index];
|
let range = &ranges[case_index];
|
||||||
let fn_criterion = &fn_criteria[case_index];
|
let fn_criterion = &fn_criteria[case_index];
|
||||||
let value = self.evaluate_cell(CellReference {
|
let value = self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: range.left.sheet,
|
sheet: range.left.sheet,
|
||||||
row: range.left.row + row - sum_range.left.row,
|
row: range.left.row + row - sum_range.left.row,
|
||||||
column: range.left.column + column - sum_range.left.column,
|
column: range.left.column + column - sum_range.left.column,
|
||||||
@@ -559,7 +560,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if is_true {
|
if is_true {
|
||||||
let v = self.evaluate_cell(CellReference {
|
let v = self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: sum_range.left.sheet,
|
sheet: sum_range.left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -575,7 +576,7 @@ impl Model {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_averageifs(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_averageifs(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let mut total = 0.0;
|
let mut total = 0.0;
|
||||||
let mut count = 0.0;
|
let mut count = 0.0;
|
||||||
|
|
||||||
@@ -597,7 +598,7 @@ impl Model {
|
|||||||
CalcResult::Number(total / count)
|
CalcResult::Number(total / count)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_minifs(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_minifs(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let mut min = f64::INFINITY;
|
let mut min = f64::INFINITY;
|
||||||
let apply_min = |value: f64| min = value.min(min);
|
let apply_min = |value: f64| min = value.min(min);
|
||||||
if let Err(e) = self.apply_ifs(args, cell, apply_min) {
|
if let Err(e) = self.apply_ifs(args, cell, apply_min) {
|
||||||
@@ -610,7 +611,7 @@ impl Model {
|
|||||||
CalcResult::Number(min)
|
CalcResult::Number(min)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_maxifs(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_maxifs(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let mut max = -f64::INFINITY;
|
let mut max = -f64::INFINITY;
|
||||||
let apply_max = |value: f64| max = value.max(max);
|
let apply_max = |value: f64| max = value.max(max);
|
||||||
if let Err(e) = self.apply_ifs(args, cell, apply_max) {
|
if let Err(e) = self.apply_ifs(args, cell, apply_max) {
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
calc_result::{CalcResult, CellReference},
|
calc_result::CalcResult,
|
||||||
expressions::{
|
expressions::{
|
||||||
parser::{parse_range, Node},
|
parser::{parse_range, Node},
|
||||||
token::Error,
|
token::Error,
|
||||||
|
types::CellReferenceIndex,
|
||||||
},
|
},
|
||||||
functions::Function,
|
functions::Function,
|
||||||
model::Model,
|
model::Model,
|
||||||
@@ -106,7 +107,7 @@ impl Model {
|
|||||||
fn subtotal_get_values(
|
fn subtotal_get_values(
|
||||||
&mut self,
|
&mut self,
|
||||||
args: &[Node],
|
args: &[Node],
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
mode: SubTotalMode,
|
mode: SubTotalMode,
|
||||||
) -> Result<Vec<f64>, CalcResult> {
|
) -> Result<Vec<f64>, CalcResult> {
|
||||||
let mut result: Vec<f64> = Vec::new();
|
let mut result: Vec<f64> = Vec::new();
|
||||||
@@ -155,7 +156,7 @@ impl Model {
|
|||||||
if self.cell_is_subtotal(left.sheet, row, column) {
|
if self.cell_is_subtotal(left.sheet, row, column) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
match self.evaluate_cell(CellReference {
|
match self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -179,7 +180,7 @@ impl Model {
|
|||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_subtotal(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_subtotal(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() < 2 {
|
if args.len() < 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -221,7 +222,7 @@ impl Model {
|
|||||||
fn subtotal_vars(
|
fn subtotal_vars(
|
||||||
&mut self,
|
&mut self,
|
||||||
args: &[Node],
|
args: &[Node],
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
mode: SubTotalMode,
|
mode: SubTotalMode,
|
||||||
) -> CalcResult {
|
) -> CalcResult {
|
||||||
let values = match self.subtotal_get_values(args, cell, mode) {
|
let values = match self.subtotal_get_values(args, cell, mode) {
|
||||||
@@ -253,7 +254,7 @@ impl Model {
|
|||||||
fn subtotal_varp(
|
fn subtotal_varp(
|
||||||
&mut self,
|
&mut self,
|
||||||
args: &[Node],
|
args: &[Node],
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
mode: SubTotalMode,
|
mode: SubTotalMode,
|
||||||
) -> CalcResult {
|
) -> CalcResult {
|
||||||
let values = match self.subtotal_get_values(args, cell, mode) {
|
let values = match self.subtotal_get_values(args, cell, mode) {
|
||||||
@@ -284,7 +285,7 @@ impl Model {
|
|||||||
fn subtotal_stdevs(
|
fn subtotal_stdevs(
|
||||||
&mut self,
|
&mut self,
|
||||||
args: &[Node],
|
args: &[Node],
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
mode: SubTotalMode,
|
mode: SubTotalMode,
|
||||||
) -> CalcResult {
|
) -> CalcResult {
|
||||||
let values = match self.subtotal_get_values(args, cell, mode) {
|
let values = match self.subtotal_get_values(args, cell, mode) {
|
||||||
@@ -316,7 +317,7 @@ impl Model {
|
|||||||
fn subtotal_stdevp(
|
fn subtotal_stdevp(
|
||||||
&mut self,
|
&mut self,
|
||||||
args: &[Node],
|
args: &[Node],
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
mode: SubTotalMode,
|
mode: SubTotalMode,
|
||||||
) -> CalcResult {
|
) -> CalcResult {
|
||||||
let values = match self.subtotal_get_values(args, cell, mode) {
|
let values = match self.subtotal_get_values(args, cell, mode) {
|
||||||
@@ -347,7 +348,7 @@ impl Model {
|
|||||||
fn subtotal_counta(
|
fn subtotal_counta(
|
||||||
&mut self,
|
&mut self,
|
||||||
args: &[Node],
|
args: &[Node],
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
mode: SubTotalMode,
|
mode: SubTotalMode,
|
||||||
) -> CalcResult {
|
) -> CalcResult {
|
||||||
let mut counta = 0;
|
let mut counta = 0;
|
||||||
@@ -392,7 +393,7 @@ impl Model {
|
|||||||
if self.cell_is_subtotal(left.sheet, row, column) {
|
if self.cell_is_subtotal(left.sheet, row, column) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
match self.evaluate_cell(CellReference {
|
match self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -419,7 +420,7 @@ impl Model {
|
|||||||
fn subtotal_count(
|
fn subtotal_count(
|
||||||
&mut self,
|
&mut self,
|
||||||
args: &[Node],
|
args: &[Node],
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
mode: SubTotalMode,
|
mode: SubTotalMode,
|
||||||
) -> CalcResult {
|
) -> CalcResult {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
@@ -462,7 +463,7 @@ impl Model {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let CalcResult::Number(_) =
|
if let CalcResult::Number(_) =
|
||||||
self.evaluate_cell(CellReference {
|
self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -486,7 +487,7 @@ impl Model {
|
|||||||
fn subtotal_average(
|
fn subtotal_average(
|
||||||
&mut self,
|
&mut self,
|
||||||
args: &[Node],
|
args: &[Node],
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
mode: SubTotalMode,
|
mode: SubTotalMode,
|
||||||
) -> CalcResult {
|
) -> CalcResult {
|
||||||
let values = match self.subtotal_get_values(args, cell, mode) {
|
let values = match self.subtotal_get_values(args, cell, mode) {
|
||||||
@@ -511,7 +512,7 @@ impl Model {
|
|||||||
fn subtotal_sum(
|
fn subtotal_sum(
|
||||||
&mut self,
|
&mut self,
|
||||||
args: &[Node],
|
args: &[Node],
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
mode: SubTotalMode,
|
mode: SubTotalMode,
|
||||||
) -> CalcResult {
|
) -> CalcResult {
|
||||||
let values = match self.subtotal_get_values(args, cell, mode) {
|
let values = match self.subtotal_get_values(args, cell, mode) {
|
||||||
@@ -528,7 +529,7 @@ impl Model {
|
|||||||
fn subtotal_product(
|
fn subtotal_product(
|
||||||
&mut self,
|
&mut self,
|
||||||
args: &[Node],
|
args: &[Node],
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
mode: SubTotalMode,
|
mode: SubTotalMode,
|
||||||
) -> CalcResult {
|
) -> CalcResult {
|
||||||
let values = match self.subtotal_get_values(args, cell, mode) {
|
let values = match self.subtotal_get_values(args, cell, mode) {
|
||||||
@@ -545,7 +546,7 @@ impl Model {
|
|||||||
fn subtotal_max(
|
fn subtotal_max(
|
||||||
&mut self,
|
&mut self,
|
||||||
args: &[Node],
|
args: &[Node],
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
mode: SubTotalMode,
|
mode: SubTotalMode,
|
||||||
) -> CalcResult {
|
) -> CalcResult {
|
||||||
let values = match self.subtotal_get_values(args, cell, mode) {
|
let values = match self.subtotal_get_values(args, cell, mode) {
|
||||||
@@ -565,7 +566,7 @@ impl Model {
|
|||||||
fn subtotal_min(
|
fn subtotal_min(
|
||||||
&mut self,
|
&mut self,
|
||||||
args: &[Node],
|
args: &[Node],
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
mode: SubTotalMode,
|
mode: SubTotalMode,
|
||||||
) -> CalcResult {
|
) -> CalcResult {
|
||||||
let values = match self.subtotal_get_values(args, cell, mode) {
|
let values = match self.subtotal_get_values(args, cell, mode) {
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
calc_result::{CalcResult, CellReference},
|
calc_result::CalcResult,
|
||||||
constants::{LAST_COLUMN, LAST_ROW},
|
constants::{LAST_COLUMN, LAST_ROW},
|
||||||
expressions::parser::Node,
|
expressions::{parser::Node, token::Error, types::CellReferenceIndex},
|
||||||
expressions::token::Error,
|
|
||||||
formatter::format::{format_number, parse_formatted_number},
|
formatter::format::{format_number, parse_formatted_number},
|
||||||
model::Model,
|
model::Model,
|
||||||
number_format::to_precision,
|
number_format::to_precision,
|
||||||
@@ -52,7 +51,7 @@ fn search(search_for: &str, text: &str, start: usize) -> Option<i32> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
pub(crate) fn fn_concat(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_concat(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let mut result = "".to_string();
|
let mut result = "".to_string();
|
||||||
for arg in args {
|
for arg in args {
|
||||||
match self.evaluate_node_in_context(arg, cell) {
|
match self.evaluate_node_in_context(arg, cell) {
|
||||||
@@ -77,7 +76,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
for row in left.row..(right.row + 1) {
|
for row in left.row..(right.row + 1) {
|
||||||
for column in left.column..(right.column + 1) {
|
for column in left.column..(right.column + 1) {
|
||||||
match self.evaluate_cell(CellReference {
|
match self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -106,7 +105,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
CalcResult::String(result)
|
CalcResult::String(result)
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_text(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_text(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 2 {
|
if args.len() == 2 {
|
||||||
let value = match self.evaluate_node_in_context(&args[0], cell) {
|
let value = match self.evaluate_node_in_context(&args[0], cell) {
|
||||||
CalcResult::Number(f) => f,
|
CalcResult::Number(f) => f,
|
||||||
@@ -153,7 +152,7 @@ impl Model {
|
|||||||
/// * If start_num is not greater than zero, FIND and FINDB return the #VALUE! error value.
|
/// * If start_num is not greater than zero, FIND and FINDB return the #VALUE! error value.
|
||||||
/// * If start_num is greater than the length of within_text, FIND and FINDB return the #VALUE! error value.
|
/// * If start_num is greater than the length of within_text, FIND and FINDB return the #VALUE! error value.
|
||||||
/// NB: FINDB is not implemented. It is the same as FIND function unless locale is a DBCS (Double Byte Character Set)
|
/// NB: FINDB is not implemented. It is the same as FIND function unless locale is a DBCS (Double Byte Character Set)
|
||||||
pub(crate) fn fn_find(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_find(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() < 2 || args.len() > 3 {
|
if args.len() < 2 || args.len() > 3 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -205,7 +204,7 @@ impl Model {
|
|||||||
/// * Allows wildcards
|
/// * Allows wildcards
|
||||||
/// * It is case insensitive
|
/// * It is case insensitive
|
||||||
/// SEARCH(find_text, within_text, [start_num])
|
/// SEARCH(find_text, within_text, [start_num])
|
||||||
pub(crate) fn fn_search(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_search(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() < 2 || args.len() > 3 {
|
if args.len() < 2 || args.len() > 3 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -259,7 +258,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// LEN, LEFT, RIGHT, MID, LOWER, UPPER, TRIM
|
// LEN, LEFT, RIGHT, MID, LOWER, UPPER, TRIM
|
||||||
pub(crate) fn fn_len(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_len(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 1 {
|
if args.len() == 1 {
|
||||||
let s = match self.evaluate_node_in_context(&args[0], cell) {
|
let s = match self.evaluate_node_in_context(&args[0], cell) {
|
||||||
CalcResult::Number(v) => format!("{}", v),
|
CalcResult::Number(v) => format!("{}", v),
|
||||||
@@ -287,7 +286,7 @@ impl Model {
|
|||||||
CalcResult::new_args_number_error(cell)
|
CalcResult::new_args_number_error(cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_trim(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_trim(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 1 {
|
if args.len() == 1 {
|
||||||
let s = match self.evaluate_node_in_context(&args[0], cell) {
|
let s = match self.evaluate_node_in_context(&args[0], cell) {
|
||||||
CalcResult::Number(v) => format!("{}", v),
|
CalcResult::Number(v) => format!("{}", v),
|
||||||
@@ -315,7 +314,7 @@ impl Model {
|
|||||||
CalcResult::new_args_number_error(cell)
|
CalcResult::new_args_number_error(cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_lower(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_lower(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 1 {
|
if args.len() == 1 {
|
||||||
let s = match self.evaluate_node_in_context(&args[0], cell) {
|
let s = match self.evaluate_node_in_context(&args[0], cell) {
|
||||||
CalcResult::Number(v) => format!("{}", v),
|
CalcResult::Number(v) => format!("{}", v),
|
||||||
@@ -343,7 +342,7 @@ impl Model {
|
|||||||
CalcResult::new_args_number_error(cell)
|
CalcResult::new_args_number_error(cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_upper(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_upper(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() == 1 {
|
if args.len() == 1 {
|
||||||
let s = match self.evaluate_node_in_context(&args[0], cell) {
|
let s = match self.evaluate_node_in_context(&args[0], cell) {
|
||||||
CalcResult::Number(v) => format!("{}", v),
|
CalcResult::Number(v) => format!("{}", v),
|
||||||
@@ -371,7 +370,7 @@ impl Model {
|
|||||||
CalcResult::new_args_number_error(cell)
|
CalcResult::new_args_number_error(cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_left(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_left(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() > 2 || args.is_empty() {
|
if args.len() > 2 || args.is_empty() {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -439,7 +438,7 @@ impl Model {
|
|||||||
CalcResult::String(result)
|
CalcResult::String(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_right(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_right(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() > 2 || args.is_empty() {
|
if args.len() > 2 || args.is_empty() {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -507,7 +506,7 @@ impl Model {
|
|||||||
return CalcResult::String(result.chars().rev().collect::<String>());
|
return CalcResult::String(result.chars().rev().collect::<String>());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_mid(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_mid(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 3 {
|
if args.len() != 3 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -611,7 +610,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// REPT(text, number_times)
|
// REPT(text, number_times)
|
||||||
pub(crate) fn fn_rept(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_rept(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -648,7 +647,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TEXTAFTER(text, delimiter, [instance_num], [match_mode], [match_end], [if_not_found])
|
// TEXTAFTER(text, delimiter, [instance_num], [match_mode], [match_end], [if_not_found])
|
||||||
pub(crate) fn fn_textafter(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_textafter(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if !(2..=6).contains(&arg_count) {
|
if !(2..=6).contains(&arg_count) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -753,7 +752,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_textbefore(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_textbefore(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if !(2..=6).contains(&arg_count) {
|
if !(2..=6).contains(&arg_count) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -859,7 +858,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TEXTJOIN(delimiter, ignore_empty, text1, [text2], …)
|
// TEXTJOIN(delimiter, ignore_empty, text1, [text2], …)
|
||||||
pub(crate) fn fn_textjoin(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_textjoin(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if arg_count < 3 {
|
if arg_count < 3 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -906,7 +905,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
for row in row1..row2 + 1 {
|
for row in row1..row2 + 1 {
|
||||||
for column in column1..(column2 + 1) {
|
for column in column1..(column2 + 1) {
|
||||||
match self.evaluate_cell(CellReference {
|
match self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -955,7 +954,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SUBSTITUTE(text, old_text, new_text, [instance_num])
|
// SUBSTITUTE(text, old_text, new_text, [instance_num])
|
||||||
pub(crate) fn fn_substitute(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_substitute(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if !(2..=4).contains(&arg_count) {
|
if !(2..=4).contains(&arg_count) {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -1000,7 +999,7 @@ impl Model {
|
|||||||
CalcResult::String(text.replace(&old_text, &new_text))
|
CalcResult::String(text.replace(&old_text, &new_text))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn fn_concatenate(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_concatenate(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
let arg_count = args.len();
|
let arg_count = args.len();
|
||||||
if arg_count == 0 {
|
if arg_count == 0 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
@@ -1016,7 +1015,7 @@ impl Model {
|
|||||||
CalcResult::String(text_array.join(""))
|
CalcResult::String(text_array.join(""))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_exact(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_exact(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -1039,7 +1038,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// VALUE(text)
|
// VALUE(text)
|
||||||
pub(crate) fn fn_value(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_value(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -1074,7 +1073,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_t(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_t(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -1088,7 +1087,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VALUETOTEXT(value)
|
// VALUETOTEXT(value)
|
||||||
pub(crate) fn fn_valuetotext(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_valuetotext(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
use crate::constants::{LAST_COLUMN, LAST_ROW};
|
use crate::constants::{LAST_COLUMN, LAST_ROW};
|
||||||
|
use crate::expressions::types::CellReferenceIndex;
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_result::{CalcResult, CellReference},
|
calc_result::CalcResult, expressions::parser::Node, expressions::token::Error, model::Model,
|
||||||
expressions::parser::Node,
|
|
||||||
expressions::token::Error,
|
|
||||||
model::Model,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@@ -146,7 +144,7 @@ impl Model {
|
|||||||
/// in ascending order. If not sorted, invalid results will be returned.
|
/// in ascending order. If not sorted, invalid results will be returned.
|
||||||
/// * -2 - Perform a binary search that relies on lookup_array being sorted
|
/// * -2 - Perform a binary search that relies on lookup_array being sorted
|
||||||
/// in descending order. If not sorted, invalid results will be returned.
|
/// in descending order. If not sorted, invalid results will be returned.
|
||||||
pub(crate) fn fn_xlookup(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
|
pub(crate) fn fn_xlookup(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if args.len() < 3 || args.len() > 6 {
|
if args.len() < 3 || args.len() > 6 {
|
||||||
return CalcResult::new_args_number_error(cell);
|
return CalcResult::new_args_number_error(cell);
|
||||||
}
|
}
|
||||||
@@ -268,12 +266,12 @@ impl Model {
|
|||||||
.dimension()
|
.dimension()
|
||||||
.max_column;
|
.max_column;
|
||||||
}
|
}
|
||||||
let left = CellReference {
|
let left = CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
column: column1,
|
column: column1,
|
||||||
row: row1,
|
row: row1,
|
||||||
};
|
};
|
||||||
let right = CellReference {
|
let right = CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
column: column2,
|
column: column2,
|
||||||
row: row2,
|
row: row2,
|
||||||
@@ -287,7 +285,7 @@ impl Model {
|
|||||||
if is_row_vector { index as i32 } else { 0 };
|
if is_row_vector { index as i32 } else { 0 };
|
||||||
let column_index =
|
let column_index =
|
||||||
if is_row_vector { 0 } else { index as i32 };
|
if is_row_vector { 0 } else { index as i32 };
|
||||||
self.evaluate_cell(CellReference {
|
self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: result_left.sheet,
|
sheet: result_left.sheet,
|
||||||
row: result_left.row + row_index,
|
row: result_left.row + row_index,
|
||||||
column: result_left.column + column_index,
|
column: result_left.column + column_index,
|
||||||
@@ -329,14 +327,14 @@ impl Model {
|
|||||||
let column =
|
let column =
|
||||||
result_left.column + if is_row_vector { 0 } else { l };
|
result_left.column + if is_row_vector { 0 } else { l };
|
||||||
if match_mode == MatchMode::ExactMatch {
|
if match_mode == MatchMode::ExactMatch {
|
||||||
let value = self.evaluate_cell(CellReference {
|
let value = self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: left.sheet,
|
sheet: left.sheet,
|
||||||
row: left.row + if is_row_vector { l } else { 0 },
|
row: left.row + if is_row_vector { l } else { 0 },
|
||||||
column: left.column
|
column: left.column
|
||||||
+ if is_row_vector { 0 } else { l },
|
+ if is_row_vector { 0 } else { l },
|
||||||
});
|
});
|
||||||
if compare_values(&value, &lookup_value) == 0 {
|
if compare_values(&value, &lookup_value) == 0 {
|
||||||
self.evaluate_cell(CellReference {
|
self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: result_left.sheet,
|
sheet: result_left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
@@ -347,7 +345,7 @@ impl Model {
|
|||||||
} else if match_mode == MatchMode::ExactMatchSmaller
|
} else if match_mode == MatchMode::ExactMatchSmaller
|
||||||
|| match_mode == MatchMode::ExactMatchLarger
|
|| match_mode == MatchMode::ExactMatchLarger
|
||||||
{
|
{
|
||||||
self.evaluate_cell(CellReference {
|
self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: result_left.sheet,
|
sheet: result_left.sheet,
|
||||||
row,
|
row,
|
||||||
column,
|
column,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::calc_result::{CellReference, Range};
|
use crate::{calc_result::Range, expressions::types::CellReferenceIndex};
|
||||||
|
|
||||||
/// It returns the closest cell from cell_reference to range in the same column/row
|
/// It returns the closest cell from cell_reference to range in the same column/row
|
||||||
/// Examples
|
/// Examples
|
||||||
@@ -6,9 +6,9 @@ use crate::calc_result::{CellReference, Range};
|
|||||||
/// * i_i(B5, A7:A9) -> None
|
/// * i_i(B5, A7:A9) -> None
|
||||||
/// * i_i(B5, A2:D2) -> B2
|
/// * i_i(B5, A2:D2) -> B2
|
||||||
pub(crate) fn implicit_intersection(
|
pub(crate) fn implicit_intersection(
|
||||||
cell_reference: &CellReference,
|
cell_reference: &CellReferenceIndex,
|
||||||
range: &Range,
|
range: &Range,
|
||||||
) -> Option<CellReference> {
|
) -> Option<CellReferenceIndex> {
|
||||||
let left = &range.left;
|
let left = &range.left;
|
||||||
let right = &range.right;
|
let right = &range.right;
|
||||||
let sheet = cell_reference.sheet;
|
let sheet = cell_reference.sheet;
|
||||||
@@ -22,7 +22,7 @@ pub(crate) fn implicit_intersection(
|
|||||||
if left.column != right.column {
|
if left.column != right.column {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
return Some(CellReference {
|
return Some(CellReferenceIndex {
|
||||||
sheet,
|
sheet,
|
||||||
row,
|
row,
|
||||||
column: left.column,
|
column: left.column,
|
||||||
@@ -31,14 +31,14 @@ pub(crate) fn implicit_intersection(
|
|||||||
if left.row != right.row {
|
if left.row != right.row {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
return Some(CellReference {
|
return Some(CellReferenceIndex {
|
||||||
sheet,
|
sheet,
|
||||||
row: left.row,
|
row: left.row,
|
||||||
column,
|
column,
|
||||||
});
|
});
|
||||||
} else if left.row == right.row && left.column == right.column {
|
} else if left.row == right.row && left.column == right.column {
|
||||||
// If the range is a single cell, then return it.
|
// If the range is a single cell, then return it.
|
||||||
return Some(CellReference {
|
return Some(CellReferenceIndex {
|
||||||
sheet,
|
sheet,
|
||||||
row: left.row,
|
row: left.row,
|
||||||
column: right.column,
|
column: right.column,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use std::collections::HashMap;
|
|||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_result::{CalcResult, CellReference, Range},
|
calc_result::{CalcResult, Range},
|
||||||
cell::CellValue,
|
cell::CellValue,
|
||||||
constants::{self, LAST_COLUMN, LAST_ROW},
|
constants::{self, LAST_COLUMN, LAST_ROW},
|
||||||
expressions::token::{Error, OpCompare, OpProduct, OpSum, OpUnary},
|
expressions::token::{Error, OpCompare, OpProduct, OpSum, OpUnary},
|
||||||
@@ -77,7 +77,7 @@ pub enum CellState {
|
|||||||
/// A parsed formula for a defined name
|
/// A parsed formula for a defined name
|
||||||
pub enum ParsedDefinedName {
|
pub enum ParsedDefinedName {
|
||||||
/// CellReference (`=C4`)
|
/// CellReference (`=C4`)
|
||||||
CellReference(CellReference),
|
CellReference(CellReferenceIndex),
|
||||||
/// A Range (`=C4:D6`)
|
/// A Range (`=C4:D6`)
|
||||||
RangeReference(Range),
|
RangeReference(Range),
|
||||||
/// `=SomethingElse`
|
/// `=SomethingElse`
|
||||||
@@ -135,7 +135,7 @@ impl Model {
|
|||||||
pub(crate) fn evaluate_node_with_reference(
|
pub(crate) fn evaluate_node_with_reference(
|
||||||
&mut self,
|
&mut self,
|
||||||
node: &Node,
|
node: &Node,
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
) -> CalcResult {
|
) -> CalcResult {
|
||||||
match node {
|
match node {
|
||||||
Node::ReferenceKind {
|
Node::ReferenceKind {
|
||||||
@@ -155,12 +155,12 @@ impl Model {
|
|||||||
column1 += cell.column;
|
column1 += cell.column;
|
||||||
}
|
}
|
||||||
CalcResult::Range {
|
CalcResult::Range {
|
||||||
left: CellReference {
|
left: CellReferenceIndex {
|
||||||
sheet: *sheet_index,
|
sheet: *sheet_index,
|
||||||
row: row1,
|
row: row1,
|
||||||
column: column1,
|
column: column1,
|
||||||
},
|
},
|
||||||
right: CellReference {
|
right: CellReferenceIndex {
|
||||||
sheet: *sheet_index,
|
sheet: *sheet_index,
|
||||||
row: row1,
|
row: row1,
|
||||||
column: column1,
|
column: column1,
|
||||||
@@ -197,12 +197,12 @@ impl Model {
|
|||||||
}
|
}
|
||||||
// FIXME: HACK. The parser is currently parsing Sheet3!A1:A10 as Sheet3!A1:(present sheet)!A10
|
// FIXME: HACK. The parser is currently parsing Sheet3!A1:A10 as Sheet3!A1:(present sheet)!A10
|
||||||
CalcResult::Range {
|
CalcResult::Range {
|
||||||
left: CellReference {
|
left: CellReferenceIndex {
|
||||||
sheet: *sheet_index,
|
sheet: *sheet_index,
|
||||||
row: row_left,
|
row: row_left,
|
||||||
column: column_left,
|
column: column_left,
|
||||||
},
|
},
|
||||||
right: CellReference {
|
right: CellReferenceIndex {
|
||||||
sheet: *sheet_index,
|
sheet: *sheet_index,
|
||||||
row: row_right,
|
row: row_right,
|
||||||
column: column_right,
|
column: column_right,
|
||||||
@@ -213,7 +213,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_range(&mut self, left: &Node, right: &Node, cell: CellReference) -> CalcResult {
|
fn get_range(&mut self, left: &Node, right: &Node, cell: CellReferenceIndex) -> CalcResult {
|
||||||
let left_result = self.evaluate_node_with_reference(left, cell);
|
let left_result = self.evaluate_node_with_reference(left, cell);
|
||||||
let right_result = self.evaluate_node_with_reference(right, cell);
|
let right_result = self.evaluate_node_with_reference(right, cell);
|
||||||
match (left_result, right_result) {
|
match (left_result, right_result) {
|
||||||
@@ -254,7 +254,7 @@ impl Model {
|
|||||||
pub(crate) fn evaluate_node_in_context(
|
pub(crate) fn evaluate_node_in_context(
|
||||||
&mut self,
|
&mut self,
|
||||||
node: &Node,
|
node: &Node,
|
||||||
cell: CellReference,
|
cell: CellReferenceIndex,
|
||||||
) -> CalcResult {
|
) -> CalcResult {
|
||||||
use Node::*;
|
use Node::*;
|
||||||
match node {
|
match node {
|
||||||
@@ -298,7 +298,7 @@ impl Model {
|
|||||||
if !absolute_column {
|
if !absolute_column {
|
||||||
column1 += cell.column;
|
column1 += cell.column;
|
||||||
}
|
}
|
||||||
self.evaluate_cell(CellReference {
|
self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: *sheet_index,
|
sheet: *sheet_index,
|
||||||
row: row1,
|
row: row1,
|
||||||
column: column1,
|
column: column1,
|
||||||
@@ -323,7 +323,7 @@ impl Model {
|
|||||||
absolute_column2,
|
absolute_column2,
|
||||||
sheet_name: _,
|
sheet_name: _,
|
||||||
} => CalcResult::Range {
|
} => CalcResult::Range {
|
||||||
left: CellReference {
|
left: CellReferenceIndex {
|
||||||
sheet: *sheet_index,
|
sheet: *sheet_index,
|
||||||
row: if *absolute_row1 {
|
row: if *absolute_row1 {
|
||||||
*row1
|
*row1
|
||||||
@@ -336,7 +336,7 @@ impl Model {
|
|||||||
*column1 + cell.column
|
*column1 + cell.column
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
right: CellReference {
|
right: CellReferenceIndex {
|
||||||
sheet: *sheet_index,
|
sheet: *sheet_index,
|
||||||
row: if *absolute_row2 {
|
row: if *absolute_row2 {
|
||||||
*row2
|
*row2
|
||||||
@@ -531,7 +531,10 @@ impl Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cell_reference_to_string(&self, cell_reference: &CellReference) -> Result<String, String> {
|
fn cell_reference_to_string(
|
||||||
|
&self,
|
||||||
|
cell_reference: &CellReferenceIndex,
|
||||||
|
) -> Result<String, String> {
|
||||||
let sheet = self.workbook.worksheet(cell_reference.sheet)?;
|
let sheet = self.workbook.worksheet(cell_reference.sheet)?;
|
||||||
let column = utils::number_to_column(cell_reference.column)
|
let column = utils::number_to_column(cell_reference.column)
|
||||||
.ok_or_else(|| "Invalid column".to_string())?;
|
.ok_or_else(|| "Invalid column".to_string())?;
|
||||||
@@ -543,8 +546,8 @@ impl Model {
|
|||||||
/// Sets `result` in the cell given by `sheet` sheet index, row and column
|
/// Sets `result` in the cell given by `sheet` sheet index, row and column
|
||||||
/// Note that will panic if the cell does not exist
|
/// Note that will panic if the cell does not exist
|
||||||
/// It will do nothing if the cell does not have a formula
|
/// It will do nothing if the cell does not have a formula
|
||||||
fn set_cell_value(&mut self, cell_reference: CellReference, result: &CalcResult) {
|
fn set_cell_value(&mut self, cell_reference: CellReferenceIndex, result: &CalcResult) {
|
||||||
let CellReference { sheet, column, row } = cell_reference;
|
let CellReferenceIndex { sheet, column, row } = cell_reference;
|
||||||
let cell = &self.workbook.worksheets[sheet as usize].sheet_data[&row][&column];
|
let cell = &self.workbook.worksheets[sheet as usize].sheet_data[&row][&column];
|
||||||
let s = cell.get_style();
|
let s = cell.get_style();
|
||||||
if let Some(f) = cell.get_formula() {
|
if let Some(f) = cell.get_formula() {
|
||||||
@@ -678,7 +681,7 @@ impl Model {
|
|||||||
Err(format!("Invalid color: {}", color))
|
Err(format!("Invalid color: {}", color))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_cell_value(&self, cell: &Cell, cell_reference: CellReference) -> CalcResult {
|
fn get_cell_value(&self, cell: &Cell, cell_reference: CellReferenceIndex) -> CalcResult {
|
||||||
use Cell::*;
|
use Cell::*;
|
||||||
match cell {
|
match cell {
|
||||||
EmptyCell { .. } => CalcResult::EmptyCell,
|
EmptyCell { .. } => CalcResult::EmptyCell,
|
||||||
@@ -736,7 +739,7 @@ impl Model {
|
|||||||
self.workbook.worksheet(sheet)?.is_empty_cell(row, column)
|
self.workbook.worksheet(sheet)?.is_empty_cell(row, column)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn evaluate_cell(&mut self, cell_reference: CellReference) -> CalcResult {
|
pub(crate) fn evaluate_cell(&mut self, cell_reference: CellReferenceIndex) -> CalcResult {
|
||||||
let row_data = match self.workbook.worksheets[cell_reference.sheet as usize]
|
let row_data = match self.workbook.worksheets[cell_reference.sheet as usize]
|
||||||
.sheet_data
|
.sheet_data
|
||||||
.get(&cell_reference.row)
|
.get(&cell_reference.row)
|
||||||
@@ -894,16 +897,16 @@ impl Model {
|
|||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use ironcalc_base::model::Model;
|
/// # use ironcalc_base::model::Model;
|
||||||
/// # use ironcalc_base::calc_result::CellReference;
|
/// # use ironcalc_base::expressions::types::CellReferenceIndex;
|
||||||
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
/// let mut model = Model::new_empty("model", "en", "UTC")?;
|
/// let mut model = Model::new_empty("model", "en", "UTC")?;
|
||||||
/// model.set_user_input(0, 1, 1, "Stella!".to_string());
|
/// model.set_user_input(0, 1, 1, "Stella!".to_string());
|
||||||
/// let reference = model.parse_reference("Sheet1!D40");
|
/// let reference = model.parse_reference("Sheet1!D40");
|
||||||
/// assert_eq!(reference, Some(CellReference {sheet: 0, row: 40, column: 4}));
|
/// assert_eq!(reference, Some(CellReferenceIndex {sheet: 0, row: 40, column: 4}));
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn parse_reference(&self, s: &str) -> Option<CellReference> {
|
pub fn parse_reference(&self, s: &str) -> Option<CellReferenceIndex> {
|
||||||
let bytes = s.as_bytes();
|
let bytes = s.as_bytes();
|
||||||
let mut sheet_name = "".to_string();
|
let mut sheet_name = "".to_string();
|
||||||
let mut column = "".to_string();
|
let mut column = "".to_string();
|
||||||
@@ -954,7 +957,7 @@ impl Model {
|
|||||||
Err(_) => return None,
|
Err(_) => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(CellReference { sheet, row, column })
|
Some(CellReferenceIndex { sheet, row, column })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Moves the formula `value` from `source` (in `area`) to `target`.
|
/// Moves the formula `value` from `source` (in `area`) to `target`.
|
||||||
@@ -1391,7 +1394,7 @@ impl Model {
|
|||||||
.set_cell_with_formula(sheet, row, column, formula, new_style_index)
|
.set_cell_with_formula(sheet, row, column, formula, new_style_index)
|
||||||
.expect("could not set the cell formula");
|
.expect("could not set the cell formula");
|
||||||
// Update the style if needed
|
// Update the style if needed
|
||||||
let cell = CellReference { sheet, row, column };
|
let cell = CellReferenceIndex { sheet, row, column };
|
||||||
let parsed_formula = &self.parsed_formulas[sheet as usize][formula_index as usize];
|
let parsed_formula = &self.parsed_formulas[sheet as usize][formula_index as usize];
|
||||||
if let Some(units) = self.compute_node_units(parsed_formula, &cell) {
|
if let Some(units) = self.compute_node_units(parsed_formula, &cell) {
|
||||||
let new_style_index = self
|
let new_style_index = self
|
||||||
@@ -1635,7 +1638,7 @@ impl Model {
|
|||||||
let cells = self.get_all_cells();
|
let cells = self.get_all_cells();
|
||||||
|
|
||||||
for cell in cells {
|
for cell in cells {
|
||||||
self.evaluate_cell(CellReference {
|
self.evaluate_cell(CellReferenceIndex {
|
||||||
sheet: cell.index,
|
sheet: cell.index,
|
||||||
row: cell.row,
|
row: cell.row,
|
||||||
column: cell.column,
|
column: cell.column,
|
||||||
@@ -1820,8 +1823,8 @@ impl Model {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::CellReferenceIndex as CellReference;
|
||||||
use crate::test::util::new_empty_model;
|
use crate::{test::util::new_empty_model, types::Cell};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cell_reference_to_string() {
|
fn test_cell_reference_to_string() {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#![allow(clippy::unwrap_used)]
|
#![allow(clippy::unwrap_used)]
|
||||||
|
|
||||||
use crate::calc_result::CellReference;
|
use crate::expressions::types::CellReferenceIndex;
|
||||||
use crate::model::Model;
|
use crate::model::Model;
|
||||||
use crate::types::Cell;
|
use crate::types::Cell;
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ pub fn new_empty_model() -> Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
fn _parse_reference(&self, cell: &str) -> CellReference {
|
fn _parse_reference(&self, cell: &str) -> CellReferenceIndex {
|
||||||
if cell.contains('!') {
|
if cell.contains('!') {
|
||||||
self.parse_reference(cell).unwrap()
|
self.parse_reference(cell).unwrap()
|
||||||
} else {
|
} else {
|
||||||
@@ -39,7 +39,7 @@ impl Model {
|
|||||||
self.formatted_cell_value(sheet, row, column).unwrap()
|
self.formatted_cell_value(sheet, row, column).unwrap()
|
||||||
}
|
}
|
||||||
pub fn _get_text(&self, cell: &str) -> String {
|
pub fn _get_text(&self, cell: &str) -> String {
|
||||||
let CellReference { sheet, row, column } = self._parse_reference(cell);
|
let CellReferenceIndex { sheet, row, column } = self._parse_reference(cell);
|
||||||
self._get_text_at(sheet, row, column)
|
self._get_text_at(sheet, row, column)
|
||||||
}
|
}
|
||||||
pub fn _get_cell(&self, cell: &str) -> &Cell {
|
pub fn _get_cell(&self, cell: &str) -> &Cell {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
calc_result::CellReference,
|
expressions::{parser::Node, token::OpProduct, types::CellReferenceIndex},
|
||||||
expressions::{parser::Node, token::OpProduct},
|
|
||||||
formatter::parser::{ParsePart, Parser},
|
formatter::parser::{ParsePart, Parser},
|
||||||
functions::Function,
|
functions::Function,
|
||||||
model::Model,
|
model::Model,
|
||||||
@@ -86,7 +85,7 @@ fn get_units_from_format_string(num_fmt: &str) -> Option<Units> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
fn compute_cell_units(&self, cell_reference: &CellReference) -> Option<Units> {
|
fn compute_cell_units(&self, cell_reference: &CellReferenceIndex) -> Option<Units> {
|
||||||
let style = &self.get_style_for_cell(
|
let style = &self.get_style_for_cell(
|
||||||
cell_reference.sheet,
|
cell_reference.sheet,
|
||||||
cell_reference.row,
|
cell_reference.row,
|
||||||
@@ -95,7 +94,11 @@ impl Model {
|
|||||||
get_units_from_format_string(&style.num_fmt)
|
get_units_from_format_string(&style.num_fmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn compute_node_units(&self, node: &Node, cell: &CellReference) -> Option<Units> {
|
pub(crate) fn compute_node_units(
|
||||||
|
&self,
|
||||||
|
node: &Node,
|
||||||
|
cell: &CellReferenceIndex,
|
||||||
|
) -> Option<Units> {
|
||||||
match node {
|
match node {
|
||||||
Node::ReferenceKind {
|
Node::ReferenceKind {
|
||||||
sheet_name: _,
|
sheet_name: _,
|
||||||
@@ -113,7 +116,7 @@ impl Model {
|
|||||||
if !absolute_column {
|
if !absolute_column {
|
||||||
column1 += cell.column;
|
column1 += cell.column;
|
||||||
}
|
}
|
||||||
self.compute_cell_units(&CellReference {
|
self.compute_cell_units(&CellReferenceIndex {
|
||||||
sheet: *sheet_index,
|
sheet: *sheet_index,
|
||||||
row: row1,
|
row: row1,
|
||||||
column: column1,
|
column: column1,
|
||||||
@@ -140,7 +143,7 @@ impl Model {
|
|||||||
if !absolute_column1 {
|
if !absolute_column1 {
|
||||||
column1 += cell.column;
|
column1 += cell.column;
|
||||||
}
|
}
|
||||||
self.compute_cell_units(&CellReference {
|
self.compute_cell_units(&CellReferenceIndex {
|
||||||
sheet: *sheet_index,
|
sheet: *sheet_index,
|
||||||
row: row1,
|
row: row1,
|
||||||
column: column1,
|
column: column1,
|
||||||
@@ -294,7 +297,7 @@ impl Model {
|
|||||||
&self,
|
&self,
|
||||||
kind: &Function,
|
kind: &Function,
|
||||||
args: &[Node],
|
args: &[Node],
|
||||||
cell: &CellReference,
|
cell: &CellReferenceIndex,
|
||||||
) -> Option<Units> {
|
) -> Option<Units> {
|
||||||
match kind {
|
match kind {
|
||||||
Function::Sum => self.units_fn_sum_like(args, cell),
|
Function::Sum => self.units_fn_sum_like(args, cell),
|
||||||
@@ -319,7 +322,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn units_fn_sum_like(&self, args: &[Node], cell: &CellReference) -> Option<Units> {
|
fn units_fn_sum_like(&self, args: &[Node], cell: &CellReferenceIndex) -> Option<Units> {
|
||||||
// We return the unit of the first argument
|
// We return the unit of the first argument
|
||||||
if !args.is_empty() {
|
if !args.is_empty() {
|
||||||
return self.compute_node_units(&args[0], cell);
|
return self.compute_node_units(&args[0], cell);
|
||||||
@@ -327,7 +330,7 @@ impl Model {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn units_fn_currency(&self, _args: &[Node], _cell: &CellReference) -> Option<Units> {
|
fn units_fn_currency(&self, _args: &[Node], _cell: &CellReferenceIndex) -> Option<Units> {
|
||||||
let currency_symbol = &self.locale.currency.symbol;
|
let currency_symbol = &self.locale.currency.symbol;
|
||||||
let standard_format = &self.locale.numbers.currency_formats.standard;
|
let standard_format = &self.locale.numbers.currency_formats.standard;
|
||||||
let num_fmt = standard_format.replace('¤', currency_symbol);
|
let num_fmt = standard_format.replace('¤', currency_symbol);
|
||||||
@@ -341,7 +344,7 @@ impl Model {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn units_fn_percentage(&self, _args: &[Node], _cell: &CellReference) -> Option<Units> {
|
fn units_fn_percentage(&self, _args: &[Node], _cell: &CellReferenceIndex) -> Option<Units> {
|
||||||
Some(Units::Percentage {
|
Some(Units::Percentage {
|
||||||
group_separator: false,
|
group_separator: false,
|
||||||
precision: 0,
|
precision: 0,
|
||||||
@@ -349,7 +352,7 @@ impl Model {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn units_fn_percentage_2(&self, _args: &[Node], _cell: &CellReference) -> Option<Units> {
|
fn units_fn_percentage_2(&self, _args: &[Node], _cell: &CellReferenceIndex) -> Option<Units> {
|
||||||
Some(Units::Percentage {
|
Some(Units::Percentage {
|
||||||
group_separator: false,
|
group_separator: false,
|
||||||
precision: 2,
|
precision: 2,
|
||||||
@@ -357,7 +360,7 @@ impl Model {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn units_fn_dates(&self, _args: &[Node], _cell: &CellReference) -> Option<Units> {
|
fn units_fn_dates(&self, _args: &[Node], _cell: &CellReferenceIndex) -> Option<Units> {
|
||||||
// TODO: update locale and use it here
|
// TODO: update locale and use it here
|
||||||
Some(Units::Date("dd/mm/yyyy".to_string()))
|
Some(Units::Date("dd/mm/yyyy".to_string()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use crate::expressions::token::get_error_by_name;
|
use crate::expressions::token::get_error_by_name;
|
||||||
|
use crate::expressions::types::CellReferenceIndex;
|
||||||
use crate::language::Language;
|
use crate::language::Language;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_result::CellReference,
|
|
||||||
expressions::{
|
expressions::{
|
||||||
lexer::{Lexer, LexerMode},
|
lexer::{Lexer, LexerMode},
|
||||||
token::TokenType,
|
token::TokenType,
|
||||||
@@ -13,8 +13,8 @@ use crate::{
|
|||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub enum ParsedReference {
|
pub enum ParsedReference {
|
||||||
CellReference(CellReference),
|
CellReference(CellReferenceIndex),
|
||||||
Range(CellReference, CellReference),
|
Range(CellReferenceIndex, CellReferenceIndex),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParsedReference {
|
impl ParsedReference {
|
||||||
@@ -71,7 +71,7 @@ impl ParsedReference {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ParsedReference::CellReference(CellReference {
|
Ok(ParsedReference::CellReference(CellReferenceIndex {
|
||||||
sheet: sheet_index,
|
sheet: sheet_index,
|
||||||
row: row_id,
|
row: row_id,
|
||||||
column: column_id,
|
column: column_id,
|
||||||
@@ -103,12 +103,12 @@ impl ParsedReference {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(ParsedReference::Range(
|
Ok(ParsedReference::Range(
|
||||||
CellReference {
|
CellReferenceIndex {
|
||||||
sheet: sheet_index,
|
sheet: sheet_index,
|
||||||
row: left.row,
|
row: left.row,
|
||||||
column: left.column,
|
column: left.column,
|
||||||
},
|
},
|
||||||
CellReference {
|
CellReferenceIndex {
|
||||||
sheet: sheet_index,
|
sheet: sheet_index,
|
||||||
row: right.row,
|
row: right.row,
|
||||||
column: right.column,
|
column: right.column,
|
||||||
@@ -176,7 +176,7 @@ mod tests {
|
|||||||
ParsedReference::parse_reference_formula(Some(7), "A1", locale, |name| {
|
ParsedReference::parse_reference_formula(Some(7), "A1", locale, |name| {
|
||||||
get_sheet_index_by_name(&sheet_names, name)
|
get_sheet_index_by_name(&sheet_names, name)
|
||||||
},),
|
},),
|
||||||
Ok(ParsedReference::CellReference(CellReference {
|
Ok(ParsedReference::CellReference(CellReferenceIndex {
|
||||||
sheet: 7,
|
sheet: 7,
|
||||||
row: 1,
|
row: 1,
|
||||||
column: 1,
|
column: 1,
|
||||||
@@ -187,7 +187,7 @@ mod tests {
|
|||||||
ParsedReference::parse_reference_formula(None, "Sheet1!A1", locale, |name| {
|
ParsedReference::parse_reference_formula(None, "Sheet1!A1", locale, |name| {
|
||||||
get_sheet_index_by_name(&sheet_names, name)
|
get_sheet_index_by_name(&sheet_names, name)
|
||||||
},),
|
},),
|
||||||
Ok(ParsedReference::CellReference(CellReference {
|
Ok(ParsedReference::CellReference(CellReferenceIndex {
|
||||||
sheet: 0,
|
sheet: 0,
|
||||||
row: 1,
|
row: 1,
|
||||||
column: 1,
|
column: 1,
|
||||||
@@ -198,7 +198,7 @@ mod tests {
|
|||||||
ParsedReference::parse_reference_formula(None, "Sheet1!$A$1", locale, |name| {
|
ParsedReference::parse_reference_formula(None, "Sheet1!$A$1", locale, |name| {
|
||||||
get_sheet_index_by_name(&sheet_names, name)
|
get_sheet_index_by_name(&sheet_names, name)
|
||||||
},),
|
},),
|
||||||
Ok(ParsedReference::CellReference(CellReference {
|
Ok(ParsedReference::CellReference(CellReferenceIndex {
|
||||||
sheet: 0,
|
sheet: 0,
|
||||||
row: 1,
|
row: 1,
|
||||||
column: 1,
|
column: 1,
|
||||||
@@ -209,7 +209,7 @@ mod tests {
|
|||||||
ParsedReference::parse_reference_formula(None, "Sheet2!$A$1", locale, |name| {
|
ParsedReference::parse_reference_formula(None, "Sheet2!$A$1", locale, |name| {
|
||||||
get_sheet_index_by_name(&sheet_names, name)
|
get_sheet_index_by_name(&sheet_names, name)
|
||||||
},),
|
},),
|
||||||
Ok(ParsedReference::CellReference(CellReference {
|
Ok(ParsedReference::CellReference(CellReferenceIndex {
|
||||||
sheet: 1,
|
sheet: 1,
|
||||||
row: 1,
|
row: 1,
|
||||||
column: 1,
|
column: 1,
|
||||||
@@ -227,12 +227,12 @@ mod tests {
|
|||||||
get_sheet_index_by_name(&sheet_names, name)
|
get_sheet_index_by_name(&sheet_names, name)
|
||||||
},),
|
},),
|
||||||
Ok(ParsedReference::Range(
|
Ok(ParsedReference::Range(
|
||||||
CellReference {
|
CellReferenceIndex {
|
||||||
sheet: 5,
|
sheet: 5,
|
||||||
column: 1,
|
column: 1,
|
||||||
row: 1,
|
row: 1,
|
||||||
},
|
},
|
||||||
CellReference {
|
CellReferenceIndex {
|
||||||
sheet: 5,
|
sheet: 5,
|
||||||
column: 1,
|
column: 1,
|
||||||
row: 2,
|
row: 2,
|
||||||
@@ -245,12 +245,12 @@ mod tests {
|
|||||||
get_sheet_index_by_name(&sheet_names, name)
|
get_sheet_index_by_name(&sheet_names, name)
|
||||||
},),
|
},),
|
||||||
Ok(ParsedReference::Range(
|
Ok(ParsedReference::Range(
|
||||||
CellReference {
|
CellReferenceIndex {
|
||||||
sheet: 0,
|
sheet: 0,
|
||||||
row: 1,
|
row: 1,
|
||||||
column: 1,
|
column: 1,
|
||||||
},
|
},
|
||||||
CellReference {
|
CellReferenceIndex {
|
||||||
sheet: 0,
|
sheet: 0,
|
||||||
row: 10,
|
row: 10,
|
||||||
column: 2,
|
column: 2,
|
||||||
@@ -263,12 +263,12 @@ mod tests {
|
|||||||
get_sheet_index_by_name(&sheet_names, name)
|
get_sheet_index_by_name(&sheet_names, name)
|
||||||
},),
|
},),
|
||||||
Ok(ParsedReference::Range(
|
Ok(ParsedReference::Range(
|
||||||
CellReference {
|
CellReferenceIndex {
|
||||||
sheet: 1,
|
sheet: 1,
|
||||||
row: 1,
|
row: 1,
|
||||||
column: 27,
|
column: 27,
|
||||||
},
|
},
|
||||||
CellReference {
|
CellReferenceIndex {
|
||||||
sheet: 1,
|
sheet: 1,
|
||||||
row: 11,
|
row: 11,
|
||||||
column: 5,
|
column: 5,
|
||||||
|
|||||||
Reference in New Issue
Block a user