committed by
Nicolás Hatcher Andrés
parent
8e15c623dd
commit
7676efca44
@@ -15,6 +15,23 @@ pub(crate) enum NumberOrArray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
|
pub(crate) fn cast_number(&self, s: &str) -> Option<f64> {
|
||||||
|
match s.trim().parse::<f64>() {
|
||||||
|
Ok(f) => Some(f),
|
||||||
|
_ => {
|
||||||
|
let currency = &self.locale.currency.symbol;
|
||||||
|
let mut currencies = vec!["$", "€"];
|
||||||
|
if !currencies.iter().any(|e| *e == currency) {
|
||||||
|
currencies.push(currency);
|
||||||
|
}
|
||||||
|
// Try to parse as a formatted number (e.g., dates, currencies, percentages)
|
||||||
|
if let Ok((v, _number_format)) = parse_formatted_number(s, ¤cies) {
|
||||||
|
return Some(v);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
pub(crate) fn get_number_or_array(
|
pub(crate) fn get_number_or_array(
|
||||||
&mut self,
|
&mut self,
|
||||||
node: &Node,
|
node: &Node,
|
||||||
@@ -22,24 +39,13 @@ impl Model {
|
|||||||
) -> Result<NumberOrArray, CalcResult> {
|
) -> Result<NumberOrArray, CalcResult> {
|
||||||
match self.evaluate_node_in_context(node, cell) {
|
match self.evaluate_node_in_context(node, cell) {
|
||||||
CalcResult::Number(f) => Ok(NumberOrArray::Number(f)),
|
CalcResult::Number(f) => Ok(NumberOrArray::Number(f)),
|
||||||
CalcResult::String(s) => match s.parse::<f64>() {
|
CalcResult::String(s) => match self.cast_number(&s) {
|
||||||
Ok(f) => Ok(NumberOrArray::Number(f)),
|
Some(f) => Ok(NumberOrArray::Number(f)),
|
||||||
_ => {
|
None => Err(CalcResult::new_error(
|
||||||
let mut currencies = vec!["$", "€"];
|
Error::VALUE,
|
||||||
let currency = &self.locale.currency.symbol;
|
cell,
|
||||||
if !currencies.iter().any(|e| e == currency) {
|
"Expecting number".to_string(),
|
||||||
currencies.push(currency);
|
)),
|
||||||
}
|
|
||||||
// Try to parse as a formatted number (e.g., dates, currencies, percentages)
|
|
||||||
if let Ok((v, _number_format)) = parse_formatted_number(&s, ¤cies) {
|
|
||||||
return Ok(NumberOrArray::Number(v));
|
|
||||||
}
|
|
||||||
Err(CalcResult::new_error(
|
|
||||||
Error::VALUE,
|
|
||||||
cell,
|
|
||||||
"Expecting number".to_string(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
CalcResult::Boolean(f) => {
|
CalcResult::Boolean(f) => {
|
||||||
if f {
|
if f {
|
||||||
@@ -108,24 +114,13 @@ impl Model {
|
|||||||
) -> Result<f64, CalcResult> {
|
) -> Result<f64, CalcResult> {
|
||||||
match result {
|
match result {
|
||||||
CalcResult::Number(f) => Ok(f),
|
CalcResult::Number(f) => Ok(f),
|
||||||
CalcResult::String(s) => match s.trim().parse::<f64>() {
|
CalcResult::String(s) => match self.cast_number(&s) {
|
||||||
Ok(f) => Ok(f),
|
Some(f) => Ok(f),
|
||||||
_ => {
|
None => Err(CalcResult::new_error(
|
||||||
let mut currencies = vec!["$", "€"];
|
Error::VALUE,
|
||||||
let currency = &self.locale.currency.symbol;
|
cell,
|
||||||
if !currencies.iter().any(|e| e == currency) {
|
"Expecting number".to_string(),
|
||||||
currencies.push(currency);
|
)),
|
||||||
}
|
|
||||||
// Try to parse as a formatted number (e.g., dates, currencies, percentages)
|
|
||||||
if let Ok((v, _number_format)) = parse_formatted_number(&s, ¤cies) {
|
|
||||||
return Ok(v);
|
|
||||||
}
|
|
||||||
Err(CalcResult::new_error(
|
|
||||||
Error::VALUE,
|
|
||||||
cell,
|
|
||||||
"Expecting number".to_string(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
CalcResult::Boolean(f) => {
|
CalcResult::Boolean(f) => {
|
||||||
if f {
|
if f {
|
||||||
|
|||||||
@@ -68,14 +68,14 @@ macro_rules! single_number_fn {
|
|||||||
},
|
},
|
||||||
// If String, parse to f64 then apply or #VALUE! error
|
// If String, parse to f64 then apply or #VALUE! error
|
||||||
ArrayNode::String(s) => {
|
ArrayNode::String(s) => {
|
||||||
let node = match s.parse::<f64>() {
|
let node = match self.cast_number(&s) {
|
||||||
Ok(f) => match $op(f) {
|
Some(f) => match $op(f) {
|
||||||
Ok(x) => ArrayNode::Number(x),
|
Ok(x) => ArrayNode::Number(x),
|
||||||
Err(Error::DIV) => ArrayNode::Error(Error::DIV),
|
Err(Error::DIV) => ArrayNode::Error(Error::DIV),
|
||||||
Err(Error::VALUE) => ArrayNode::Error(Error::VALUE),
|
Err(Error::VALUE) => ArrayNode::Error(Error::VALUE),
|
||||||
Err(e) => ArrayNode::Error(e),
|
Err(e) => ArrayNode::Error(e),
|
||||||
},
|
},
|
||||||
Err(_) => ArrayNode::Error(Error::VALUE),
|
None => ArrayNode::Error(Error::VALUE),
|
||||||
};
|
};
|
||||||
data_row.push(node);
|
data_row.push(node);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1336,7 +1336,13 @@ impl Model {
|
|||||||
}
|
}
|
||||||
Ok(acc)
|
Ok(acc)
|
||||||
});
|
});
|
||||||
single_number_fn!(fn_sign, |f| Ok(f64::signum(f)));
|
single_number_fn!(fn_sign, |f| {
|
||||||
|
if f == 0.0 {
|
||||||
|
Ok(0.0)
|
||||||
|
} else {
|
||||||
|
Ok(f64::signum(f))
|
||||||
|
}
|
||||||
|
});
|
||||||
single_number_fn!(fn_degrees, |f| Ok(f * (180.0 / PI)));
|
single_number_fn!(fn_degrees, |f| Ok(f * (180.0 / PI)));
|
||||||
single_number_fn!(fn_radians, |f| Ok(f * (PI / 180.0)));
|
single_number_fn!(fn_radians, |f| Ok(f * (PI / 180.0)));
|
||||||
single_number_fn!(fn_odd, |f| {
|
single_number_fn!(fn_odd, |f| {
|
||||||
|
|||||||
BIN
xlsx/tests/calc_tests/EXP_SIGN.xlsx
Normal file
BIN
xlsx/tests/calc_tests/EXP_SIGN.xlsx
Normal file
Binary file not shown.
Reference in New Issue
Block a user