#filter #vec #ast #query-string #struct-fields #macro-derive

vec_filter_derive

Vec Filter是一个Rust库,可以根据查询字符串过滤结构体向量。它允许您使用简单的查询语法在结构体字段上指定过滤条件。该库提供自定义衍生宏Filterable,以轻松使您的结构体可过滤。

3个版本

0.1.2 2023年3月27日
0.1.1 2023年3月22日
0.1.0 2023年3月22日

#63 in #query-string


用于vec_filter

Apache-2.0

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