mf_expression/functions/
internal.rs

1//! 内置函数模块
2//!
3//! 提供表达式系统中的所有内置函数,包括通用、字符串、数学、类型和映射相关函数
4
5use crate::functions::defs::{
6    CompositeFunction, FunctionDefinition, FunctionSignature, StaticFunction,
7};
8use std::rc::Rc;
9use strum_macros::{Display, EnumIter, EnumString, IntoStaticStr};
10
11/// 内置函数枚举
12///
13/// 定义了表达式系统中所有可用的内置函数
14#[derive(
15    Debug,
16    PartialEq,
17    Eq,
18    Hash,
19    Display,
20    EnumString,
21    EnumIter,
22    IntoStaticStr,
23    Clone,
24    Copy,
25)]
26#[strum(serialize_all = "camelCase")]
27pub enum InternalFunction {
28    // 通用函数
29    /// 长度函数:获取字符串长度或数组元素个数
30    Len,
31    /// 包含函数:检查字符串包含子串或数组包含元素
32    Contains,
33    /// 扁平化函数:将嵌套数组展平为一维数组
34    Flatten,
35
36    // 字符串函数
37    /// 转大写:将字符串转换为大写
38    Upper,
39    /// 转小写:将字符串转换为小写
40    Lower,
41    /// 去空格:移除字符串两端的空白字符
42    Trim,
43    /// 开始匹配:检查字符串是否以指定前缀开始
44    StartsWith,
45    /// 结束匹配:检查字符串是否以指定后缀结束
46    EndsWith,
47    /// 正则匹配:检查字符串是否匹配正则表达式
48    Matches,
49    /// 提取匹配:使用正则表达式提取字符串中的匹配内容
50    Extract,
51    /// 模糊匹配:计算两个字符串或字符串数组的相似度
52    FuzzyMatch,
53    /// 分割:使用分隔符将字符串分割为数组
54    Split,
55
56    // 数学函数
57    /// 绝对值:返回数字的绝对值
58    Abs,
59    /// 求和:计算数组中所有数字的和
60    Sum,
61    /// 平均值:计算数组中所有数字的平均值
62    Avg,
63    /// 最小值:返回数组中的最小值
64    Min,
65    /// 最大值:返回数组中的最大值
66    Max,
67    /// 随机数:生成0到指定数字之间的随机数
68    Rand,
69    /// 中位数:计算数组的中位数
70    Median,
71    /// 众数:计算数组的众数
72    Mode,
73    /// 向下取整:返回不大于给定数字的最大整数
74    Floor,
75    /// 向上取整:返回不小于给定数字的最小整数
76    Ceil,
77    /// 四舍五入:对数字进行四舍五入
78    Round,
79    /// 截断:截断数字的小数部分
80    Trunc,
81
82    // 类型函数
83    /// 数字检查:检查值是否为数字类型
84    IsNumeric,
85    /// 字符串转换:将值转换为字符串
86    String,
87    /// 数字转换:将值转换为数字
88    Number,
89    /// 布尔转换:将值转换为布尔值
90    Bool,
91    /// 类型获取:返回值的类型名称
92    Type,
93
94    // 映射函数
95    /// 键列表:获取对象的所有键
96    Keys,
97    /// 值列表:获取对象的所有值
98    Values,
99
100    /// 日期函数:创建或解析日期(使用简写'd')
101    #[strum(serialize = "d")]
102    Date,
103}
104
105impl From<&InternalFunction> for Rc<dyn FunctionDefinition> {
106    /// 将内置函数枚举转换为函数定义
107    ///
108    /// 为每个内置函数创建相应的函数定义,包括函数签名和实现
109    fn from(value: &InternalFunction) -> Self {
110        use crate::variable::VariableType as VT;
111        use InternalFunction as IF;
112
113        let s: Rc<dyn FunctionDefinition> = match value {
114            // 长度函数:支持字符串和数组
115            IF::Len => Rc::new(CompositeFunction {
116                implementation: Rc::new(imp::len),
117                signatures: vec![
118                    FunctionSignature::single(VT::String, VT::Number),
119                    FunctionSignature::single(VT::Any.array(), VT::Number),
120                ],
121            }),
122
123            // 包含函数:支持字符串包含和数组包含
124            IF::Contains => Rc::new(CompositeFunction {
125                implementation: Rc::new(imp::contains),
126                signatures: vec![
127                    FunctionSignature {
128                        parameters: vec![VT::String, VT::String],
129                        return_type: VT::Bool,
130                    },
131                    FunctionSignature {
132                        parameters: vec![VT::Any.array(), VT::Any],
133                        return_type: VT::Bool,
134                    },
135                ],
136            }),
137
138            // 扁平化函数:将嵌套数组展平
139            IF::Flatten => Rc::new(StaticFunction {
140                implementation: Rc::new(imp::flatten),
141                signature: FunctionSignature::single(
142                    VT::Any.array(),
143                    VT::Any.array(),
144                ),
145            }),
146
147            // 字符串转大写
148            IF::Upper => Rc::new(StaticFunction {
149                implementation: Rc::new(imp::upper),
150                signature: FunctionSignature::single(VT::String, VT::String),
151            }),
152
153            // 字符串转小写
154            IF::Lower => Rc::new(StaticFunction {
155                implementation: Rc::new(imp::lower),
156                signature: FunctionSignature::single(VT::String, VT::String),
157            }),
158
159            // 字符串去空格
160            IF::Trim => Rc::new(StaticFunction {
161                implementation: Rc::new(imp::trim),
162                signature: FunctionSignature::single(VT::String, VT::String),
163            }),
164
165            // 字符串开始匹配
166            IF::StartsWith => Rc::new(StaticFunction {
167                implementation: Rc::new(imp::starts_with),
168                signature: FunctionSignature {
169                    parameters: vec![VT::String, VT::String],
170                    return_type: VT::Bool,
171                },
172            }),
173
174            // 字符串结束匹配
175            IF::EndsWith => Rc::new(StaticFunction {
176                implementation: Rc::new(imp::ends_with),
177                signature: FunctionSignature {
178                    parameters: vec![VT::String, VT::String],
179                    return_type: VT::Bool,
180                },
181            }),
182
183            // 正则表达式匹配
184            IF::Matches => Rc::new(StaticFunction {
185                implementation: Rc::new(imp::matches),
186                signature: FunctionSignature {
187                    parameters: vec![VT::String, VT::String],
188                    return_type: VT::Bool,
189                },
190            }),
191
192            // 正则表达式提取
193            IF::Extract => Rc::new(StaticFunction {
194                implementation: Rc::new(imp::extract),
195                signature: FunctionSignature {
196                    parameters: vec![VT::String, VT::String],
197                    return_type: VT::String.array(),
198                },
199            }),
200
201            // 字符串分割
202            IF::Split => Rc::new(StaticFunction {
203                implementation: Rc::new(imp::split),
204                signature: FunctionSignature {
205                    parameters: vec![VT::String, VT::String],
206                    return_type: VT::String.array(),
207                },
208            }),
209
210            // 模糊匹配:支持单个字符串和字符串数组
211            IF::FuzzyMatch => Rc::new(CompositeFunction {
212                implementation: Rc::new(imp::fuzzy_match),
213                signatures: vec![
214                    FunctionSignature {
215                        parameters: vec![VT::String, VT::String],
216                        return_type: VT::Number,
217                    },
218                    FunctionSignature {
219                        parameters: vec![VT::String.array(), VT::String],
220                        return_type: VT::Number.array(),
221                    },
222                ],
223            }),
224
225            // 绝对值
226            IF::Abs => Rc::new(StaticFunction {
227                implementation: Rc::new(imp::abs),
228                signature: FunctionSignature::single(VT::Number, VT::Number),
229            }),
230
231            // 随机数生成
232            IF::Rand => Rc::new(StaticFunction {
233                implementation: Rc::new(imp::rand),
234                signature: FunctionSignature::single(VT::Number, VT::Number),
235            }),
236
237            // 向下取整
238            IF::Floor => Rc::new(StaticFunction {
239                implementation: Rc::new(imp::floor),
240                signature: FunctionSignature::single(VT::Number, VT::Number),
241            }),
242
243            // 向上取整
244            IF::Ceil => Rc::new(StaticFunction {
245                implementation: Rc::new(imp::ceil),
246                signature: FunctionSignature::single(VT::Number, VT::Number),
247            }),
248
249            // 四舍五入:支持指定小数位数
250            IF::Round => Rc::new(CompositeFunction {
251                implementation: Rc::new(imp::round),
252                signatures: vec![
253                    FunctionSignature {
254                        parameters: vec![VT::Number],
255                        return_type: VT::Number,
256                    },
257                    FunctionSignature {
258                        parameters: vec![VT::Number, VT::Number],
259                        return_type: VT::Number,
260                    },
261                ],
262            }),
263
264            // 截断:支持指定小数位数
265            IF::Trunc => Rc::new(CompositeFunction {
266                implementation: Rc::new(imp::trunc),
267                signatures: vec![
268                    FunctionSignature {
269                        parameters: vec![VT::Number],
270                        return_type: VT::Number,
271                    },
272                    FunctionSignature {
273                        parameters: vec![VT::Number, VT::Number],
274                        return_type: VT::Number,
275                    },
276                ],
277            }),
278
279            // 求和
280            IF::Sum => Rc::new(StaticFunction {
281                implementation: Rc::new(imp::sum),
282                signature: FunctionSignature::single(
283                    VT::Number.array(),
284                    VT::Number,
285                ),
286            }),
287
288            // 平均值
289            IF::Avg => Rc::new(StaticFunction {
290                implementation: Rc::new(imp::avg),
291                signature: FunctionSignature::single(
292                    VT::Number.array(),
293                    VT::Number,
294                ),
295            }),
296
297            // 最小值
298            IF::Min => Rc::new(CompositeFunction {
299                implementation: Rc::new(imp::min),
300                signatures: vec![
301                    FunctionSignature::single(VT::Number.array(), VT::Number),
302                    FunctionSignature::single(VT::Date.array(), VT::Date),
303                ],
304            }),
305
306            // 最大值
307            IF::Max => Rc::new(CompositeFunction {
308                implementation: Rc::new(imp::max),
309                signatures: vec![
310                    FunctionSignature::single(VT::Number.array(), VT::Number),
311                    FunctionSignature::single(VT::Date.array(), VT::Date),
312                ],
313            }),
314
315            // 中位数
316            IF::Median => Rc::new(StaticFunction {
317                implementation: Rc::new(imp::median),
318                signature: FunctionSignature::single(
319                    VT::Number.array(),
320                    VT::Number,
321                ),
322            }),
323
324            // 众数
325            IF::Mode => Rc::new(StaticFunction {
326                implementation: Rc::new(imp::mode),
327                signature: FunctionSignature::single(
328                    VT::Number.array(),
329                    VT::Number,
330                ),
331            }),
332
333            // 类型获取
334            IF::Type => Rc::new(StaticFunction {
335                implementation: Rc::new(imp::to_type),
336                signature: FunctionSignature::single(VT::Any, VT::String),
337            }),
338
339            // 字符串转换
340            IF::String => Rc::new(StaticFunction {
341                implementation: Rc::new(imp::to_string),
342                signature: FunctionSignature::single(VT::Any, VT::String),
343            }),
344
345            // 布尔转换
346            IF::Bool => Rc::new(StaticFunction {
347                implementation: Rc::new(imp::to_bool),
348                signature: FunctionSignature::single(VT::Any, VT::Bool),
349            }),
350
351            // 数字检查
352            IF::IsNumeric => Rc::new(StaticFunction {
353                implementation: Rc::new(imp::is_numeric),
354                signature: FunctionSignature::single(VT::Any, VT::Bool),
355            }),
356
357            // 数字转换
358            IF::Number => Rc::new(StaticFunction {
359                implementation: Rc::new(imp::to_number),
360                signature: FunctionSignature::single(VT::Any, VT::Number),
361            }),
362
363            // 键列表
364            IF::Keys => Rc::new(CompositeFunction {
365                implementation: Rc::new(imp::keys),
366                signatures: vec![
367                    FunctionSignature::single(
368                        VT::Object(Default::default()),
369                        VT::String.array(),
370                    ),
371                    FunctionSignature::single(
372                        VT::Any.array(),
373                        VT::Number.array(),
374                    ),
375                ],
376            }),
377
378            // 值列表
379            IF::Values => Rc::new(StaticFunction {
380                implementation: Rc::new(imp::values),
381                signature: FunctionSignature::single(
382                    VT::Object(Default::default()),
383                    VT::Any.array(),
384                ),
385            }),
386
387            // 日期函数
388            IF::Date => Rc::new(CompositeFunction {
389                implementation: Rc::new(imp::date),
390                signatures: vec![
391                    FunctionSignature {
392                        parameters: vec![],
393                        return_type: VT::Date,
394                    },
395                    FunctionSignature {
396                        parameters: vec![VT::Any],
397                        return_type: VT::Date,
398                    },
399                    FunctionSignature {
400                        parameters: vec![VT::Any, VT::String],
401                        return_type: VT::Date,
402                    },
403                ],
404            }),
405        };
406
407        s
408    }
409}
410
411/// 内置函数实现模块
412///
413/// 包含所有内置函数的具体实现代码
414pub(crate) mod imp {
415    use crate::functions::arguments::Arguments;
416    use crate::vm::VmDate;
417    use crate::{Variable as V, Variable};
418    use anyhow::{anyhow, Context};
419    use chrono_tz::Tz;
420    #[cfg(not(feature = "regex-lite"))]
421    use regex::Regex;
422    #[cfg(feature = "regex-lite")]
423    use regex_lite::Regex;
424    use rust_decimal::prelude::{FromPrimitive, ToPrimitive};
425    use rust_decimal::{Decimal, RoundingStrategy};
426    use rust_decimal_macros::dec;
427    use std::collections::BTreeMap;
428    use std::rc::Rc;
429    use std::str::FromStr;
430
431    /// 辅助函数:从参数中提取数字数组
432    ///
433    /// # 参数
434    /// * `args` - 函数参数
435    /// * `pos` - 参数位置
436    ///
437    /// # 返回值
438    /// * `Ok(Vec<Decimal>)` - 成功提取的数字数组
439    /// * `Err` - 参数不是数组或包含非数字元素
440    fn __internal_number_array(
441        args: &Arguments,
442        pos: usize,
443    ) -> anyhow::Result<Vec<Decimal>> {
444        let a = args.array(pos)?;
445        let arr = a.borrow();
446
447        arr.iter()
448            .map(|v| v.as_number())
449            .collect::<Option<Vec<_>>>()
450            .context("Expected a number array")
451    }
452
453    /// 联合类型:表示数字数组或日期数组
454    enum Either<A, B> {
455        Left(A),
456        Right(B),
457    }
458
459    /// 辅助函数:从参数中提取数字数组或日期数组
460    ///
461    /// 根据数组的第一个元素类型自动判断是数字数组还是日期数组
462    ///
463    /// # 参数
464    /// * `args` - 函数参数
465    /// * `pos` - 参数位置
466    ///
467    /// # 返回值
468    /// * `Ok(Either::Left(Vec<Decimal>))` - 数字数组
469    /// * `Ok(Either::Right(Vec<VmDate>))` - 日期数组
470    /// * `Err` - 参数无效或类型不匹配
471    fn __internal_number_or_date_array(
472        args: &Arguments,
473        pos: usize,
474    ) -> anyhow::Result<Either<Vec<Decimal>, Vec<VmDate>>> {
475        let a = args.array(pos)?;
476        let arr = a.borrow();
477
478        let is_number = arr.first().map(|v| v.as_number()).flatten().is_some();
479        if is_number {
480            Ok(Either::Left(
481                arr.iter()
482                    .map(|v| v.as_number())
483                    .collect::<Option<Vec<_>>>()
484                    .context("Expected a number array")?,
485            ))
486        } else {
487            Ok(Either::Right(
488                arr.iter()
489                    .map(|v| match v {
490                        Variable::Dynamic(d) => d.as_date().cloned(),
491                        _ => None,
492                    })
493                    .collect::<Option<Vec<_>>>()
494                    .context("Expected a number array")?,
495            ))
496        }
497    }
498
499    /// 字符串开始匹配函数实现
500    ///
501    /// 检查第一个字符串是否以第二个字符串开始
502    pub fn starts_with(args: Arguments) -> anyhow::Result<V> {
503        let a = args.str(0)?;
504        let b = args.str(1)?;
505
506        Ok(V::Bool(a.starts_with(b)))
507    }
508
509    /// 字符串结束匹配函数实现
510    ///
511    /// 检查第一个字符串是否以第二个字符串结束
512    pub fn ends_with(args: Arguments) -> anyhow::Result<V> {
513        let a = args.str(0)?;
514        let b = args.str(1)?;
515
516        Ok(V::Bool(a.ends_with(b)))
517    }
518
519    /// 正则表达式匹配函数实现
520    ///
521    /// 使用正则表达式检查字符串是否匹配模式
522    pub fn matches(args: Arguments) -> anyhow::Result<V> {
523        let a = args.str(0)?;
524        let b = args.str(1)?;
525
526        let regex =
527            Regex::new(b.as_ref()).context("Invalid regular expression")?;
528
529        Ok(V::Bool(regex.is_match(a.as_ref())))
530    }
531
532    /// 字符串转大写函数实现
533    ///
534    /// 将字符串转换为大写形式
535    pub fn upper(args: Arguments) -> anyhow::Result<V> {
536        let a = args.str(0)?;
537        Ok(V::String(a.to_uppercase().into()))
538    }
539
540    /// 字符串转小写函数实现
541    ///
542    /// 将字符串转换为小写形式
543    pub fn lower(args: Arguments) -> anyhow::Result<V> {
544        let a = args.str(0)?;
545        Ok(V::String(a.to_lowercase().into()))
546    }
547
548    /// 字符串去空格函数实现
549    ///
550    /// 移除字符串两端的空白字符
551    pub fn trim(args: Arguments) -> anyhow::Result<V> {
552        let a = args.str(0)?;
553        Ok(V::String(a.trim().into()))
554    }
555
556    /// 正则表达式提取函数实现
557    ///
558    /// 使用正则表达式从字符串中提取匹配的捕获组
559    /// 返回包含所有捕获组的字符串数组
560    pub fn extract(args: Arguments) -> anyhow::Result<V> {
561        let a = args.str(0)?;
562        let b = args.str(1)?;
563
564        let regex =
565            Regex::new(b.as_ref()).context("Invalid regular expression")?;
566
567        let captures = regex
568            .captures(a.as_ref())
569            .map(|capture| {
570                capture
571                    .iter()
572                    .map(|c| c.map(|c| c.as_str()))
573                    .filter_map(|c| c)
574                    .map(|s| V::String(Rc::from(s)))
575                    .collect()
576            })
577            .unwrap_or_default();
578
579        Ok(V::from_array(captures))
580    }
581
582    /// 字符串分割函数实现
583    ///
584    /// 使用指定分隔符将字符串分割为字符串数组
585    pub fn split(args: Arguments) -> anyhow::Result<V> {
586        let a = args.str(0)?;
587        let b = args.str(1)?;
588
589        let arr = Vec::from_iter(
590            a.split(b).into_iter().map(|s| V::String(s.to_string().into())),
591        );
592
593        Ok(V::from_array(arr))
594    }
595
596    /// 数组扁平化函数实现
597    ///
598    /// 将嵌套数组展平为一维数组,非数组元素保持不变
599    pub fn flatten(args: Arguments) -> anyhow::Result<V> {
600        let a = args.array(0)?;
601
602        let arr = a.borrow();
603        let mut flat_arr = Vec::with_capacity(arr.len());
604        arr.iter().for_each(|v| match v {
605            V::Array(b) => {
606                let arr = b.borrow();
607                arr.iter().for_each(|v| flat_arr.push(v.clone()))
608            },
609            _ => flat_arr.push(v.clone()),
610        });
611
612        Ok(V::from_array(flat_arr))
613    }
614
615    /// 绝对值函数实现
616    ///
617    /// 返回数字的绝对值
618    pub fn abs(args: Arguments) -> anyhow::Result<V> {
619        let a = args.number(0)?;
620        Ok(V::Number(a.abs()))
621    }
622
623    /// 向上取整函数实现
624    ///
625    /// 返回不小于给定数字的最小整数
626    pub fn ceil(args: Arguments) -> anyhow::Result<V> {
627        let a = args.number(0)?;
628        Ok(V::Number(a.ceil()))
629    }
630
631    /// 向下取整函数实现
632    ///
633    /// 返回不大于给定数字的最大整数
634    pub fn floor(args: Arguments) -> anyhow::Result<V> {
635        let a = args.number(0)?;
636        Ok(V::Number(a.floor()))
637    }
638
639    /// 四舍五入函数实现
640    ///
641    /// 对数字进行四舍五入,可选择指定小数位数
642    pub fn round(args: Arguments) -> anyhow::Result<V> {
643        let a = args.number(0)?;
644        let dp = args
645            .onumber(1)?
646            .map(|v| v.to_u32().context("Invalid number of decimal places"))
647            .transpose()?
648            .unwrap_or(0);
649
650        Ok(V::Number(a.round_dp_with_strategy(
651            dp,
652            RoundingStrategy::MidpointAwayFromZero,
653        )))
654    }
655
656    /// 截断函数实现
657    ///
658    /// 截断数字的小数部分,可选择指定保留的小数位数
659    pub fn trunc(args: Arguments) -> anyhow::Result<V> {
660        let a = args.number(0)?;
661        let dp = args
662            .onumber(1)?
663            .map(|v| v.to_u32().context("Invalid number of decimal places"))
664            .transpose()?
665            .unwrap_or(0);
666
667        Ok(V::Number(a.trunc_with_scale(dp)))
668    }
669
670    /// 随机数生成函数实现
671    ///
672    /// 生成0到指定数字之间的随机整数
673    pub fn rand(args: Arguments) -> anyhow::Result<V> {
674        let a = args.number(0)?;
675        let upper_range = a.round().to_i64().context("Invalid upper range")?;
676
677        let random_number = fastrand::i64(0..=upper_range);
678        Ok(V::Number(Decimal::from(random_number)))
679    }
680
681    /// 最小值函数实现
682    ///
683    /// 返回数字数组或日期数组中的最小值
684    pub fn min(args: Arguments) -> anyhow::Result<V> {
685        let a = __internal_number_or_date_array(&args, 0)?;
686
687        match a {
688            Either::Left(arr) => {
689                let min = arr.into_iter().min().context("Empty array")?;
690                Ok(V::Number(Decimal::from(min)))
691            },
692            Either::Right(arr) => {
693                let min = arr.into_iter().min().context("Empty array")?;
694                Ok(V::Dynamic(Rc::new(min)))
695            },
696        }
697    }
698
699    /// 最大值函数实现
700    ///
701    /// 返回数字数组或日期数组中的最大值
702    pub fn max(args: Arguments) -> anyhow::Result<V> {
703        let a = __internal_number_or_date_array(&args, 0)?;
704
705        match a {
706            Either::Left(arr) => {
707                let max = arr.into_iter().max().context("Empty array")?;
708                Ok(V::Number(Decimal::from(max)))
709            },
710            Either::Right(arr) => {
711                let max = arr.into_iter().max().context("Empty array")?;
712                Ok(V::Dynamic(Rc::new(max)))
713            },
714        }
715    }
716
717    /// 平均值函数实现
718    ///
719    /// 计算数字数组的算术平均值
720    pub fn avg(args: Arguments) -> anyhow::Result<V> {
721        let a = __internal_number_array(&args, 0)?;
722        let sum = a.iter().fold(Decimal::ZERO, |acc, x| acc + x);
723
724        Ok(V::Number(Decimal::from(
725            sum.checked_div(Decimal::from(a.len())).context("Empty array")?,
726        )))
727    }
728
729    /// 求和函数实现
730    ///
731    /// 计算数字数组中所有元素的和
732    pub fn sum(args: Arguments) -> anyhow::Result<V> {
733        let a = __internal_number_array(&args, 0)?;
734        let sum = a.iter().fold(Decimal::ZERO, |acc, v| acc + v);
735
736        Ok(V::Number(Decimal::from(sum)))
737    }
738
739    /// 中位数函数实现
740    ///
741    /// 计算数字数组的中位数(中间值)
742    pub fn median(args: Arguments) -> anyhow::Result<V> {
743        let mut a = __internal_number_array(&args, 0)?;
744        a.sort();
745
746        let center = a.len() / 2;
747        if a.len() % 2 == 1 {
748            // 奇数个元素,取中间的元素
749            let center_num = a.get(center).context("Index out of bounds")?;
750            Ok(V::Number(*center_num))
751        } else {
752            // 偶数个元素,取中间两个元素的平均值
753            let center_left =
754                a.get(center - 1).context("Index out of bounds")?;
755            let center_right = a.get(center).context("Index out of bounds")?;
756
757            let median = ((*center_left) + (*center_right)) / dec!(2);
758            Ok(V::Number(median))
759        }
760    }
761
762    /// 众数函数实现
763    ///
764    /// 计算数字数组的众数(出现次数最多的值)
765    pub fn mode(args: Arguments) -> anyhow::Result<V> {
766        let a = __internal_number_array(&args, 0)?;
767        let mut counts = BTreeMap::new();
768        for num in a {
769            *counts.entry(num).or_insert(0) += 1;
770        }
771
772        let most_common = counts
773            .into_iter()
774            .max_by_key(|&(_, count)| count)
775            .map(|(num, _)| num)
776            .context("Empty array")?;
777
778        Ok(V::Number(most_common))
779    }
780
781    pub fn to_type(args: Arguments) -> anyhow::Result<V> {
782        let a = args.var(0)?;
783        Ok(V::String(a.type_name().into()))
784    }
785
786    pub fn to_bool(args: Arguments) -> anyhow::Result<V> {
787        let a = args.var(0)?;
788        let val = match a {
789            V::Null => false,
790            V::Bool(v) => *v,
791            V::Number(n) => !n.is_zero(),
792            V::Array(_) | V::Object(_) | V::Dynamic(_) => true,
793            V::String(s) => match (*s).trim() {
794                "true" => true,
795                "false" => false,
796                _ => s.is_empty(),
797            },
798        };
799
800        Ok(V::Bool(val))
801    }
802
803    pub fn to_string(args: Arguments) -> anyhow::Result<V> {
804        let a = args.var(0)?;
805        let val = match a {
806            V::Null => Rc::from("null"),
807            V::Bool(v) => Rc::from(v.to_string().as_str()),
808            V::Number(n) => Rc::from(n.to_string().as_str()),
809            V::String(s) => s.clone(),
810            _ => {
811                return Err(anyhow!(
812                    "Cannot convert type {} to string",
813                    a.type_name()
814                ));
815            },
816        };
817
818        Ok(V::String(val))
819    }
820
821    pub fn to_number(args: Arguments) -> anyhow::Result<V> {
822        let a = args.var(0)?;
823        let val = match a {
824            V::Number(n) => *n,
825            V::String(str) => {
826                let s = str.trim();
827                Decimal::from_str_exact(s)
828                    .or_else(|_| Decimal::from_scientific(s))
829                    .context("Invalid number")?
830            },
831            V::Bool(b) => match *b {
832                true => Decimal::ONE,
833                false => Decimal::ZERO,
834            },
835            _ => {
836                return Err(anyhow!(
837                    "Cannot convert type {} to number",
838                    a.type_name()
839                ));
840            },
841        };
842
843        Ok(V::Number(val))
844    }
845
846    pub fn is_numeric(args: Arguments) -> anyhow::Result<V> {
847        let a = args.var(0)?;
848        let is_ok = match a {
849            V::Number(_) => true,
850            V::String(str) => {
851                let s = str.trim();
852                Decimal::from_str_exact(s)
853                    .or_else(|_| Decimal::from_scientific(s))
854                    .is_ok()
855            },
856            _ => false,
857        };
858
859        Ok(V::Bool(is_ok))
860    }
861
862    pub fn len(args: Arguments) -> anyhow::Result<V> {
863        let a = args.var(0)?;
864        let len = match a {
865            V::String(s) => s.len(),
866            V::Array(s) => {
867                let arr = s.borrow();
868                arr.len()
869            },
870            _ => {
871                return Err(anyhow!(
872                    "Cannot determine len of type {}",
873                    a.type_name()
874                ));
875            },
876        };
877
878        Ok(V::Number(len.into()))
879    }
880
881    pub fn contains(args: Arguments) -> anyhow::Result<V> {
882        let a = args.var(0)?;
883        let b = args.var(1)?;
884
885        let val = match (a, b) {
886            (V::String(a), V::String(b)) => a.contains(b.as_ref()),
887            (V::Array(a), _) => {
888                let arr = a.borrow();
889
890                arr.iter().any(|a| match (a, b) {
891                    (V::Number(a), V::Number(b)) => a == b,
892                    (V::String(a), V::String(b)) => a == b,
893                    (V::Bool(a), V::Bool(b)) => a == b,
894                    (V::Null, V::Null) => true,
895                    _ => false,
896                })
897            },
898            _ => {
899                return Err(anyhow!(
900                    "无法确定类型 {} 和 {} 的包含关系",
901                    a.type_name(),
902                    b.type_name()
903                ));
904            },
905        };
906
907        Ok(V::Bool(val))
908    }
909
910    pub fn fuzzy_match(args: Arguments) -> anyhow::Result<V> {
911        let a = args.var(0)?;
912        let b = args.str(1)?;
913
914        let val = match a {
915            V::String(a) => {
916                let sim = strsim::normalized_damerau_levenshtein(
917                    a.as_ref(),
918                    b.as_ref(),
919                );
920                // This is okay, as NDL will return [0, 1]
921                V::Number(Decimal::from_f64(sim).unwrap_or(dec!(0)))
922            },
923            V::Array(_a) => {
924                let a = _a.borrow();
925                let mut sims = Vec::with_capacity(a.len());
926                for v in a.iter() {
927                    let s = v.as_str().context("期望字符串数组")?;
928
929                    let sim = Decimal::from_f64(
930                        strsim::normalized_damerau_levenshtein(
931                            s.as_ref(),
932                            b.as_ref(),
933                        ),
934                    )
935                    .unwrap_or(dec!(0));
936                    sims.push(V::Number(sim));
937                }
938
939                V::from_array(sims)
940            },
941            _ => {
942                return Err(anyhow!("模糊匹配不适用于类型 {} ", a.type_name()));
943            },
944        };
945
946        Ok(val)
947    }
948
949    pub fn keys(args: Arguments) -> anyhow::Result<V> {
950        let a = args.var(0)?;
951        let var = match a {
952            V::Array(a) => {
953                let arr = a.borrow();
954                let indices = arr
955                    .iter()
956                    .enumerate()
957                    .map(|(index, _)| V::Number(index.into()))
958                    .collect();
959
960                V::from_array(indices)
961            },
962            V::Object(a) => {
963                let obj = a.borrow();
964                let keys =
965                    obj.iter().map(|(key, _)| V::String(key.clone())).collect();
966
967                V::from_array(keys)
968            },
969            _ => {
970                return Err(anyhow!("无法确定类型 {} 的键", a.type_name()));
971            },
972        };
973
974        Ok(var)
975    }
976
977    pub fn values(args: Arguments) -> anyhow::Result<V> {
978        let a = args.object(0)?;
979        let obj = a.borrow();
980        let values: Vec<_> = obj.values().cloned().collect();
981
982        Ok(V::from_array(values))
983    }
984
985    pub fn date(args: Arguments) -> anyhow::Result<V> {
986        let provided = args.ovar(0);
987        let tz = args
988            .ostr(1)?
989            .map(|v| Tz::from_str(v).context("无效的时区"))
990            .transpose()?;
991
992        let date_time = match provided {
993            Some(v) => VmDate::new(v.clone(), tz),
994            None => VmDate::now(),
995        };
996
997        Ok(V::Dynamic(Rc::new(date_time)))
998    }
999}