1use super::Query;
9use super::types::{QueryGenericLang, QuerySearchLimit, QuerySearchOffset};
10use crate::config::{ConfigNormalization, ConfigTokenization};
11use crate::lexer::{TokenLexerBuilder, TokenLexerMode};
12use crate::store::StoreItemBuilder;
13
14impl<'a> Query<'a> {
15 #[allow(clippy::too_many_arguments)] pub fn search(
17 query_id: &'a str,
18 collection: &'a str,
19 bucket: &'a str,
20 terms: &'a str,
21 limit: QuerySearchLimit,
22 offset: QuerySearchOffset,
23 lang: Option<QueryGenericLang>,
24 normalization_config: ConfigNormalization,
25 tokenization_config: ConfigTokenization,
26 ) -> Result<Self, ()> {
27 match (
28 StoreItemBuilder::from_depth_2(collection, bucket),
29 TokenLexerBuilder::from(
30 TokenLexerMode::from_query_lang(&lang),
31 lang.and_then(QueryGenericLang::into_lang_opt),
32 terms,
33 normalization_config,
34 tokenization_config,
35 ),
36 ) {
37 (Ok(store), Ok(text_lexed)) => {
38 Ok(Query::Search(store, query_id, text_lexed, limit, offset))
39 }
40 _ => Err(()),
41 }
42 }
43
44 pub fn suggest(
45 query_id: &'a str,
46 collection: &'a str,
47 bucket: &'a str,
48 terms: &'a str,
49 limit: QuerySearchLimit,
50 normalization_config: ConfigNormalization,
51 tokenization_config: ConfigTokenization,
52 ) -> Result<Self, ()> {
53 match (
54 StoreItemBuilder::from_depth_2(collection, bucket),
55 TokenLexerBuilder::from(
56 TokenLexerMode::NormalizeOnly,
57 None,
58 terms,
59 normalization_config,
60 tokenization_config,
61 ),
62 ) {
63 (Ok(store), Ok(text_lexed)) => Ok(Query::Suggest(store, query_id, text_lexed, limit)),
64 _ => Err(()),
65 }
66 }
67
68 pub fn list(
69 query_id: &'a str,
70 collection: &'a str,
71 bucket: &'a str,
72 limit: QuerySearchLimit,
73 offset: QuerySearchOffset,
74 ) -> Result<Self, ()> {
75 match StoreItemBuilder::from_depth_2(collection, bucket) {
76 Ok(store) => Ok(Query::List(store, query_id, limit, offset)),
77 _ => Err(()),
78 }
79 }
80
81 pub fn push(
82 collection: &'a str,
83 bucket: &'a str,
84 object: &'a str,
85 text: &'a str,
86 lang: Option<QueryGenericLang>,
87 normalization_config: ConfigNormalization,
88 tokenization_config: ConfigTokenization,
89 ) -> Result<Self, ()> {
90 match (
91 StoreItemBuilder::from_depth_3(collection, bucket, object),
92 TokenLexerBuilder::from(
93 TokenLexerMode::from_query_lang(&lang),
94 lang.and_then(QueryGenericLang::into_lang_opt),
95 text,
96 normalization_config,
97 tokenization_config,
98 ),
99 ) {
100 (Ok(store), Ok(text_lexed)) => Ok(Query::Push(store, text_lexed)),
101 _ => Err(()),
102 }
103 }
104
105 pub fn pop(
106 collection: &'a str,
107 bucket: &'a str,
108 object: &'a str,
109 text: &'a str,
110 normalization_config: ConfigNormalization,
111 tokenization_config: ConfigTokenization,
112 ) -> Result<Self, ()> {
113 match (
114 StoreItemBuilder::from_depth_3(collection, bucket, object),
115 TokenLexerBuilder::from(
116 TokenLexerMode::NormalizeOnly,
117 None,
118 text,
119 normalization_config,
120 tokenization_config,
121 ),
122 ) {
123 (Ok(store), Ok(text_lexed)) => Ok(Query::Pop(store, text_lexed)),
124 _ => Err(()),
125 }
126 }
127
128 pub fn count(
129 collection: &'a str,
130 bucket: Option<&'a str>,
131 object: Option<&'a str>,
132 ) -> Result<Self, ()> {
133 let store_result = match (bucket, object) {
134 (Some(bucket_inner), Some(object_inner)) => {
135 StoreItemBuilder::from_depth_3(collection, bucket_inner, object_inner)
136 }
137 (Some(bucket_inner), None) => StoreItemBuilder::from_depth_2(collection, bucket_inner),
138 _ => StoreItemBuilder::from_depth_1(collection),
139 };
140
141 match store_result {
142 Ok(store) => Ok(Query::Count(store)),
143 _ => Err(()),
144 }
145 }
146
147 pub fn flushc(collection: &'a str) -> Result<Self, ()> {
148 match StoreItemBuilder::from_depth_1(collection) {
149 Ok(store) => Ok(Query::FlushC(store)),
150 _ => Err(()),
151 }
152 }
153
154 pub fn flushb(collection: &'a str, bucket: &'a str) -> Result<Self, ()> {
155 match StoreItemBuilder::from_depth_2(collection, bucket) {
156 Ok(store) => Ok(Query::FlushB(store)),
157 _ => Err(()),
158 }
159 }
160
161 pub fn flusho(collection: &'a str, bucket: &'a str, object: &'a str) -> Result<Self, ()> {
162 match StoreItemBuilder::from_depth_3(collection, bucket, object) {
163 Ok(store) => Ok(Query::FlushO(store)),
164 _ => Err(()),
165 }
166 }
167}
168
169#[cfg(test)]
170mod tests {
171 use super::*;
172
173 const NORMALIZATION_CONFIG: ConfigNormalization = ConfigNormalization {
174 diacritic_folding_enabled: false,
175 stemming_enabled: false,
176 };
177 const TOKENIZATION_CONFIG: ConfigTokenization = ConfigTokenization {
178 detect_special_patterns: true,
179 compat_split_special_patterns: false,
180 };
181
182 #[test]
183 fn it_builds_search_query() {
184 #[rustfmt::skip]
185 assert!(Query::search(
186 "id1", "c:test:1", "b:test:1", "Michael Dake", 10, 20, None,
187 NORMALIZATION_CONFIG, TOKENIZATION_CONFIG,
188 ).is_ok());
189
190 #[rustfmt::skip]
191 assert!(Query::search(
192 "id2", "c:test:1", "", "Michael Dake", 1, 0, None,
193 NORMALIZATION_CONFIG, TOKENIZATION_CONFIG,
194 ).is_err());
195 }
196
197 #[test]
198 fn it_builds_suggest_query() {
199 #[rustfmt::skip]
200 assert!(Query::suggest(
201 "id1", "c:test:2", "b:test:2", "Micha", 5,
202 NORMALIZATION_CONFIG, TOKENIZATION_CONFIG,
203 ).is_ok());
204
205 #[rustfmt::skip]
206 assert!(Query::suggest(
207 "id2", "c:test:2", "", "Micha", 1,
208 NORMALIZATION_CONFIG, TOKENIZATION_CONFIG,
209 ).is_err());
210 }
211
212 #[test]
213 fn it_builds_list_query() {
214 assert!(Query::list("id1", "c:test:2", "b:test:2", 100, 0).is_ok());
215 assert!(Query::list("id2", "c:test:2", "", 10, 0).is_err());
216 }
217
218 #[test]
219 fn it_builds_push_query() {
220 #[rustfmt::skip]
221 assert!(Query::push(
222 "c:test:3", "b:test:3", "o:test:3", "My name is Michael Dake. I'm ordering in the US.", None,
223 NORMALIZATION_CONFIG, TOKENIZATION_CONFIG,
224 ).is_ok());
225
226 #[rustfmt::skip]
227 assert!(Query::push(
228 "c:test:3", "", "o:test:3", "My name is Michael Dake.", None,
229 NORMALIZATION_CONFIG, TOKENIZATION_CONFIG,
230 ).is_err());
231 }
232
233 #[test]
234 fn it_builds_pop_query() {
235 #[rustfmt::skip]
236 assert!(Query::pop(
237 "c:test:4", "b:test:4", "o:test:4", "ordering US",
238 NORMALIZATION_CONFIG, TOKENIZATION_CONFIG,
239 ).is_ok());
240
241 #[rustfmt::skip]
242 assert!(Query::pop(
243 "c:test:4", "", "o:test:4", "ordering US",
244 NORMALIZATION_CONFIG, TOKENIZATION_CONFIG,
245 ).is_err());
246 }
247
248 #[test]
249 fn it_builds_count_query() {
250 assert!(Query::count("c:test:5", None, None).is_ok());
251 assert!(Query::count("c:test:5", Some("b:test:5"), None).is_ok());
252 assert!(Query::count("c:test:5", Some("b:test:5"), Some("o:test:5")).is_ok());
253 assert!(Query::count("c:test:5", Some(""), Some("o:test:5")).is_err());
254 }
255
256 #[test]
257 fn it_builds_flushc_query() {
258 assert!(Query::flushc("c:test:6").is_ok());
259 assert!(Query::flushc("").is_err());
260 }
261
262 #[test]
263 fn it_builds_flushb_query() {
264 assert!(Query::flushb("c:test:7", "b:test:7").is_ok());
265 assert!(Query::flushb("c:test:7", "").is_err());
266 }
267
268 #[test]
269 fn it_builds_flusho_query() {
270 assert!(Query::flusho("c:test:8", "b:test:8", "o:test:8").is_ok());
271 assert!(Query::flusho("c:test:8", "b:test:8", "").is_err());
272 }
273}