1#[derive(Clone, Debug, Eq, PartialEq)]
2pub struct QueryAst {
3 pub raw: String,
4}
5
6#[derive(Clone, Debug, Eq, PartialEq)]
7pub struct CompiledQuery {
8 pub match_expression: String,
9}
10
11#[must_use]
12pub fn compile_text_query(raw: impl Into<String>) -> CompiledQuery {
13 let raw = raw.into();
14 let normalized = raw.split_whitespace().filter(|token| !token.is_empty()).collect::<Vec<_>>();
15 let match_expression = normalized
16 .into_iter()
17 .map(|token| format!("\"{}\"", token.replace('"', "\"\"")))
18 .collect::<Vec<_>>()
19 .join(" AND ");
20
21 CompiledQuery { match_expression }
22}
23
24#[cfg(test)]
25mod tests {
26 use super::compile_text_query;
27
28 #[test]
29 fn normalizes_whitespace() {
30 let compiled = compile_text_query("alpha beta");
31 assert_eq!(compiled.match_expression, "\"alpha\" AND \"beta\"");
32 }
33
34 #[test]
35 fn escapes_double_quotes_in_tokens() {
36 let compiled = compile_text_query("alpha \"beta");
37 assert_eq!(compiled.match_expression, "\"alpha\" AND \"\"\"beta\"");
38 }
39}