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