aether/builtins/
mod.rs

1// src/builtins/mod.rs
2//! Built-in functions standard library
3
4use crate::evaluator::RuntimeError;
5use crate::value::Value;
6use std::collections::HashMap;
7
8// Module declarations
9pub mod array;
10pub mod dict;
11pub mod filesystem;
12pub mod help;
13pub mod io;
14pub mod json;
15pub mod math;
16pub mod network;
17pub mod payroll;
18pub mod precise;
19pub mod report;
20pub mod string;
21pub mod types;
22
23/// Type alias for built-in function implementations
24pub type BuiltInFn = fn(&[Value]) -> Result<Value, RuntimeError>;
25
26/// 函数文档信息
27#[derive(Debug, Clone)]
28pub struct FunctionDoc {
29    /// 函数名称
30    pub name: String,
31    /// 函数描述
32    pub description: String,
33    /// 参数列表(参数名和描述)
34    pub params: Vec<(String, String)>,
35    /// 返回值描述
36    pub returns: String,
37    /// 使用示例
38    pub example: Option<String>,
39}
40
41/// IO 权限配置
42#[derive(Debug, Clone, Default)]
43pub struct IOPermissions {
44    /// 是否允许文件系统操作
45    pub filesystem_enabled: bool,
46    /// 是否允许网络操作
47    pub network_enabled: bool,
48}
49
50impl IOPermissions {
51    /// 创建启用所有权限的配置
52    pub fn allow_all() -> Self {
53        Self {
54            filesystem_enabled: true,
55            network_enabled: true,
56        }
57    }
58
59    /// 创建禁用所有权限的配置
60    pub fn deny_all() -> Self {
61        Self::default()
62    }
63}
64
65/// Registry of all built-in functions
66pub struct BuiltInRegistry {
67    functions: HashMap<String, (BuiltInFn, usize)>, // (function, arity)
68    docs: HashMap<String, FunctionDoc>,             // 函数文档
69    #[allow(dead_code)]
70    permissions: IOPermissions,
71}
72
73impl BuiltInRegistry {
74    /// Create a new registry with all built-in functions (默认禁用IO)
75    pub fn new() -> Self {
76        Self::with_permissions(IOPermissions::default())
77    }
78
79    /// Create a new registry with custom permissions
80    pub fn with_permissions(permissions: IOPermissions) -> Self {
81        let mut registry = Self {
82            functions: HashMap::new(),
83            docs: HashMap::new(),
84            permissions: permissions.clone(),
85        };
86
87        // Help function
88        registry.register("HELP", help::help, 0); // Variadic: 0-1 args
89
90        // IO functions
91        registry.register("PRINT", io::print, 1);
92        registry.register("PRINTLN", io::println, 1);
93        registry.register("INPUT", io::input, 1);
94
95        // Array functions
96        registry.register("RANGE", array::range, 1); // Variadic: 1-3 args
97        registry.register("LEN", types::len, 1);
98        registry.register("PUSH", array::push, 2);
99        registry.register("POP", array::pop, 1);
100        registry.register("MAP", array::map, 2);
101        registry.register("FILTER", array::filter, 2);
102        registry.register("REDUCE", array::reduce, 3);
103        registry.register("JOIN", array::join, 2);
104        registry.register("REVERSE", array::reverse, 1);
105        registry.register("SORT", array::sort, 1);
106        registry.register("SUM", array::sum, 1);
107        registry.register("MAX", array::max, 1);
108        registry.register("MIN", array::min, 1);
109
110        // Dict functions
111        registry.register("KEYS", dict::keys, 1);
112        registry.register("VALUES", dict::values, 1);
113        registry.register("HAS", dict::has, 2);
114        registry.register("MERGE", dict::merge, 2);
115
116        // String functions
117        registry.register("SPLIT", string::split, 2);
118        registry.register("UPPER", string::upper, 1);
119        registry.register("LOWER", string::lower, 1);
120        registry.register("TRIM", string::trim, 1);
121        registry.register("CONTAINS", string::contains, 2);
122        registry.register("STARTS_WITH", string::starts_with, 2);
123        registry.register("ENDS_WITH", string::ends_with, 2);
124        registry.register("REPLACE", string::replace, 3);
125        registry.register("REPEAT", string::repeat, 2);
126        registry.register("STRSLICE", string::substr, 3);
127        registry.register("STRLEN", string::strlen, 1);
128        registry.register("INDEXOF", string::index_of, 2);
129        registry.register("CHARAT", string::char_at, 2);
130
131        // Math functions - Basic
132        registry.register("ABS", math::abs, 1);
133        registry.register("FLOOR", math::floor, 1);
134        registry.register("CEIL", math::ceil, 1);
135        registry.register("ROUND", math::round, 1);
136        registry.register("SQRT", math::sqrt, 1);
137        registry.register("POW", math::pow, 2);
138
139        // Math functions - Trigonometry
140        registry.register("SIN", math::sin, 1);
141        registry.register("COS", math::cos, 1);
142        registry.register("TAN", math::tan, 1);
143        registry.register("ASIN", math::asin, 1);
144        registry.register("ACOS", math::acos, 1);
145        registry.register("ATAN", math::atan, 1);
146        registry.register("ATAN2", math::atan2, 2);
147        registry.register("SINH", math::sinh, 1);
148        registry.register("COSH", math::cosh, 1);
149        registry.register("TANH", math::tanh, 1);
150
151        // Math functions - Logarithms & Exponentials
152        registry.register("LOG", math::log, 1);
153        registry.register("LN", math::ln, 1);
154        registry.register("LOG2", math::log2, 1);
155        registry.register("EXP", math::exp, 1);
156        registry.register("EXP2", math::exp2, 1);
157        registry.register("EXPM1", math::expm1, 1);
158        registry.register("LOG1P", math::log1p, 1);
159
160        // Math functions - Special
161        registry.register("FACTORIAL", math::factorial, 1);
162        registry.register("GAMMA", math::gamma, 1);
163        registry.register("ERF", math::erf, 1);
164        registry.register("HYPOT", math::hypot, 2);
165        registry.register("SIGN", math::sign, 1);
166        registry.register("CLAMP", math::clamp, 3);
167
168        // Math functions - Statistics
169        registry.register("MEAN", math::mean, 1);
170        registry.register("MEDIAN", math::median, 1);
171        registry.register("VARIANCE", math::variance, 1);
172        registry.register("STD", math::std, 1);
173        registry.register("QUANTILE", math::quantile, 2);
174
175        // Math functions - Vector Operations
176        registry.register("DOT", math::dot, 2);
177        registry.register("NORM", math::norm, 1);
178        registry.register("CROSS", math::cross, 2);
179        registry.register("DISTANCE", math::distance, 2);
180        registry.register("NORMALIZE", math::normalize, 1);
181
182        // Math functions - Matrix Operations
183        registry.register("MATMUL", math::matmul, 2);
184        registry.register("TRANSPOSE", math::transpose, 1);
185        registry.register("DETERMINANT", math::determinant, 1);
186        registry.register("INVERSE", math::matrix_inverse, 1);
187
188        // Math functions - Statistics & Regression
189        registry.register("LINEAR_REGRESSION", math::linear_regression, 2);
190
191        // Math functions - Probability Distributions
192        registry.register("NORMAL_PDF", math::normal_pdf, 1); // Variadic: 1 or 3
193        registry.register("NORMAL_CDF", math::normal_cdf, 1); // Variadic: 1 or 3
194        registry.register("POISSON_PMF", math::poisson_pmf, 2);
195
196        // Math constants
197        registry.register("PI", math::pi, 0);
198        registry.register("E", math::e, 0);
199        registry.register("TAU", math::tau, 0);
200        registry.register("PHI", math::phi, 0);
201
202        // Precision arithmetic functions
203        registry.register("ROUND_TO", math::round_to, 2);
204        registry.register("ADD_WITH_PRECISION", math::add_with_precision, 3);
205        registry.register("SUB_WITH_PRECISION", math::sub_with_precision, 3);
206        registry.register("MUL_WITH_PRECISION", math::mul_with_precision, 3);
207        registry.register("DIV_WITH_PRECISION", math::div_with_precision, 3);
208        registry.register("SET_PRECISION", math::set_precision, 2);
209
210        // Precise (Fraction) arithmetic functions
211        registry.register("TO_FRACTION", precise::to_fraction, 1);
212        registry.register("TO_FLOAT", precise::to_float, 1);
213        registry.register("SIMPLIFY", precise::simplify, 1);
214        registry.register("FRAC_ADD", precise::frac_add, 2);
215        registry.register("FRAC_SUB", precise::frac_sub, 2);
216        registry.register("FRAC_MUL", precise::frac_mul, 2);
217        registry.register("FRAC_DIV", precise::frac_div, 2);
218        registry.register("NUMERATOR", precise::numerator, 1);
219        registry.register("DENOMINATOR", precise::denominator, 1);
220        registry.register("GCD", precise::gcd, 2);
221        registry.register("LCM", precise::lcm, 2);
222
223        // Type functions
224        registry.register("TYPE", types::type_of, 1);
225        registry.register("TO_STRING", types::to_string, 1);
226        registry.register("TO_NUMBER", types::to_number, 1);
227        registry.register("CLONE", types::clone, 1);
228
229        // JSON functions
230        registry.register("JSON_PARSE", json::json_parse, 1);
231        registry.register("JSON_STRINGIFY", json::json_stringify, 1); // Variadic: 1-2 args
232
233        // Payroll functions - Basic salary calculations (7个)
234        registry.register("CALC_HOURLY_PAY", payroll::basic::calc_hourly_pay, 2);
235        registry.register("CALC_DAILY_PAY", payroll::basic::calc_daily_pay, 2);
236        registry.register(
237            "CALC_MONTHLY_FROM_HOURLY",
238            payroll::basic::calc_monthly_from_hourly,
239            1,
240        );
241        registry.register("CALC_ANNUAL_SALARY", payroll::basic::calc_annual_salary, 1);
242        registry.register("CALC_BASE_SALARY", payroll::basic::calc_base_salary, 1);
243        registry.register("CALC_GROSS_SALARY", payroll::basic::calc_gross_salary, 2);
244        registry.register("CALC_NET_SALARY", payroll::basic::calc_net_salary, 2);
245
246        // Payroll functions - Overtime pay (5个)
247        registry.register("CALC_OVERTIME_PAY", payroll::overtime::calc_overtime_pay, 2);
248        registry.register(
249            "CALC_WEEKDAY_OVERTIME",
250            payroll::overtime::calc_weekday_overtime,
251            2,
252        );
253        registry.register(
254            "CALC_WEEKEND_OVERTIME",
255            payroll::overtime::calc_weekend_overtime,
256            2,
257        );
258        registry.register(
259            "CALC_HOLIDAY_OVERTIME",
260            payroll::overtime::calc_holiday_overtime,
261            2,
262        );
263        registry.register(
264            "CALC_TOTAL_OVERTIME",
265            payroll::overtime::calc_total_overtime,
266            4,
267        );
268
269        // Payroll functions - Personal income tax (6个)
270        registry.register("CALC_PERSONAL_TAX", payroll::tax::calc_personal_tax, 1);
271        registry.register("CALC_TAXABLE_INCOME", payroll::tax::calc_taxable_income, 1);
272        registry.register(
273            "CALC_ANNUAL_BONUS_TAX",
274            payroll::tax::calc_annual_bonus_tax,
275            1,
276        );
277        registry.register(
278            "CALC_EFFECTIVE_TAX_RATE",
279            payroll::tax::calc_effective_tax_rate,
280            2,
281        );
282        registry.register("CALC_GROSS_FROM_NET", payroll::tax::calc_gross_from_net, 1);
283        registry.register("CALC_TAX_REFUND", payroll::tax::calc_tax_refund, 2);
284
285        // Payroll functions - Social insurance (10个)
286        registry.register(
287            "CALC_PENSION_INSURANCE",
288            payroll::insurance::calc_pension_insurance,
289            1,
290        );
291        registry.register(
292            "CALC_MEDICAL_INSURANCE",
293            payroll::insurance::calc_medical_insurance,
294            1,
295        );
296        registry.register(
297            "CALC_UNEMPLOYMENT_INSURANCE",
298            payroll::insurance::calc_unemployment_insurance,
299            1,
300        );
301        registry.register(
302            "CALC_HOUSING_FUND",
303            payroll::insurance::calc_housing_fund,
304            1,
305        );
306        registry.register(
307            "CALC_SOCIAL_INSURANCE",
308            payroll::insurance::calc_social_insurance,
309            1,
310        );
311        registry.register(
312            "ADJUST_SOCIAL_BASE",
313            payroll::insurance::adjust_social_base,
314            3,
315        );
316        registry.register(
317            "CALC_SOCIAL_BASE_LOWER",
318            payroll::insurance::calc_social_base_lower,
319            2,
320        );
321        registry.register(
322            "CALC_SOCIAL_BASE_UPPER",
323            payroll::insurance::calc_social_base_upper,
324            2,
325        );
326        registry.register(
327            "CALC_INJURY_INSURANCE",
328            payroll::insurance::calc_injury_insurance,
329            1,
330        );
331        registry.register(
332            "CALC_MATERNITY_INSURANCE",
333            payroll::insurance::calc_maternity_insurance,
334            1,
335        );
336
337        // Payroll functions - Attendance (7个)
338        registry.register(
339            "CALC_ATTENDANCE_RATE",
340            payroll::attendance::calc_attendance_rate,
341            2,
342        );
343        registry.register(
344            "CALC_LATE_DEDUCTION",
345            payroll::attendance::calc_late_deduction,
346            1,
347        );
348        registry.register(
349            "CALC_EARLY_LEAVE_DEDUCTION",
350            payroll::attendance::calc_early_leave_deduction,
351            1,
352        );
353        registry.register(
354            "CALC_ABSENT_DEDUCTION",
355            payroll::attendance::calc_absent_deduction,
356            2,
357        );
358        registry.register(
359            "CALC_LEAVE_DEDUCTION",
360            payroll::attendance::calc_leave_deduction,
361            2,
362        );
363        registry.register(
364            "CALC_SICK_LEAVE_PAY",
365            payroll::attendance::calc_sick_leave_pay,
366            3,
367        );
368        registry.register(
369            "CALC_UNPAID_LEAVE_DEDUCTION",
370            payroll::attendance::calc_unpaid_leave_deduction,
371            2,
372        );
373
374        // Payroll functions - Bonus (6个)
375        registry.register(
376            "CALC_PERFORMANCE_PAY",
377            payroll::bonus::calc_performance_pay,
378            2,
379        );
380        registry.register("CALC_ANNUAL_BONUS", payroll::bonus::calc_annual_bonus, 1);
381        registry.register(
382            "CALC_ATTENDANCE_BONUS",
383            payroll::bonus::calc_attendance_bonus,
384            2,
385        );
386        registry.register(
387            "CALC_SALES_COMMISSION",
388            payroll::bonus::calc_sales_commission,
389            2,
390        );
391        registry.register("CALC_PROJECT_BONUS", payroll::bonus::calc_project_bonus, 2);
392        registry.register("CALC_13TH_SALARY", payroll::bonus::calc_13th_salary, 2);
393
394        // Payroll functions - Allowance (7个)
395        registry.register(
396            "CALC_MEAL_ALLOWANCE",
397            payroll::allowance::calc_meal_allowance,
398            2,
399        );
400        registry.register(
401            "CALC_TRANSPORT_ALLOWANCE",
402            payroll::allowance::calc_transport_allowance,
403            2,
404        );
405        registry.register(
406            "CALC_COMMUNICATION_ALLOWANCE",
407            payroll::allowance::calc_communication_allowance,
408            2,
409        );
410        registry.register(
411            "CALC_HOUSING_ALLOWANCE",
412            payroll::allowance::calc_housing_allowance,
413            2,
414        );
415        registry.register(
416            "CALC_HIGH_TEMP_ALLOWANCE",
417            payroll::allowance::calc_high_temp_allowance,
418            2,
419        );
420        registry.register(
421            "CALC_NIGHT_SHIFT_ALLOWANCE",
422            payroll::allowance::calc_night_shift_allowance,
423            2,
424        );
425        registry.register(
426            "CALC_POSITION_ALLOWANCE",
427            payroll::allowance::calc_position_allowance,
428            2,
429        );
430
431        // Payroll functions - Conversion (12个)
432        registry.register(
433            "ANNUAL_TO_MONTHLY",
434            payroll::conversion::annual_to_monthly,
435            1,
436        );
437        registry.register(
438            "MONTHLY_TO_ANNUAL",
439            payroll::conversion::monthly_to_annual,
440            1,
441        );
442        registry.register("DAILY_TO_MONTHLY", payroll::conversion::daily_to_monthly, 1);
443        registry.register("MONTHLY_TO_DAILY", payroll::conversion::monthly_to_daily, 1);
444        registry.register(
445            "HOURLY_TO_MONTHLY",
446            payroll::conversion::hourly_to_monthly,
447            1,
448        );
449        registry.register(
450            "MONTHLY_TO_HOURLY",
451            payroll::conversion::monthly_to_hourly,
452            1,
453        );
454        registry.register(
455            "PRORATE_BY_NATURAL_DAYS",
456            payroll::conversion::prorate_by_natural_days,
457            3,
458        );
459        registry.register(
460            "PRORATE_BY_LEGAL_DAYS",
461            payroll::conversion::prorate_by_legal_days,
462            2,
463        );
464        registry.register(
465            "PRORATE_BY_WORKDAYS",
466            payroll::conversion::prorate_by_workdays,
467            3,
468        );
469        registry.register(
470            "CALC_ONBOARDING_SALARY",
471            payroll::conversion::calc_onboarding_salary,
472            4,
473        );
474        registry.register(
475            "CALC_RESIGNATION_SALARY",
476            payroll::conversion::calc_resignation_salary,
477            4,
478        );
479        registry.register("CALC_14TH_SALARY", payroll::conversion::calc_14th_salary, 2);
480
481        // Payroll functions - DateTime (12个)
482        registry.register("CALC_NATURAL_DAYS", payroll::datetime::calc_natural_days, 2);
483        registry.register(
484            "GET_LEGAL_PAY_DAYS",
485            payroll::datetime::get_legal_pay_days,
486            0,
487        );
488        registry.register("CALC_WORKDAYS", payroll::datetime::calc_workdays, 2);
489        registry.register("CALC_WEEKEND_DAYS", payroll::datetime::calc_weekend_days, 2);
490        registry.register("CALC_HOLIDAY_DAYS", payroll::datetime::calc_holiday_days, 1);
491        registry.register("IS_WORKDAY", payroll::datetime::is_workday, 2);
492        registry.register("IS_WEEKEND", payroll::datetime::is_weekend, 1);
493        registry.register("IS_HOLIDAY", payroll::datetime::is_holiday, 2);
494        registry.register("CALC_WORK_HOURS", payroll::datetime::calc_work_hours, 1);
495        registry.register(
496            "CALC_MONTHLY_WORK_HOURS",
497            payroll::datetime::calc_monthly_work_hours,
498            0,
499        );
500        registry.register(
501            "CALC_ANNUAL_WORKDAYS",
502            payroll::datetime::calc_annual_workdays,
503            0,
504        );
505        registry.register(
506            "CALC_ANNUAL_PAY_DAYS",
507            payroll::datetime::calc_annual_pay_days,
508            0,
509        );
510
511        // Payroll functions - Statistics (6个)
512        registry.register(
513            "CALC_SALARY_AVERAGE",
514            payroll::statistics::calc_salary_average,
515            1,
516        );
517        registry.register(
518            "CALC_SALARY_MEDIAN",
519            payroll::statistics::calc_salary_median,
520            1,
521        );
522        registry.register(
523            "CALC_SALARY_RANGE",
524            payroll::statistics::calc_salary_range,
525            1,
526        );
527        registry.register("CALC_PERCENTILE", payroll::statistics::calc_percentile, 2);
528        registry.register(
529            "CALC_SALARY_STD_DEV",
530            payroll::statistics::calc_salary_std_dev,
531            1,
532        );
533        registry.register(
534            "CALC_SALARY_DISTRIBUTION",
535            payroll::statistics::calc_salary_distribution,
536            2,
537        );
538
539        // Filesystem functions (根据权限注册)
540        if permissions.filesystem_enabled {
541            registry.register("READ_FILE", filesystem::read_file, 1);
542            registry.register("WRITE_FILE", filesystem::write_file, 2);
543            registry.register("APPEND_FILE", filesystem::append_file, 2);
544            registry.register("DELETE_FILE", filesystem::delete_file, 1);
545            registry.register("FILE_EXISTS", filesystem::file_exists, 1);
546            registry.register("LIST_DIR", filesystem::list_dir, 1);
547            registry.register("CREATE_DIR", filesystem::create_dir, 1);
548        }
549
550        // Network functions (根据权限注册)
551        if permissions.network_enabled {
552            registry.register("HTTP_GET", network::http_get, 1);
553            registry.register("HTTP_POST", network::http_post, 2); // Variadic: 2-3 args
554            registry.register("HTTP_PUT", network::http_put, 2); // Variadic: 2-3 args
555            registry.register("HTTP_DELETE", network::http_delete, 1);
556        }
557
558        // Report functions - Data formatting (always enabled)
559        registry.register("FORMAT_NUMBER", report::format_number, 1); // Variadic: 1-3 args
560        registry.register("FORMAT_CURRENCY", report::format_currency, 1); // Variadic: 1-3 args
561        registry.register("FORMAT_PERCENT", report::format_percent, 1); // Variadic: 1-2 args
562        registry.register("FORMAT_DATE", report::format_date, 1); // Variadic: 1-2 args
563
564        // Report functions - Excel operations (根据权限注册)
565        if permissions.filesystem_enabled {
566            registry.register("EXCEL_CREATE", report::excel_create, 0);
567            registry.register("EXCEL_WRITE_CELL", report::excel_write_cell, 5);
568            registry.register("EXCEL_WRITE_ROW", report::excel_write_row, 4);
569            registry.register("EXCEL_WRITE_COLUMN", report::excel_write_column, 4);
570            registry.register("EXCEL_WRITE_TABLE", report::excel_write_table, 5);
571            registry.register("EXCEL_SAVE", report::excel_save, 2);
572            registry.register("EXCEL_READ_SHEET", report::excel_read_sheet, 2);
573            registry.register("EXCEL_READ_CELL", report::excel_read_cell, 4);
574            registry.register("EXCEL_READ_RANGE", report::excel_read_range, 6);
575            registry.register("EXCEL_GET_SHEETS", report::excel_get_sheets, 1);
576        }
577
578        registry
579    }
580
581    /// Register a built-in function
582    fn register(&mut self, name: &str, func: BuiltInFn, arity: usize) {
583        self.functions.insert(name.to_string(), (func, arity));
584    }
585
586    /// 注册带文档的函数
587    #[allow(dead_code)]
588    fn register_with_doc(&mut self, name: &str, func: BuiltInFn, arity: usize, doc: FunctionDoc) {
589        self.functions.insert(name.to_string(), (func, arity));
590        self.docs.insert(name.to_string(), doc);
591    }
592
593    /// Get a built-in function by name
594    pub fn get(&self, name: &str) -> Option<(BuiltInFn, usize)> {
595        self.functions.get(name).copied()
596    }
597
598    /// Check if a function exists
599    pub fn has(&self, name: &str) -> bool {
600        self.functions.contains_key(name)
601    }
602
603    /// Get all function names
604    pub fn names(&self) -> Vec<String> {
605        self.functions.keys().cloned().collect()
606    }
607
608    /// 获取函数文档
609    pub fn get_doc(&self, name: &str) -> Option<&FunctionDoc> {
610        self.docs.get(name)
611    }
612
613    /// 获取所有文档
614    pub fn all_docs(&self) -> &HashMap<String, FunctionDoc> {
615        &self.docs
616    }
617}
618
619impl Default for BuiltInRegistry {
620    fn default() -> Self {
621        Self::new()
622    }
623}