XQPath
A jq-inspired expression parser and evaluator for structured data in Rust
🎯 项目概述
XQPath 是一个用于结构化数据(JSON/YAML/TOML/CSV)路径提取与更新的高性能 Rust 工具,提供 jq 风格的表达式语法:
🧩 双重形态
- 命令行工具:
xqpathCLI - 快速处理文件和管道数据 - 集成库:
xqpathcrate - 嵌入到 Rust 项目中
✨ 核心特性
| 功能 | 描述 | 状态 |
|---|---|---|
| 路径提取 | 支持 .field、[index]、** 等 jq 风格路径 |
✅ |
| 管道操作 | expr1 | expr2 管道操作符(v1.1 新增) |
✅ |
| 逗号操作 | expr1, expr2 多选择操作符(v1.1 新增) |
✅ |
| 字面量 | "string", 42, true, null 支持 |
✅ |
| 恒等表达式 | . 恒等操作,返回输入值(v1.1 新增) |
✅ |
| 格式支持 | JSON/YAML 自动检测与解析 | ✅ |
| 通配符 | *、** 支持字段和递归匹配 |
✅ |
| 类型断言 | 如 .users[] | string 类型过滤 |
✅ |
| 字段更新 | 使用 feature = "update" 启用更新功能 |
⚙️ |
| 格式扩展 | 插件式支持 TOML、XML 等格式 | ⚡️ |
| 高测试性 | 全模块单元测试,覆盖边界情况 | 🧪 |
| 轻量依赖 | 最小依赖集(serde + winnow) | 📦 |
🆕 v1.1 新特性
表达式语法支持
XQPath v1.1 引入了 jq 风格的表达式语法,支持:
- 管道操作符
|:expr1 | expr2将左表达式的结果传递给右表达式 - 逗号操作符
,:expr1, expr2收集多个表达式的所有结果 - 括号表达式:
(expr)改变操作优先级 - 字面量值:支持字符串、数字、布尔值和 null
- 恒等表达式:
.返回输入值本身
语法示例
use ;
use json;
let data = json!;
// 管道操作:获取第一个用户的名字
let expr = parse_path_expression?;
let result = evaluate_path_expression?;
// 结果: ["Alice"]
// 逗号操作:获取所有用户名和年龄
let expr = parse_path_expression?;
let result = evaluate_path_expression?;
// 结果: ["Alice", "Bob", 30, 25]
// 复杂表达式:混合使用管道和逗号
let expr = parse_path_expression?;
let result = evaluate_path_expression?;
// 结果: ["Alice", "Bob", "summary"]
📦 项目架构
xqpath/
├── Cargo.toml # 项目配置
├── src/
│ ├── lib.rs # 库入口,导出所有公共 API
│ ├── macros.rs # 便利宏定义
│ ├── extractor.rs # 路径提取核心逻辑
│ ├── updater.rs # 路径更新逻辑(feature = "update")
│ ├── parser/
│ │ ├── path.rs # 路径段解析(winnow 实现)
│ │ └── expression.rs # 表达式解析与求值(v1.1 新增)
│ ├── value/
│ │ ├── format.rs # ValueFormat trait 抽象
│ │ ├── json.rs # JSON 格式支持
│ │ └── yaml.rs # YAML 格式支持
│ └── cli.rs # CLI 工具入口
└── tests/
└── integration.rs # 集成测试
🔧 核心模块设计
1. 路径解析器(parser::path)
使用 winnow 实现高性能路径解析,支持:
支持的路径语法:
.field- 字段访问[index]- 数组索引访问*- 通配符匹配任意字段名**- 递归字段匹配| type- 类型过滤(可选)
2. 数据格式抽象(value::format)
统一接口设计,支持格式插件化扩展:
内置实现:
JsonFormat- 基于serde_json::ValueYamlFormat- 基于serde_yaml::Value
3. 字段提取器(extractor.rs)
核心提取逻辑,支持:
功能特性:
- 路径逐级匹配(Field, Index)
- 递归遍历(
**) - 通配符字段选择(
*) - 类型断言过滤(如
| string)
4. 字段更新器(updater.rs)
⚠️ Feature Gate: 需启用
feature = "update"
提供路径指定位置的更新功能:
更新能力:
- 设置字段值
- 创建缺失路径
- 通配符批量更新(如
.users[*].role = "admin")
⚙️ Feature 配置
在 Cargo.toml 中配置功能特性:
[]
= []
= [] # 启用字段更新功能
🖥️ CLI 工具使用
基本命令
# 提取字段
# 更新字段(需编译时启用 --features update)
参数说明
| 参数 | 长参数 | 说明 |
|---|---|---|
-f |
--file |
输入文件路径,省略时从 stdin 读取 |
-p |
--path |
提取路径表达式(jq 风格语法) |
-v |
--value |
要写入的新值(仅 set 命令使用) |
📚 使用示例
输入数据 (example.yaml)
spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.25
- name: redis
image: redis:7.0
提取操作
# 提取单个值
# 使用通配符提取多个值
# 递归查找所有 image 字段
🔌 格式扩展机制
通过 ValueFormat trait 和注册表机制支持新格式扩展:
// 示例:注册 TOML 格式支持
xqpath.register_format;
🧪 测试策略
测试覆盖范围
| 测试类型 | 测试内容 | 状态 |
|---|---|---|
| 单元测试 | PathParser、Extractor、Updater 模块独立测试 | ✅ |
| 集成测试 | CLI 输入输出、stdin 处理、文件编码等 | ✅ |
| 边界测试 | 空数组、null 值、混合类型结构处理 | ✅ |
| 错误测试 | 路径不存在、索引越界、类型不匹配等 | ✅ |
运行测试
# 运行所有测试
# 运行特定模块测试
# 带更新功能的测试
🔍 格式自动检测
为了提供更好的用户体验,XQPath 实现了智能格式检测:
📁 库模块组织
更新后的 lib.rs 结构:
// 重新导出便利接口
pub use *;
pub use extract;
pub use update;
🚀 快速开始
作为库使用
在 Cargo.toml 中添加依赖:
[]
= "0.1.0"
# 如需更新功能
= { = "0.1.0", = ["update"] }
编译 CLI 工具
# 基本版本
# 包含更新功能
🤝 贡献指南
- Fork 项目
- 创建特性分支 (
git checkout -b feature/amazing-feature) - 提交更改 (
git commit -m 'Add amazing feature') - 推送到分支 (
git push origin feature/amazing-feature) - 打开 Pull Request
📄 许可证
本项目采用 MIT 或 Apache-2.0 双重许可证。详见 LICENSE 文件。
🔗 相关资源
设计理念: XQPath 致力于提供简单、高效、可扩展的结构化数据处理体验,无论是在命令行环境还是 Rust 应用程序中。
🔄 向后兼容性
XQPath v1.1 完全向后兼容 v1.0 的 API 和语法:
- 现有代码无需修改:所有 v1.0 的路径语法(如
.field[0].*)继续工作 - API 保持不变:现有的
extract()函数和宏继续可用 - 自动语法检测:库会自动检测是使用传统路径语法还是新的表达式语法
- 渐进式升级:您可以在现有项目中逐步采用新的表达式功能
迁移指南
// v1.0 语法(继续支持)
let result = datapath_get!;
// v1.1 新语法(可选升级)
let expr = parse_path_expression?;
let result = evaluate_path_expression?;