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