Skip to main content

office_rs/xlsx/formulas/
formula_calculator.rs

1//! 公式计算引擎
2//! 提供公式求值和内置函数实现
3
4use super::*;
5use crate::error::{ OfficeError, Result, XlsxError };
6use crate::xlsx::cell::{ CellReference, CellValue };
7use std::collections::HashMap;
8
9impl FormulaCalculator {
10    /// 创建新的公式计算器
11    pub fn new(cell_provider: Box<dyn CellProvider>) -> Self {
12        let mut calculator = Self {
13            cell_provider,
14            function_library: FunctionLibrary::new(),
15            cache: HashMap::new(),
16        };
17
18        // 注册内置函数
19        calculator.register_builtin_functions();
20        calculator
21    }
22
23    /// 计算公式表达式
24    pub fn evaluate(&mut self, expr: &FormulaExpression) -> Result<FormulaValue> {
25        match expr {
26            FormulaExpression::Constant(value) => Ok(value.clone()),
27
28            FormulaExpression::CellRef(cell_ref) => {
29                let cell_value = self.cell_provider.get_cell_value(cell_ref)?;
30                Ok(self.cell_value_to_formula_value(cell_value))
31            }
32
33            FormulaExpression::RangeRef(start, end) => {
34                let values = self.cell_provider.get_range_values(start, end)?;
35                let formula_values = values
36                    .into_iter()
37                    .map(|row| {
38                        row.into_iter()
39                            .map(|cell| self.cell_value_to_formula_value(cell))
40                            .collect()
41                    })
42                    .collect();
43                Ok(FormulaValue::Array(formula_values))
44            }
45
46            FormulaExpression::Function { name, args } => self.evaluate_function(name, args),
47
48            FormulaExpression::BinaryOp { op, left, right } => {
49                let left_val = self.evaluate(left)?;
50                let right_val = self.evaluate(right)?;
51                self.evaluate_binary_op(op, &left_val, &right_val)
52            }
53
54            FormulaExpression::UnaryOp { op, operand } => {
55                let operand_val = self.evaluate(operand)?;
56                self.evaluate_unary_op(op, &operand_val)
57            }
58        }
59    }
60
61    /// 转换CellValue到FormulaValue
62    fn cell_value_to_formula_value(&self, cell_value: CellValue) -> FormulaValue {
63        match cell_value {
64            CellValue::Empty => FormulaValue::Number(0.0),
65            CellValue::Number(n) => FormulaValue::Number(n),
66            CellValue::Text(s) => FormulaValue::Text(s),
67            CellValue::Boolean(b) => FormulaValue::Boolean(b),
68            CellValue::DateTime(d) => FormulaValue::Number(d),
69            CellValue::Formula(_) => FormulaValue::Error(FormulaError::ReferenceError),
70            CellValue::Error(e) => FormulaValue::Error(FormulaError::ValueError),
71        }
72    }
73
74    /// 计算二元操作
75    fn evaluate_binary_op(
76        &self,
77        op: &BinaryOperator,
78        left: &FormulaValue,
79        right: &FormulaValue
80    ) -> Result<FormulaValue> {
81        // 如果任一操作数是错误,返回错误
82        if left.is_error() {
83            return Ok(left.clone());
84        }
85        if right.is_error() {
86            return Ok(right.clone());
87        }
88
89        match op {
90            BinaryOperator::Add => {
91                let left_num = left.as_number()?;
92                let right_num = right.as_number()?;
93                Ok(FormulaValue::Number(left_num + right_num))
94            }
95
96            BinaryOperator::Subtract => {
97                let left_num = left.as_number()?;
98                let right_num = right.as_number()?;
99                Ok(FormulaValue::Number(left_num - right_num))
100            }
101
102            BinaryOperator::Multiply => {
103                let left_num = left.as_number()?;
104                let right_num = right.as_number()?;
105                Ok(FormulaValue::Number(left_num * right_num))
106            }
107
108            BinaryOperator::Divide => {
109                let left_num = left.as_number()?;
110                let right_num = right.as_number()?;
111
112                if right_num == 0.0 {
113                    Ok(FormulaValue::Error(FormulaError::DivisionByZero))
114                } else {
115                    Ok(FormulaValue::Number(left_num / right_num))
116                }
117            }
118
119            BinaryOperator::Power => {
120                let left_num = left.as_number()?;
121                let right_num = right.as_number()?;
122                Ok(FormulaValue::Number(left_num.powf(right_num)))
123            }
124
125            BinaryOperator::Equal => Ok(FormulaValue::Boolean(self.values_equal(left, right))),
126
127            BinaryOperator::NotEqual => Ok(FormulaValue::Boolean(!self.values_equal(left, right))),
128
129            BinaryOperator::LessThan => {
130                let result = self.compare_values(left, right)?;
131                Ok(FormulaValue::Boolean(result < 0))
132            }
133
134            BinaryOperator::LessThanOrEqual => {
135                let result = self.compare_values(left, right)?;
136                Ok(FormulaValue::Boolean(result <= 0))
137            }
138
139            BinaryOperator::GreaterThan => {
140                let result = self.compare_values(left, right)?;
141                Ok(FormulaValue::Boolean(result > 0))
142            }
143
144            BinaryOperator::GreaterThanOrEqual => {
145                let result = self.compare_values(left, right)?;
146                Ok(FormulaValue::Boolean(result >= 0))
147            }
148
149            BinaryOperator::Concatenate => {
150                let left_text = left.as_text();
151                let right_text = right.as_text();
152                Ok(FormulaValue::Text(format!("{}{}", left_text, right_text)))
153            }
154
155            BinaryOperator::LogicalOr => {
156                let left_bool = left.as_boolean()?;
157                let right_bool = right.as_boolean()?;
158                Ok(FormulaValue::Boolean(left_bool || right_bool))
159            }
160
161            BinaryOperator::LogicalAnd => {
162                let left_bool = left.as_boolean()?;
163                let right_bool = right.as_boolean()?;
164                Ok(FormulaValue::Boolean(left_bool && right_bool))
165            }
166        }
167    }
168
169    /// 计算一元操作
170    fn evaluate_unary_op(
171        &self,
172        op: &UnaryOperator,
173        operand: &FormulaValue
174    ) -> Result<FormulaValue> {
175        if operand.is_error() {
176            return Ok(operand.clone());
177        }
178
179        match op {
180            UnaryOperator::Plus => {
181                let num = operand.as_number()?;
182                Ok(FormulaValue::Number(num))
183            }
184            UnaryOperator::Minus => {
185                let num = operand.as_number()?;
186                Ok(FormulaValue::Number(-num))
187            }
188            UnaryOperator::Percent => {
189                let num = operand.as_number()?;
190                Ok(FormulaValue::Number(num / 100.0))
191            }
192            UnaryOperator::Factorial => {
193                let num = operand.as_number()?;
194                if num < 0.0 || num.fract() != 0.0 {
195                    return Ok(FormulaValue::Error(FormulaError::ValueError));
196                }
197                let mut result = 1.0;
198                for i in 1..=num as u64 {
199                    result *= i as f64;
200                }
201                Ok(FormulaValue::Number(result))
202            }
203        }
204    }
205
206    /// 比较两个值
207    fn values_equal(&self, left: &FormulaValue, right: &FormulaValue) -> bool {
208        match (left, right) {
209            (FormulaValue::Number(a), FormulaValue::Number(b)) => (a - b).abs() < f64::EPSILON,
210            (FormulaValue::Text(a), FormulaValue::Text(b)) => a == b,
211            (FormulaValue::Boolean(a), FormulaValue::Boolean(b)) => a == b,
212            (FormulaValue::Error(a), FormulaValue::Error(b)) => a == b,
213            _ => false,
214        }
215    }
216
217    /// 比较两个值的大小
218    fn compare_values(&self, left: &FormulaValue, right: &FormulaValue) -> Result<i32> {
219        match (left, right) {
220            (FormulaValue::Number(a), FormulaValue::Number(b)) => {
221                Ok(a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal) as i32)
222            }
223            (FormulaValue::Text(a), FormulaValue::Text(b)) => Ok(a.cmp(b) as i32),
224            (FormulaValue::Boolean(a), FormulaValue::Boolean(b)) => Ok(a.cmp(b) as i32),
225            _ =>
226                Err(
227                    OfficeError::Xlsx(XlsxError::InvalidFormula {
228                        formula: "Cannot compare different types".to_string(),
229                    })
230                ),
231        }
232    }
233
234    /// 计算函数
235    fn evaluate_function(
236        &mut self,
237        name: &str,
238        args: &[FormulaExpression]
239    ) -> Result<FormulaValue> {
240        // 先计算所有参数
241        let mut arg_values = Vec::new();
242        for arg in args {
243            arg_values.push(self.evaluate(arg)?);
244        }
245
246        // 调用函数
247        self.function_library.call_function(name, &arg_values)
248    }
249
250    /// 注册内置函数
251    fn register_builtin_functions(&mut self) {
252        // 数学函数
253        self.function_library.register(Box::new(SumFunction));
254        self.function_library.register(Box::new(AverageFunction));
255        self.function_library.register(Box::new(MaxFunction));
256        self.function_library.register(Box::new(MinFunction));
257        self.function_library.register(Box::new(CountFunction));
258        self.function_library.register(Box::new(RoundFunction));
259        self.function_library.register(Box::new(AbsFunction));
260        self.function_library.register(Box::new(SqrtFunction));
261
262        // 逻辑函数
263        self.function_library.register(Box::new(IfFunction));
264        self.function_library.register(Box::new(AndFunction));
265        self.function_library.register(Box::new(OrFunction));
266        self.function_library.register(Box::new(NotFunction));
267
268        // 文本函数
269        self.function_library.register(Box::new(ConcatenateFunction));
270        self.function_library.register(Box::new(LeftFunction));
271        self.function_library.register(Box::new(RightFunction));
272        self.function_library.register(Box::new(MidFunction));
273        self.function_library.register(Box::new(LenFunction));
274        self.function_library.register(Box::new(UpperFunction));
275        self.function_library.register(Box::new(LowerFunction));
276    }
277}
278
279impl FunctionLibrary {
280    /// 创建新的函数库
281    pub fn new() -> Self {
282        Self {
283            functions: HashMap::new(),
284        }
285    }
286
287    /// 注册函数
288    pub fn register(&mut self, function: Box<dyn FormulaFunction>) {
289        self.functions.insert(function.name().to_uppercase(), function);
290    }
291
292    /// 调用函数
293    pub fn call_function(&self, name: &str, args: &[FormulaValue]) -> Result<FormulaValue> {
294        let function = self.functions.get(&name.to_uppercase()).ok_or_else(|| {
295            OfficeError::Xlsx(XlsxError::InvalidFormula {
296                formula: format!("Unknown function: {}", name),
297            })
298        })?;
299
300        // 检查参数数量
301        if args.len() < function.min_args() {
302            return Err(
303                OfficeError::Xlsx(XlsxError::InvalidFormula {
304                    formula: format!(
305                        "Function {} requires at least {} arguments",
306                        name,
307                        function.min_args()
308                    ),
309                })
310            );
311        }
312
313        if let Some(max_args) = function.max_args() {
314            if args.len() > max_args {
315                return Err(
316                    OfficeError::Xlsx(XlsxError::InvalidFormula {
317                        formula: format!(
318                            "Function {} accepts at most {} arguments",
319                            name,
320                            max_args
321                        ),
322                    })
323                );
324            }
325        }
326
327        function.execute(args)
328    }
329}
330
331// 内置函数实现
332
333/// SUM函数
334struct SumFunction;
335
336impl FormulaFunction for SumFunction {
337    fn name(&self) -> &str {
338        "SUM"
339    }
340    fn min_args(&self) -> usize {
341        1
342    }
343    fn max_args(&self) -> Option<usize> {
344        None
345    }
346
347    fn execute(&self, args: &[FormulaValue]) -> Result<FormulaValue> {
348        let mut sum = 0.0;
349
350        for arg in args {
351            match arg {
352                FormulaValue::Number(n) => {
353                    sum += n;
354                }
355                FormulaValue::Boolean(b) => {
356                    sum += if *b { 1.0 } else { 0.0 };
357                }
358                FormulaValue::Array(arr) => {
359                    for row in arr {
360                        for cell in row {
361                            if let FormulaValue::Number(n) = cell {
362                                sum += n;
363                            }
364                        }
365                    }
366                }
367                FormulaValue::Error(e) => {
368                    return Ok(FormulaValue::Error(e.clone()));
369                }
370                _ => {} // 忽略文本
371            }
372        }
373
374        Ok(FormulaValue::Number(sum))
375    }
376}
377
378/// AVERAGE函数
379struct AverageFunction;
380
381impl FormulaFunction for AverageFunction {
382    fn name(&self) -> &str {
383        "AVERAGE"
384    }
385    fn min_args(&self) -> usize {
386        1
387    }
388    fn max_args(&self) -> Option<usize> {
389        None
390    }
391
392    fn execute(&self, args: &[FormulaValue]) -> Result<FormulaValue> {
393        let mut sum = 0.0;
394        let mut count = 0;
395
396        for arg in args {
397            match arg {
398                FormulaValue::Number(n) => {
399                    sum += n;
400                    count += 1;
401                }
402                FormulaValue::Boolean(b) => {
403                    sum += if *b { 1.0 } else { 0.0 };
404                    count += 1;
405                }
406                FormulaValue::Array(arr) => {
407                    for row in arr {
408                        for cell in row {
409                            if let FormulaValue::Number(n) = cell {
410                                sum += n;
411                                count += 1;
412                            }
413                        }
414                    }
415                }
416                FormulaValue::Error(e) => {
417                    return Ok(FormulaValue::Error(e.clone()));
418                }
419                _ => {} // 忽略文本
420            }
421        }
422
423        if count == 0 {
424            Ok(FormulaValue::Error(FormulaError::DivisionByZero))
425        } else {
426            Ok(FormulaValue::Number(sum / (count as f64)))
427        }
428    }
429}
430
431/// MAX函数
432struct MaxFunction;
433
434impl FormulaFunction for MaxFunction {
435    fn name(&self) -> &str {
436        "MAX"
437    }
438    fn min_args(&self) -> usize {
439        1
440    }
441    fn max_args(&self) -> Option<usize> {
442        None
443    }
444
445    fn execute(&self, args: &[FormulaValue]) -> Result<FormulaValue> {
446        let mut max_val = f64::NEG_INFINITY;
447        let mut has_number = false;
448
449        for arg in args {
450            match arg {
451                FormulaValue::Number(n) => {
452                    max_val = max_val.max(*n);
453                    has_number = true;
454                }
455                FormulaValue::Array(arr) => {
456                    for row in arr {
457                        for cell in row {
458                            if let FormulaValue::Number(n) = cell {
459                                max_val = max_val.max(*n);
460                                has_number = true;
461                            }
462                        }
463                    }
464                }
465                FormulaValue::Error(e) => {
466                    return Ok(FormulaValue::Error(e.clone()));
467                }
468                _ => {} // 忽略其他类型
469            }
470        }
471
472        if has_number {
473            Ok(FormulaValue::Number(max_val))
474        } else {
475            Ok(FormulaValue::Number(0.0))
476        }
477    }
478}
479
480/// MIN函数
481struct MinFunction;
482
483impl FormulaFunction for MinFunction {
484    fn name(&self) -> &str {
485        "MIN"
486    }
487    fn min_args(&self) -> usize {
488        1
489    }
490    fn max_args(&self) -> Option<usize> {
491        None
492    }
493
494    fn execute(&self, args: &[FormulaValue]) -> Result<FormulaValue> {
495        let mut min_val = f64::INFINITY;
496        let mut has_number = false;
497
498        for arg in args {
499            match arg {
500                FormulaValue::Number(n) => {
501                    min_val = min_val.min(*n);
502                    has_number = true;
503                }
504                FormulaValue::Array(arr) => {
505                    for row in arr {
506                        for cell in row {
507                            if let FormulaValue::Number(n) = cell {
508                                min_val = min_val.min(*n);
509                                has_number = true;
510                            }
511                        }
512                    }
513                }
514                FormulaValue::Error(e) => {
515                    return Ok(FormulaValue::Error(e.clone()));
516                }
517                _ => {} // 忽略其他类型
518            }
519        }
520
521        if has_number {
522            Ok(FormulaValue::Number(min_val))
523        } else {
524            Ok(FormulaValue::Number(0.0))
525        }
526    }
527}
528
529/// COUNT函数
530struct CountFunction;
531
532impl FormulaFunction for CountFunction {
533    fn name(&self) -> &str {
534        "COUNT"
535    }
536    fn min_args(&self) -> usize {
537        1
538    }
539    fn max_args(&self) -> Option<usize> {
540        None
541    }
542
543    fn execute(&self, args: &[FormulaValue]) -> Result<FormulaValue> {
544        let mut count = 0;
545
546        for arg in args {
547            match arg {
548                FormulaValue::Number(_) => {
549                    count += 1;
550                }
551                FormulaValue::Array(arr) => {
552                    for row in arr {
553                        for cell in row {
554                            if let FormulaValue::Number(_) = cell {
555                                count += 1;
556                            }
557                        }
558                    }
559                }
560                FormulaValue::Error(e) => {
561                    return Ok(FormulaValue::Error(e.clone()));
562                }
563                _ => {} // 忽略其他类型
564            }
565        }
566
567        Ok(FormulaValue::Number(count as f64))
568    }
569}
570
571/// ROUND函数
572struct RoundFunction;
573
574impl FormulaFunction for RoundFunction {
575    fn name(&self) -> &str {
576        "ROUND"
577    }
578    fn min_args(&self) -> usize {
579        2
580    }
581    fn max_args(&self) -> Option<usize> {
582        Some(2)
583    }
584
585    fn execute(&self, args: &[FormulaValue]) -> Result<FormulaValue> {
586        let number = args[0].as_number()?;
587        let digits = args[1].as_number()? as i32;
588
589        let multiplier = (10.0_f64).powi(digits);
590        let rounded = (number * multiplier).round() / multiplier;
591
592        Ok(FormulaValue::Number(rounded))
593    }
594}
595
596/// ABS函数
597struct AbsFunction;
598
599impl FormulaFunction for AbsFunction {
600    fn name(&self) -> &str {
601        "ABS"
602    }
603    fn min_args(&self) -> usize {
604        1
605    }
606    fn max_args(&self) -> Option<usize> {
607        Some(1)
608    }
609
610    fn execute(&self, args: &[FormulaValue]) -> Result<FormulaValue> {
611        let number = args[0].as_number()?;
612        Ok(FormulaValue::Number(number.abs()))
613    }
614}
615
616/// SQRT函数
617struct SqrtFunction;
618
619impl FormulaFunction for SqrtFunction {
620    fn name(&self) -> &str {
621        "SQRT"
622    }
623    fn min_args(&self) -> usize {
624        1
625    }
626    fn max_args(&self) -> Option<usize> {
627        Some(1)
628    }
629
630    fn execute(&self, args: &[FormulaValue]) -> Result<FormulaValue> {
631        let number = args[0].as_number()?;
632
633        if number < 0.0 {
634            Ok(FormulaValue::Error(FormulaError::NumError))
635        } else {
636            Ok(FormulaValue::Number(number.sqrt()))
637        }
638    }
639}
640
641/// IF函数
642struct IfFunction;
643
644impl FormulaFunction for IfFunction {
645    fn name(&self) -> &str {
646        "IF"
647    }
648    fn min_args(&self) -> usize {
649        2
650    }
651    fn max_args(&self) -> Option<usize> {
652        Some(3)
653    }
654
655    fn execute(&self, args: &[FormulaValue]) -> Result<FormulaValue> {
656        let condition = args[0].as_boolean()?;
657
658        if condition {
659            Ok(args[1].clone())
660        } else if args.len() > 2 {
661            Ok(args[2].clone())
662        } else {
663            Ok(FormulaValue::Boolean(false))
664        }
665    }
666}
667
668/// AND函数
669struct AndFunction;
670
671impl FormulaFunction for AndFunction {
672    fn name(&self) -> &str {
673        "AND"
674    }
675    fn min_args(&self) -> usize {
676        1
677    }
678    fn max_args(&self) -> Option<usize> {
679        None
680    }
681
682    fn execute(&self, args: &[FormulaValue]) -> Result<FormulaValue> {
683        for arg in args {
684            if !arg.as_boolean()? {
685                return Ok(FormulaValue::Boolean(false));
686            }
687        }
688        Ok(FormulaValue::Boolean(true))
689    }
690}
691
692/// OR函数
693struct OrFunction;
694
695impl FormulaFunction for OrFunction {
696    fn name(&self) -> &str {
697        "OR"
698    }
699    fn min_args(&self) -> usize {
700        1
701    }
702    fn max_args(&self) -> Option<usize> {
703        None
704    }
705
706    fn execute(&self, args: &[FormulaValue]) -> Result<FormulaValue> {
707        for arg in args {
708            if arg.as_boolean()? {
709                return Ok(FormulaValue::Boolean(true));
710            }
711        }
712        Ok(FormulaValue::Boolean(false))
713    }
714}
715
716/// NOT函数
717struct NotFunction;
718
719impl FormulaFunction for NotFunction {
720    fn name(&self) -> &str {
721        "NOT"
722    }
723    fn min_args(&self) -> usize {
724        1
725    }
726    fn max_args(&self) -> Option<usize> {
727        Some(1)
728    }
729
730    fn execute(&self, args: &[FormulaValue]) -> Result<FormulaValue> {
731        let value = args[0].as_boolean()?;
732        Ok(FormulaValue::Boolean(!value))
733    }
734}
735
736/// CONCATENATE函数
737struct ConcatenateFunction;
738
739impl FormulaFunction for ConcatenateFunction {
740    fn name(&self) -> &str {
741        "CONCATENATE"
742    }
743    fn min_args(&self) -> usize {
744        1
745    }
746    fn max_args(&self) -> Option<usize> {
747        None
748    }
749
750    fn execute(&self, args: &[FormulaValue]) -> Result<FormulaValue> {
751        let mut result = String::new();
752
753        for arg in args {
754            result.push_str(&arg.as_text());
755        }
756
757        Ok(FormulaValue::Text(result))
758    }
759}
760
761/// LEFT函数
762struct LeftFunction;
763
764impl FormulaFunction for LeftFunction {
765    fn name(&self) -> &str {
766        "LEFT"
767    }
768    fn min_args(&self) -> usize {
769        1
770    }
771    fn max_args(&self) -> Option<usize> {
772        Some(2)
773    }
774
775    fn execute(&self, args: &[FormulaValue]) -> Result<FormulaValue> {
776        let text = args[0].as_text();
777        let num_chars = if args.len() > 1 { args[1].as_number()? as usize } else { 1 };
778
779        let result = text.chars().take(num_chars).collect::<String>();
780        Ok(FormulaValue::Text(result))
781    }
782}
783
784/// RIGHT函数
785struct RightFunction;
786
787impl FormulaFunction for RightFunction {
788    fn name(&self) -> &str {
789        "RIGHT"
790    }
791    fn min_args(&self) -> usize {
792        1
793    }
794    fn max_args(&self) -> Option<usize> {
795        Some(2)
796    }
797
798    fn execute(&self, args: &[FormulaValue]) -> Result<FormulaValue> {
799        let text = args[0].as_text();
800        let num_chars = if args.len() > 1 { args[1].as_number()? as usize } else { 1 };
801
802        let chars: Vec<char> = text.chars().collect();
803        let start = chars.len().saturating_sub(num_chars);
804        let result = chars[start..].iter().collect::<String>();
805
806        Ok(FormulaValue::Text(result))
807    }
808}
809
810/// MID函数
811struct MidFunction;
812
813impl FormulaFunction for MidFunction {
814    fn name(&self) -> &str {
815        "MID"
816    }
817    fn min_args(&self) -> usize {
818        3
819    }
820    fn max_args(&self) -> Option<usize> {
821        Some(3)
822    }
823
824    fn execute(&self, args: &[FormulaValue]) -> Result<FormulaValue> {
825        let text = args[0].as_text();
826        let start = (args[1].as_number()? as usize).saturating_sub(1); // Excel是1开始的
827        let length = args[2].as_number()? as usize;
828
829        let chars: Vec<char> = text.chars().collect();
830        let end = (start + length).min(chars.len());
831
832        if start >= chars.len() {
833            Ok(FormulaValue::Text(String::new()))
834        } else {
835            let result = chars[start..end].iter().collect::<String>();
836            Ok(FormulaValue::Text(result))
837        }
838    }
839}
840
841/// LEN函数
842struct LenFunction;
843
844impl FormulaFunction for LenFunction {
845    fn name(&self) -> &str {
846        "LEN"
847    }
848    fn min_args(&self) -> usize {
849        1
850    }
851    fn max_args(&self) -> Option<usize> {
852        Some(1)
853    }
854
855    fn execute(&self, args: &[FormulaValue]) -> Result<FormulaValue> {
856        let text = args[0].as_text();
857        Ok(FormulaValue::Number(text.chars().count() as f64))
858    }
859}
860
861/// UPPER函数
862struct UpperFunction;
863
864impl FormulaFunction for UpperFunction {
865    fn name(&self) -> &str {
866        "UPPER"
867    }
868    fn min_args(&self) -> usize {
869        1
870    }
871    fn max_args(&self) -> Option<usize> {
872        Some(1)
873    }
874
875    fn execute(&self, args: &[FormulaValue]) -> Result<FormulaValue> {
876        let text = args[0].as_text();
877        Ok(FormulaValue::Text(text.to_uppercase()))
878    }
879}
880
881/// LOWER函数
882struct LowerFunction;
883
884impl FormulaFunction for LowerFunction {
885    fn name(&self) -> &str {
886        "LOWER"
887    }
888    fn min_args(&self) -> usize {
889        1
890    }
891    fn max_args(&self) -> Option<usize> {
892        Some(1)
893    }
894
895    fn execute(&self, args: &[FormulaValue]) -> Result<FormulaValue> {
896        let text = args[0].as_text();
897        Ok(FormulaValue::Text(text.to_lowercase()))
898    }
899}
900
901#[cfg(test)]
902mod tests {
903    use super::*;
904    use crate::xlsx::cell::CellValue;
905
906    struct MockCellProvider {
907        cells: HashMap<String, CellValue>,
908    }
909
910    impl MockCellProvider {
911        fn new() -> Self {
912            let mut cells = HashMap::new();
913            cells.insert("A1".to_string(), CellValue::Number(10.0));
914            cells.insert("A2".to_string(), CellValue::Number(20.0));
915            cells.insert("A3".to_string(), CellValue::Number(30.0));
916
917            Self { cells }
918        }
919    }
920
921    impl CellProvider for MockCellProvider {
922        fn get_cell_value(&self, reference: &CellReference) -> Result<CellValue> {
923            let key = reference.to_a1();
924            Ok(self.cells.get(&key).cloned().unwrap_or(CellValue::Empty))
925        }
926
927        fn get_range_values(
928            &self,
929            start: &CellReference,
930            end: &CellReference
931        ) -> Result<Vec<Vec<CellValue>>> {
932            let mut result = Vec::new();
933
934            for row in start.row..=end.row {
935                let mut row_values = Vec::new();
936                for col in start.column..=end.column {
937                    let ref_key = CellReference::new(col, row).to_a1();
938                    row_values.push(self.cells.get(&ref_key).cloned().unwrap_or(CellValue::Empty));
939                }
940                result.push(row_values);
941            }
942
943            Ok(result)
944        }
945    }
946
947    #[test]
948    fn test_sum_function() {
949        let provider = Box::new(MockCellProvider::new());
950        let mut calculator = FormulaCalculator::new(provider);
951
952        let args = vec![
953            FormulaValue::Number(1.0),
954            FormulaValue::Number(2.0),
955            FormulaValue::Number(3.0)
956        ];
957
958        let result = calculator.function_library.call_function("SUM", &args).unwrap();
959        assert_eq!(result, FormulaValue::Number(6.0));
960    }
961
962    #[test]
963    fn test_if_function() {
964        let provider = Box::new(MockCellProvider::new());
965        let mut calculator = FormulaCalculator::new(provider);
966
967        let args = vec![
968            FormulaValue::Boolean(true),
969            FormulaValue::Text("Yes".to_string()),
970            FormulaValue::Text("No".to_string())
971        ];
972
973        let result = calculator.function_library.call_function("IF", &args).unwrap();
974        assert_eq!(result, FormulaValue::Text("Yes".to_string()));
975    }
976
977    #[test]
978    fn test_binary_operations() {
979        let provider = Box::new(MockCellProvider::new());
980        let mut calculator = FormulaCalculator::new(provider);
981
982        let left = FormulaValue::Number(10.0);
983        let right = FormulaValue::Number(3.0);
984
985        let result = calculator.evaluate_binary_op(&BinaryOperator::Add, &left, &right).unwrap();
986        assert_eq!(result, FormulaValue::Number(13.0));
987
988        let result = calculator.evaluate_binary_op(&BinaryOperator::Divide, &left, &right).unwrap();
989        assert_eq!(result, FormulaValue::Number(10.0 / 3.0));
990    }
991
992    #[test]
993    fn test_factorial() {
994        let provider = Box::new(MockCellProvider::new());
995        let calculator = FormulaCalculator::new(provider);
996
997        // Test positive integers
998        let result = calculator
999            .evaluate_unary_op(&UnaryOperator::Factorial, &FormulaValue::Number(5.0))
1000            .unwrap();
1001        assert_eq!(result, FormulaValue::Number(120.0)); // 5! = 120
1002
1003        let result = calculator
1004            .evaluate_unary_op(&UnaryOperator::Factorial, &FormulaValue::Number(0.0))
1005            .unwrap();
1006        assert_eq!(result, FormulaValue::Number(1.0)); // 0! = 1
1007
1008        // Test negative number
1009        let result = calculator
1010            .evaluate_unary_op(&UnaryOperator::Factorial, &FormulaValue::Number(-3.0))
1011            .unwrap();
1012        assert_eq!(result, FormulaValue::Error(FormulaError::ValueError));
1013
1014        // Test decimal number
1015        let result = calculator
1016            .evaluate_unary_op(&UnaryOperator::Factorial, &FormulaValue::Number(3.5))
1017            .unwrap();
1018        assert_eq!(result, FormulaValue::Error(FormulaError::ValueError));
1019
1020        // Test large number
1021        let result = calculator
1022            .evaluate_unary_op(&UnaryOperator::Factorial, &FormulaValue::Number(10.0))
1023            .unwrap();
1024        assert_eq!(result, FormulaValue::Number(3628800.0)); // 10! = 3,628,800
1025    }
1026}