xqpath 1.4.3

A high-performance jq-inspired path extractor and updater for structured data in Rust with advanced debugging, configuration management and interactive debugging capabilities
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
# XQPath v1.3 用户自定义函数实现计划

**文档类型**: 设计计划
**创建日期**: 2024-07-27
**负责人**: XQPath 开发团队
**状态**: 规划中
**优先级**: 高(v1.3 首要功能)

## 🎯 概述

将用户自定义函数作为 v1.3 的**首要功能**优先开发,为后续的变量系统和模块系统奠定基础。

## 📋 详细实现计划

### Week 1: AST 设计和基础架构

#### 1.1 扩展 PathExpression 枚举

```rust
// src/parser/expression.rs
#[derive(Debug, Clone, PartialEq)]
pub enum PathExpression {
    // ...existing variants...
    FunctionDefinition {
        name: String,
        parameters: Vec<String>,
        body: Box<PathExpression>,
    },
    FunctionCall {
        name: String,
        arguments: Vec<PathExpression>,
    },
}
```

#### 1.2 函数注册表扩展

```rust
// src/functions/user_defined.rs
use std::collections::HashMap;

#[derive(Debug, Clone)]
pub struct UserDefinedFunction {
    pub name: String,
    pub parameters: Vec<String>,
    pub body: PathExpression,
}

#[derive(Debug, Default)]
pub struct UserFunctionRegistry {
    functions: HashMap<String, UserDefinedFunction>,
}

impl UserFunctionRegistry {
    pub fn register(&mut self, func: UserDefinedFunction) -> Result<(), String> {
        if self.functions.contains_key(&func.name) {
            return Err(format!("Function '{}' already defined", func.name));
        }
        self.functions.insert(func.name.clone(), func);
        Ok(())
    }

    pub fn get(&self, name: &str) -> Option<&UserDefinedFunction> {
        self.functions.get(name)
    }

    pub fn list_functions(&self) -> Vec<&str> {
        self.functions.keys().map(|s| s.as_str()).collect()
    }
}
```

#### 1.3 求值器上下文扩展

```rust
// src/evaluator.rs
#[derive(Debug, Default)]
pub struct EvaluationContext {
    pub user_functions: UserFunctionRegistry,
    pub call_stack: Vec<String>, // 用于递归检测
    pub max_recursion_depth: usize,
}

impl EvaluationContext {
    pub fn new() -> Self {
        Self {
            user_functions: UserFunctionRegistry::default(),
            call_stack: Vec::new(),
            max_recursion_depth: 1000, // 默认最大递归深度
        }
    }
}
```

### Week 2: 解析器实现

#### 2.1 函数定义解析

```rust
// src/parser/expression.rs
impl ExpressionParser {
    fn parse_function_definition(&mut self) -> Result<PathExpression, ParseError> {
        // 解析 "def function_name(param1; param2): body;"
        self.expect_keyword("def")?;

        let name = self.parse_identifier()?;

        // 解析参数列表
        self.expect_char('(')?;
        let mut parameters = Vec::new();

        while !self.check_char(')') {
            parameters.push(self.parse_identifier()?);
            if self.check_char(';') {
                self.advance(); // 消费 ';'
            } else if !self.check_char(')') {
                return Err(ParseError::Expected("';' or ')'".to_string()));
            }
        }

        self.expect_char(')')?;
        self.expect_char(':')?;

        // 解析函数体
        let body = Box::new(self.parse_pipe_expression()?);

        self.expect_char(';')?;

        Ok(PathExpression::FunctionDefinition {
            name,
            parameters,
            body,
        })
    }

    fn parse_function_call(&mut self, name: String) -> Result<PathExpression, ParseError> {
        // 解析 "function_name(arg1; arg2)"
        self.expect_char('(')?;
        let mut arguments = Vec::new();

        while !self.check_char(')') {
            arguments.push(self.parse_pipe_expression()?);
            if self.check_char(';') {
                self.advance();
            } else if !self.check_char(')') {
                return Err(ParseError::Expected("';' or ')'".to_string()));
            }
        }

        self.expect_char(')')?;

        Ok(PathExpression::FunctionCall { name, arguments })
    }
}
```

#### 2.2 集成到主解析流程

```rust
impl ExpressionParser {
    fn parse_primary_expression(&mut self) -> Result<PathExpression, ParseError> {
        // ... existing code ...

        // 检查是否是函数定义
        if self.check_keyword("def") {
            return self.parse_function_definition();
        }

        // 检查是否是标识符(可能是函数调用)
        if let Some(identifier) = self.try_parse_identifier() {
            if self.check_char('(') {
                // 函数调用
                return self.parse_function_call(identifier);
            } else {
                // 其他标识符处理
                return Err(ParseError::UnexpectedIdentifier(identifier));
            }
        }

        // ... existing code ...
    }
}
```

### Week 3: 求值器实现

#### 3.1 函数定义求值

```rust
// src/evaluator.rs
impl ExpressionEvaluator {
    fn evaluate_function_definition(
        &self,
        name: &str,
        parameters: &[String],
        body: &PathExpression,
        context: &mut EvaluationContext,
        _input: &Value,
    ) -> Result<Vec<Value>, EvaluationError> {
        // 注册函数到上下文
        let user_func = UserDefinedFunction {
            name: name.to_string(),
            parameters: parameters.to_vec(),
            body: body.clone(),
        };

        context.user_functions.register(user_func)
            .map_err(|e| EvaluationError::FunctionDefinitionError(e))?;

        // 函数定义本身不产生输出
        Ok(vec![])
    }

    fn evaluate_function_call(
        &self,
        name: &str,
        arguments: &[PathExpression],
        context: &mut EvaluationContext,
        input: &Value,
    ) -> Result<Vec<Value>, EvaluationError> {
        // 递归深度检查
        if context.call_stack.len() >= context.max_recursion_depth {
            return Err(EvaluationError::RecursionLimitExceeded(
                context.max_recursion_depth
            ));
        }

        // 查找函数定义
        let func = context.user_functions.get(name)
            .ok_or_else(|| EvaluationError::UndefinedFunction(name.to_string()))?
            .clone();

        // 参数数量检查
        if arguments.len() != func.parameters.len() {
            return Err(EvaluationError::ArgumentCountMismatch {
                expected: func.parameters.len(),
                actual: arguments.len(),
            });
        }

        // 求值参数
        let mut arg_values = Vec::new();
        for arg in arguments {
            let values = self.evaluate_expression(arg, context, input)?;
            // 简化:每个参数取第一个值
            arg_values.push(values.into_iter().next().unwrap_or(Value::Null));
        }

        // 创建函数调用上下文
        context.call_stack.push(name.to_string());

        // TODO: 实现参数绑定到局部作用域
        // 现在先简单实现:将参数替换到函数体中
        let result = self.evaluate_expression(&func.body, context, input);

        // 恢复调用栈
        context.call_stack.pop();

        result
    }
}
```

#### 3.2 错误类型扩展

```rust
// src/evaluator.rs
#[derive(Debug, thiserror::Error)]
pub enum EvaluationError {
    // ... existing variants ...

    #[error("Function definition error: {0}")]
    FunctionDefinitionError(String),

    #[error("Undefined function: {0}")]
    UndefinedFunction(String),

    #[error("Argument count mismatch: expected {expected}, got {actual}")]
    ArgumentCountMismatch { expected: usize, actual: usize },

    #[error("Recursion limit exceeded: {0}")]
    RecursionLimitExceeded(usize),
}
```

### Week 4: 测试和优化

#### 4.1 基础功能测试

```rust
// tests/user_defined_functions.rs
use xqpath::{parse_path_expression, evaluate_path_expression_with_context, EvaluationContext};
use serde_json::json;

#[test]
fn test_simple_function_definition_and_call() {
    let expr = parse_path_expression("
        def double(x): x * 2;
        5 | double(.)
    ").expect("Failed to parse expression");

    let mut context = EvaluationContext::new();
    let data = json!(null);
    let result = evaluate_path_expression_with_context(&expr, &mut context, &data)
        .expect("Failed to evaluate expression");

    assert_eq!(result, vec![json!(10)]);
}

#[test]
fn test_recursive_function() {
    let expr = parse_path_expression("
        def factorial: if . <= 1 then 1 else . * ((. - 1) | factorial) end;
        5 | factorial
    ").expect("Failed to parse expression");

    let mut context = EvaluationContext::new();
    let data = json!(null);
    let result = evaluate_path_expression_with_context(&expr, &mut context, &data)
        .expect("Failed to evaluate expression");

    assert_eq!(result, vec![json!(120)]);
}

#[test]
fn test_multiple_parameter_function() {
    let expr = parse_path_expression("
        def add(a; b): a + b;
        add(3; 7)
    ").expect("Failed to parse expression");

    let mut context = EvaluationContext::new();
    let data = json!(null);
    let result = evaluate_path_expression_with_context(&expr, &mut context, &data)
        .expect("Failed to evaluate expression");

    assert_eq!(result, vec![json!(10)]);
}
```

#### 4.2 性能测试

```rust
// benches/user_functions_performance.rs
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use xqpath::{parse_path_expression, evaluate_path_expression_with_context, EvaluationContext};
use serde_json::json;

fn benchmark_simple_function_call(c: &mut Criterion) {
    let expr = parse_path_expression("
        def double(x): x * 2;
        . | double(.)
    ").expect("Failed to parse expression");

    let mut context = EvaluationContext::new();
    let data = json!(42);

    c.bench_function("simple_function_call", |b| {
        b.iter(|| {
            let mut ctx = context.clone();
            evaluate_path_expression_with_context(
                black_box(&expr),
                black_box(&mut ctx),
                black_box(&data)
            )
        })
    });
}
```

#### 4.3 示例程序

```rust
// examples/user_defined_functions_demo.rs
use xqpath::{parse_path_expression, evaluate_path_expression_with_context, EvaluationContext};
use serde_json::json;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("🔧 XQPath v1.3 用户自定义函数演示");
    println!("=" .repeat(50));

    // 示例 1: 简单函数定义和调用
    demo_simple_functions()?;

    // 示例 2: 递归函数
    demo_recursive_functions()?;

    // 示例 3: 数据处理函数
    demo_data_processing_functions()?;

    Ok(())
}

fn demo_simple_functions() -> Result<(), Box<dyn std::error::Error>> {
    println!("\n📋 1. 简单函数定义和调用");
    println!("-" .repeat(30));

    let expr = parse_path_expression("
        def double(x): x * 2;
        def add(a; b): a + b;
        def greet(name): \"Hello, \" + name + \"!\";

        [
            5 | double(.),
            add(3; 7),
            \"World\" | greet(.)
        ]
    ")?;

    let mut context = EvaluationContext::new();
    let data = json!(null);
    let result = evaluate_path_expression_with_context(&expr, &mut context, &data)?;

    println!("表达式: 定义多个简单函数并调用");
    println!("结果: {}", serde_json::to_string_pretty(&result[0])?);

    Ok(())
}

fn demo_recursive_functions() -> Result<(), Box<dyn std::error::Error>> {
    println!("\n🔄 2. 递归函数");
    println!("-" .repeat(20));

    let expr = parse_path_expression("
        # 阶乘函数
        def factorial: if . <= 1 then 1 else . * ((. - 1) | factorial) end;

        # 斐波那契函数
        def fibonacci:
            if . <= 1 then .
            else ((. - 1) | fibonacci) + ((. - 2) | fibonacci)
            end;

        # 计算多个值
        {
            factorial_5: 5 | factorial,
            factorial_7: 7 | factorial,
            fibonacci_8: 8 | fibonacci,
            fibonacci_10: 10 | fibonacci
        }
    ")?;

    let mut context = EvaluationContext::new();
    let data = json!(null);
    let result = evaluate_path_expression_with_context(&expr, &mut context, &data)?;

    println!("表达式: 递归计算阶乘和斐波那契数列");
    println!("结果: {}", serde_json::to_string_pretty(&result[0])?);

    Ok(())
}
```

## 🎯 预期成果

完成这 4 周的开发后,XQPath 将支持:

### ✅ 核心功能

- **函数定义**: `def function_name(param1; param2): body;`
- **函数调用**: `function_name(arg1; arg2)`
- **递归支持**: 自动递归深度管理和栈溢出保护
- **多参数**: 支持任意数量的函数参数
- **错误处理**: 完善的函数相关错误报告

### ✅ 高级特性

- **尾递归优化**: 优化尾递归调用的性能
- **函数重载**: 支持相同名称不同参数数量的函数
- **高阶函数**: 函数作为参数传递(基础版本)
- **性能优化**: 函数调用的性能优化

### ✅ 质量保证

- **完整测试**: 单元测试、集成测试、性能测试
- **文档完善**: API 文档、用户指南、示例程序
- **错误处理**: 友好的错误信息和调试支持

## 🚀 后续计划

用户自定义函数完成后,将为后续功能奠定坚实基础:

1. **变量系统**: 函数参数绑定机制可扩展为通用变量系统
2. **模块系统**: 函数定义可以模块化组织和导入
3. **作用域管理**: 函数作用域是通用作用域管理的基础

这种优先开发顺序将确保 XQPath v1.3 能够更快地为用户提供强大的函数式编程能力!

## 📝 相关文档

- [RFC-004: 用户自定义函数系统]../rfcs/RFC-004-user-defined-functions.md
- [v1.3 开发路线图]../planning/roadmap-v1.3.md