4 个版本
0.2.2 | 2023年3月27日 |
---|---|
0.2.1 | 2023年3月22日 |
0.2.0 | 2023年3月22日 |
0.1.0 | 2023年3月22日 |
1474 在 Rust 模式
每月下载量 44 次
33KB
695 行
Vec Filter
Vec Filter 是一个 Rust 库,用于根据查询字符串过滤结构体向量。它允许您使用简单的查询语法指定对结构体字段的过滤条件。该库提供了一个自定义 derive 宏 Filterable
,以轻松使您的结构体可过滤。
目录
安装
将以下内容添加到您的 Cargo.toml
[dependencies]
vec_filter = "0.1.0"
使用
派生 Filterable
要使您的结构体可过滤,派生 Filterable
特性
use vec_filter::Filterable;
#[derive(Debug, Clone, Filterable)]
struct Person {
name: String,
age: u32,
}
查询语法
本节描述了库可以解析的字符串查询格式。字符串查询由一系列表示操作、值和逻辑连接词的表达式组成。可以使用括号组合表达式以创建更复杂的查询。
操作
==
: 等于!=
: 不等于>
: 大于>=
: 大于等于<
: 小于<=
: 小于等于contains
: 包含子字符串startswith
: 以子字符串开头endswith
: 以子字符串结尾regexmatch
: 匹配正则表达式模式in
: 检查值是否在值列表中
值
值可以是以下类型
- 字符串:用双引号括起来,例如
"hello"
- 整数:一系列数字,例如
42
- 字符串列表:用方括号括起来,用逗号分隔,例如
["apple", "banana", "cherry"]
- 整数列表:用方括号括起来,用逗号分隔,例如
[1, 2, 3]
逻辑连接符
&&
:逻辑与||
:逻辑或!
:逻辑非(与括号一起使用)
示例
(field1 == "value1")
:field1 等于 "value1"(field1 != "value1") && (field2 > 42)
:field1 不等于 "value1" 且 field2 大于 42(field1 contains "substr") || (field2 < 10)
:field1 包含子串 "substr" 或 field2 小于 10!(field1 >= 100)
:field1 不大于或等于 100field1 in ["apple", "banana"]
:field1 要么是 "apple",要么是 "banana"((field1 == "value1") || (field1 == "value2")) && (field2 <= 20)
:field1 要么是 "value1",要么是 "value2",且 field2 小于或等于 20
括号
为了设置操作的优先级,请使用括号。括号内的表达式将先被评估。如果您想分组条件,可以使用括号创建更复杂的查询。
例如
((age >= 25) && (interests in ["hiking"])) || (name == "Alice")
:此查询将匹配年龄大于或等于 25 且兴趣包含 "hiking",或名称等于 "Alice" 的项。(name == "Alice") || ((age < 30) && (interests in ["cooking"]))
:此查询将匹配名称等于"Alice",或年龄小于30且兴趣包含"cooking"的项目。
通过使用括号,您可以将多个条件组合在一起,以不同的优先级级别构建复杂的查询,以实现精确过滤。
注意
- 元素之间可以有空格,但不是必需的。
- 字段名称必须是有效的Rust标识符。
- 解析器区分大小写;字段名称和字符串值必须完全匹配大小写。
示例
让我们看看如何使用Vec Filter过滤Person结构体的向量。
use vec_filter::{Filterable, AST};
use vec_filter::Value;
#[derive(Debug, Clone, PartialEq, Filterable)]
struct Person {
name: String,
age: u32,
}
fn main() {
let people = vec![
Person { name: "Alice".to_string(), age: 30 },
Person { name: "Bob".to_string(), age: 40 },
Person { name: "Charlie".to_string(), age: 50 },
];
let ast = AST::And(
Box::new(AST::Equals {
field: "name",
value: Value::String("Alice".to_string()),
}),
Box::new(AST::NotEquals {
field: "age",
value: Value::Int(30),
}),
);
let filtered_people = ast.apply(&people);
println!("{:?}", filtered_people); // []
}
在这个例子中,我们想要找到所有名字为"Alice"且年龄不等于30的人。查询使用AST值表示。然后调用apply
方法,并打印过滤后的结果。
许可证
本项目采用Apache 2.0许可证。
依赖关系
约7.5MB
约131K SLoC