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

vec_filter

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

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日

1474Rust 模式

每月下载量 44 次

Apache-2.0

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 不大于或等于 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且兴趣包含"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