Implement UNICODE function

This commit is contained in:
Bruno Carvalhal
2024-11-10 14:25:10 +01:00
committed by Nicolás Hatcher Andrés
parent d681f63b25
commit 726bf677ed
5 changed files with 94 additions and 1 deletions

View File

@@ -122,6 +122,7 @@ pub enum Function {
Textbefore, Textbefore,
Textjoin, Textjoin,
Trim, Trim,
Unicode,
Upper, Upper,
Value, Value,
Valuetotext, Valuetotext,
@@ -246,7 +247,7 @@ pub enum Function {
} }
impl Function { impl Function {
pub fn into_iter() -> IntoIter<Function, 192> { pub fn into_iter() -> IntoIter<Function, 193> {
[ [
Function::And, Function::And,
Function::False, Function::False,
@@ -316,6 +317,7 @@ impl Function {
Function::Search, Function::Search,
Function::Text, Function::Text,
Function::Trim, Function::Trim,
Function::Unicode,
Function::Upper, Function::Upper,
Function::Isnumber, Function::Isnumber,
Function::Isnontext, Function::Isnontext,
@@ -567,6 +569,7 @@ impl Function {
"SEARCH" => Some(Function::Search), "SEARCH" => Some(Function::Search),
"TEXT" => Some(Function::Text), "TEXT" => Some(Function::Text),
"TRIM" => Some(Function::Trim), "TRIM" => Some(Function::Trim),
"UNICODE" => Some(Function::Unicode),
"UPPER" => Some(Function::Upper), "UPPER" => Some(Function::Upper),
"REPT" => Some(Function::Rept), "REPT" => Some(Function::Rept),
@@ -779,6 +782,7 @@ impl fmt::Display for Function {
Function::Search => write!(f, "SEARCH"), Function::Search => write!(f, "SEARCH"),
Function::Text => write!(f, "TEXT"), Function::Text => write!(f, "TEXT"),
Function::Trim => write!(f, "TRIM"), Function::Trim => write!(f, "TRIM"),
Function::Unicode => write!(f, "UNICODE"),
Function::Upper => write!(f, "UPPER"), Function::Upper => write!(f, "UPPER"),
Function::Isnumber => write!(f, "ISNUMBER"), Function::Isnumber => write!(f, "ISNUMBER"),
Function::Isnontext => write!(f, "ISNONTEXT"), Function::Isnontext => write!(f, "ISNONTEXT"),
@@ -1012,6 +1016,7 @@ impl Model {
Function::Search => self.fn_search(args, cell), Function::Search => self.fn_search(args, cell),
Function::Text => self.fn_text(args, cell), Function::Text => self.fn_text(args, cell),
Function::Trim => self.fn_trim(args, cell), Function::Trim => self.fn_trim(args, cell),
Function::Unicode => self.fn_unicode(args, cell),
Function::Upper => self.fn_upper(args, cell), Function::Upper => self.fn_upper(args, cell),
// Information // Information
Function::Isnumber => self.fn_isnumber(args, cell), Function::Isnumber => self.fn_isnumber(args, cell),

View File

@@ -342,6 +342,51 @@ impl Model {
CalcResult::new_args_number_error(cell) CalcResult::new_args_number_error(cell)
} }
pub(crate) fn fn_unicode(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
if args.len() == 1 {
let s = match self.evaluate_node_in_context(&args[0], cell) {
CalcResult::Number(v) => format!("{}", v),
CalcResult::String(v) => v,
CalcResult::Boolean(b) => {
if b {
"TRUE".to_string()
} else {
"FALSE".to_string()
}
}
error @ CalcResult::Error { .. } => return error,
CalcResult::Range { .. } => {
// Implicit Intersection not implemented
return CalcResult::Error {
error: Error::NIMPL,
origin: cell,
message: "Implicit Intersection not implemented".to_string(),
};
}
CalcResult::EmptyCell | CalcResult::EmptyArg => {
return CalcResult::Error {
error: Error::VALUE,
origin: cell,
message: "Empty cell".to_string(),
}
}
};
// TODO: Needed?
if s.len() == 0 {
return CalcResult::Error {
error: Error::VALUE,
origin: cell,
message: "Empty cell".to_string(),
};
}
let unicode_number = s.chars().nth(0).unwrap() as u32;
return CalcResult::String(unicode_number.to_string());
}
CalcResult::new_args_number_error(cell)
}
pub(crate) fn fn_upper(&mut self, args: &[Node], cell: CellReferenceIndex) -> 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) {

View File

@@ -24,6 +24,7 @@ mod test_fn_sum;
mod test_fn_sumifs; mod test_fn_sumifs;
mod test_fn_textbefore; mod test_fn_textbefore;
mod test_fn_textjoin; mod test_fn_textjoin;
mod test_fn_unicode;
mod test_forward_references; mod test_forward_references;
mod test_frozen_rows_columns; mod test_frozen_rows_columns;
mod test_general; mod test_general;

View File

@@ -0,0 +1,41 @@
#![allow(clippy::unwrap_used)]
use crate::test::util::new_empty_model;
#[test]
fn simple_cases() {
let mut model = new_empty_model();
model._set("A1", "=UNICODE(\"1,00\")");
model._set("A2", "=UNICODE(\"1\")");
model._set("A3", "=UNICODE(\"T\")");
model._set("A4", "=UNICODE(\"TRUE\")");
model._set("A5", "=UNICODE(\"\")");
model._set("A6", "=UNICODE(\" \")");
model.evaluate();
assert_eq!(model._get_text("A1"), *"49");
assert_eq!(model._get_text("A2"), *"49");
assert_eq!(model._get_text("A3"), *"84");
assert_eq!(model._get_text("A4"), *"84");
assert_eq!(model._get_text("A5"), *"12398");
assert_eq!(model._get_text("A6"), *"32");
}
#[test]
fn value_errors() {
let mut model = new_empty_model();
model._set("A1", "=UNICODE(\"\")");
model.evaluate();
assert_eq!(model._get_text("A1"), *"#VALUE!");
}
#[test]
fn wrong_number_of_arguments() {
let mut model = new_empty_model();
model._set("A1", "=UNICODE()");
model.evaluate();
assert_eq!(model._get_text("A1"), *"#ERROR!");
}

View File

@@ -68,6 +68,7 @@
* SEARCH * SEARCH
* TEXT * TEXT
* TRIM * TRIM
* UNICODE
* UPPER * UPPER
* ISNUMBER * ISNUMBER
* ISNONTEXT * ISNONTEXT