yozefu_lib/search/mod.rs
1//! This module defines the parsing functions of search query.
2//! The grammar of the syntax is the following:
3//!
4//! ```bnf
5//! search-query ::= clause+
6//! clause ::= or-expression | limit-clause | from-clause | order-clause
7//! or-expression ::= And-expression | and-expression 'or' and-expression
8//! and-expression ::= atom | atom 'and' atom
9//! term ::= atom | '!' atom
10//! atom ::= comparison | filter | '(' expression ')'
11//! number-symbol ::= 'offset' | 'partition' | 'size'
12//! string-symbol ::= 'topic' | 'key' | 'timestamp' | 'value'
13//! symbol ::= number-symbol | string-symbol
14//! comparison ::= number-comparison | string-comparison | time-comparison
15//! number-comparison ::= number-symbol number-operator number
16//! string-comparison ::= string-symbol string-operator string
17//! time-comparison ::= 'between' string 'and' string
18//! number-operator ::= '==' | '!=' | '>' | '<' | '>=' | '<='
19//! string-operator ::= 'starts with' | '==' | '!=' | '=~' | 'contains' | 'contain' | 'includes' | 'include'
20//! filter ::= .+ '('filter-parameters')'
21//! filter-parameter ::= string | number
22//! filter-parameters ::= filter-parameter (',' filter-parameter)*
23//! limit-clause ::= 'limit' number
24//! order-clause ::= 'order by' symbol order-keyword
25//! order-keyword ::= 'asc' | 'desc'
26//! from-clause ::= 'from' offset
27//! offset ::= 'beginning' | 'begin' | 'end' | 'end' '-' number | string | number
28//! number ::= [0-9_]+
29//! string ::= '"' [^"]+ '"' | "'" [^']+ "'"
30//! ```
31//! You can use <https://www.bottlecaps.de/rr/ui> to visualize it.
32
33#[cfg(feature = "native")]
34pub mod atom;
35#[cfg(feature = "native")]
36pub mod clause;
37#[cfg(feature = "native")]
38pub mod expression;
39#[cfg(feature = "native")]
40pub mod filter;
41#[cfg(feature = "native")]
42pub mod number;
43#[cfg(feature = "native")]
44pub mod offset;
45#[cfg(feature = "native")]
46pub mod order;
47#[cfg(feature = "native")]
48pub mod search_query;
49#[cfg(feature = "native")]
50pub mod string;
51#[cfg(feature = "native")]
52pub mod symbol;
53#[cfg(feature = "native")]
54pub mod term;
55#[cfg(feature = "native")]
56pub mod timestamp;
57#[cfg(feature = "native")]
58pub mod wsi;
59
60pub mod compare;
61
62#[cfg(feature = "native")]
63pub use order::Order;
64#[cfg(feature = "native")]
65pub use order::OrderBy;
66#[cfg(feature = "native")]
67pub use search_query::SearchQuery;
68#[cfg(feature = "native")]
69pub use search_query::parse_search_query;
70use serde::Deserialize;
71use serde::Serialize;
72
73#[cfg(test)]
74pub mod expression_test;
75#[cfg(test)]
76pub mod filter_test;
77#[cfg(test)]
78pub mod number_test;
79#[cfg(test)]
80pub mod offset_test;
81
82/// Result of a search filter evaluation.
83#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
84#[cfg_attr(test, derive(schemars::JsonSchema))]
85pub struct FilterResult {
86 /// `true` if the kafka record matched the search filter condition, `false` otherwise.
87 pub r#match: bool,
88}
89
90impl FilterResult {
91 pub fn new(r#match: bool) -> Self {
92 Self { r#match }
93 }
94}
95
96impl From<bool> for FilterResult {
97 fn from(r#match: bool) -> Self {
98 Self { r#match }
99 }
100}
101
102#[test]
103fn generate_json_schema_filter_result() {
104 use schemars::schema_for;
105 let mut schema = schema_for!(FilterResult);
106 schema.insert("$id".into(), "https://raw.githubusercontent.com/MAIF/yozefu/refs/heads/main/docs/json-schemas/filter-result.json".into());
107 std::fs::write(
108 std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
109 .parent()
110 .unwrap()
111 .parent()
112 .unwrap()
113 .join("docs")
114 .join("json-schemas")
115 .join("filter-result.json"),
116 serde_json::to_string_pretty(&schema).unwrap(),
117 )
118 .unwrap();
119}