15 个版本

0.4.4 2024年4月4日
0.4.2 2023年10月25日
0.4.0-alpha.32023年7月12日

#173 in 解析器实现

Download history 742/week @ 2024-04-22 160/week @ 2024-04-29 218/week @ 2024-05-06 390/week @ 2024-05-13 304/week @ 2024-05-20 310/week @ 2024-05-27 490/week @ 2024-06-03 619/week @ 2024-06-10 763/week @ 2024-06-17 774/week @ 2024-06-24 693/week @ 2024-07-01 370/week @ 2024-07-08 914/week @ 2024-07-15 741/week @ 2024-07-22 445/week @ 2024-07-29 504/week @ 2024-08-05

2,604 每月下载

Apache-2.0

65KB
1.5K SLoC

SiKuLa

CI GitHub release (latest SemVer) crates.io docs.rs

Simple Query Language - [ˈziːˈkuːˈlaː]

原理

又一个查询语言,你认真吗?

实际上它并不算新颖。但是将其命名为“类似GitHub搜索语法的查询语言”(QLSTGHSS)并不是一个真正的选择。

更准确地说,它更像是一个熟悉语法的实现。

那么区别在哪里呢?

它们很微妙。但我不想破坏惊喜。或者也许我只是太懒于编写文档。🤷

示例

假设你定义了一个用于搜索电子邮件的枚举类型

use sikula::prelude::*;

#[derive(Search, Clone, Debug, PartialEq, Eq)]
enum DeriveResource<'a> {
    /// Standard qualifier: `author:someone`
    #[search(sort, scope)]
    Author(&'a str),
    /// Default primary: `warranty`
    #[search(default)]
    Subject(Primary<'a>),
    /// Non-default primary: `warranty in:message`, to search in both: `warranty in:message in:subject`
    #[search(scope)]
    Message(Primary<'a>),

    /// Predicate: `is:read`
    Read,

    /// Numeric qualifier example:
    /// * `size:100` (equals)
    /// * `size:>=100` (size greater than or equals 100)
    /// * `size:100..200` (size between 100 inclusive and 200 exclusive)
    /// * `size:*..200` (size up to 200 exclusive)
    #[search(sort)]
    Size(Ordered<usize>),

    #[search(sort)]
    Sent(Ordered<time::OffsetDateTime>),

    Label(Qualified<'a, &'a str>),
}

Query derive 提供了特质实现。#[query(scope)] 属性将 Subject 变体标记为 Body 范围的主要搜索词,如果没有选择则将 Subject 作为默认值。

一般来说,有三种类型的词:主要、修饰词、谓词。谓词是简单的“这个条件是否为真”风格的过滤器。如果一个枚举变体没有值,它就是一个谓词。

修饰词是额外的匹配条件,这取决于值的类型。

使用 #[query(sort)] 标志,字段可以用于对结果进行排序。

现在,你可以执行以下查询

查询 检索所有条目…
foo … 包含“foo”在“主题”中
fooin:subjectin:message … 包含“foo”在“主题”或“正文”中
fooin:subjectin:message is:read … 包含“foo”在“主题”或“正文”中且被“读取”
foo bar … 包含“foo”和“bar”在主题中
size:>10000 … 大于10000
size:100..200 … 在100(包含)和200(不包含)之间
-is:read … 为“未读取”
foo sort:sent … 包含“foo”在主题中,按“sent”升序排序
foo-排序:sent … 包含“foo”在主题中,按“sent”降序排序
发件人:"Max Mustermann" … 具有发件人为 Max Mustermann
发件人:"Max Mustermann"发件人:"Eva Mustermann" … 具有发件人为 Max MustermannEva Mustermann(很可能会找不到结果)
发件人:"Max Mustermann","Eva Mustermann" … 具有发件人为 Max MustermannEva Mustermann
foobar … 主题中包含“foo”或“bar”
foobar … 主题中包含“foo”和“bar”
foobarbaz … 主题中包含“foo”或(“bar”和“baz”)
(foobar) baz … 主题中包含(“foo”或“bar”)和“baz”
foobar baz … 主题中包含(“foo”或“bar”)和“baz”

为了测试上面的资源,你可以运行 cli 示例

cargo run --example cli --features time -- -is:read AND foo

这将为您提供解析查询的结构化输出

Input: '-is:read AND foo'
Query {
    terms: And(
        [
            Not(
                Match(
                    Read,
                ),
            ),
            Match(
                Subject(
                    Partial(
                        "foo",
                    ),
                ),
            ),
        ],
    ),
    sorting: [],
}

依赖项

~11MB
~191K SLoC