3个版本
0.1.2 | 2023年3月27日 |
---|---|
0.1.1 | 2023年3月22日 |
0.1.0 | 2023年3月22日 |
#63 in #query-string
13KB
128 行
Vec Filter
Vec Filter是一个Rust库,可以根据查询字符串过滤结构体向量。它允许您使用简单的查询语法在结构体字段上指定过滤条件。该库提供自定义衍生宏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 不大于等于 100}field1 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且兴趣包含“烹饪”的项。
通过使用括号,您可以构建复杂的查询,结合多个条件,以不同的优先级级别实现精确过滤。
注意
- 元素之间允许有空间,但不是必需的。
- 字段名称必须是有效的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方法对people向量进行调用,并打印过滤后的结果。
许可
本项目采用Apache 2.0许可证。
依赖关系
约1.5MB
约35K SLoC