1use crate::{enums::StringBounds, utils::{strs_to_negative_string_bounds, strs_to_string_bounds}, BoundsPosition, CaseMatchMode};
2
3#[derive(Debug, Clone)]
5pub struct BoundsBuilder<'a> {
6 string_bounds: Vec<StringBounds<'a>>,
7}
8
9impl<'a> BoundsBuilder<'a> {
10 pub fn new() -> Self {
11 BoundsBuilder {
12 string_bounds: Vec::new()
13 }
14 }
15
16 pub fn as_vec(&self) -> Vec<StringBounds<'a>> {
18 self.string_bounds.clone()
19 }
20
21 fn starts_with(&mut self, pattern: &'a str, is_positive: bool, case_insensitive: bool) -> Self {
23 self.string_bounds.push(StringBounds::StartsWith(pattern, is_positive, CaseMatchMode::insensitive(case_insensitive)));
24 self.to_owned()
25 }
26
27 pub fn starts_with_ci(&mut self, pattern: &'a str, is_positive: bool) -> Self {
29 self.starts_with(pattern, is_positive, true)
30 }
31
32 pub fn starts_with_ci_alphanum(&mut self, pattern: &'a str, is_positive: bool) -> Self {
34 self.string_bounds.push(StringBounds::StartsWith(pattern, is_positive, CaseMatchMode::AlphanumInsensitive));
35 self.to_owned()
36 }
37
38 pub fn starts_with_cs(&mut self, pattern: &'a str, is_positive: bool) -> Self {
40 self.starts_with(pattern, is_positive, false)
41 }
42
43 pub fn starting_with(&mut self, pattern: &'a str, case_insensitive: bool) -> Self {
45 self.starts_with(pattern, true, case_insensitive)
46 }
47
48 pub fn starting_with_ci(&mut self, pattern: &'a str) -> Self {
50 self.starting_with(pattern, true)
51 }
52
53 pub fn starting_with_ci_alphanum(&mut self, pattern: &'a str) -> Self {
55 self.starts_with_ci_alphanum(pattern, true)
56 }
57
58 pub fn starting_with_cs(&mut self, pattern: &'a str) -> Self {
60 self.starting_with(pattern, false)
61 }
62
63 pub fn not_starting_with(&mut self, pattern: &'a str, case_insensitive: bool) -> Self {
65 self.starts_with(pattern, false, case_insensitive)
66 }
67
68 pub fn not_starting_with_ci(&mut self, pattern: &'a str) -> Self {
70 self.not_starting_with(pattern, true)
71 }
72
73 pub fn not_starting_with_ci_alphanum(&mut self, pattern: &'a str) -> Self {
75 self.starts_with_ci_alphanum(pattern, false)
76 }
77
78 pub fn not_starting_with_cs(&mut self, pattern: &'a str) -> Self {
80 self.not_starting_with(pattern, false)
81 }
82
83 pub fn contains(&mut self, pattern: &'a str, is_positive: bool, case_insensitive: bool) -> Self {
85 let cm = if case_insensitive {
86 CaseMatchMode::Insensitive
87 } else {
88 CaseMatchMode::Sensitive
89 };
90 self.string_bounds.push(StringBounds::Contains(pattern, is_positive, cm));
91 self.to_owned()
92 }
93
94 pub fn contains_ci_alphanum(&mut self, pattern: &'a str, is_positive: bool) -> Self {
96 self.string_bounds.push(StringBounds::Contains(pattern, is_positive, CaseMatchMode::AlphanumInsensitive));
97 self.to_owned()
98 }
99
100 pub fn contains_ci(&mut self, pattern: &'a str, is_positive: bool) -> Self {
102 self.contains(pattern, is_positive, true)
103 }
104
105 pub fn contains_cs(&mut self, pattern: &'a str, is_positive: bool) -> Self {
107 self.contains(pattern, is_positive, false)
108 }
109
110 pub fn containing(&mut self, pattern: &'a str, case_insensitive: bool) -> Self {
112 self.contains(pattern, true, case_insensitive)
113 }
114
115 pub fn containing_ci(&mut self, pattern: &'a str) -> Self {
117 self.containing(pattern, true)
118 }
119
120 pub fn containing_ci_alphanum(&mut self, pattern: &'a str) -> Self {
122 self.contains_ci_alphanum(pattern, true)
123 }
124
125 pub fn containing_cs(&mut self, pattern: &'a str) -> Self {
127 self.containing(pattern, false)
128 }
129
130 pub fn not_containing(&mut self, pattern: &'a str, case_insensitive: bool) -> Self {
132 self.contains(pattern, false, case_insensitive)
133 }
134
135 pub fn not_containing_ci(&mut self, pattern: &'a str) -> Self {
137 self.not_containing(pattern, true)
138 }
139
140 pub fn not_containing_ci_alphanum(&mut self, pattern: &'a str) -> Self {
142 self.contains_ci_alphanum(pattern, false)
143 }
144
145 pub fn not_containing_cs(&mut self, pattern: &'a str) -> Self {
147 self.not_containing(pattern, false)
148 }
149
150 fn ends_with(&mut self, pattern: &'a str, is_positive: bool, case_insensitive: bool) -> Self {
152 let cm = if case_insensitive {
153 CaseMatchMode::Insensitive
154 } else {
155 CaseMatchMode::Sensitive
156 };
157 self.string_bounds.push(StringBounds::EndsWith(pattern, is_positive, cm));
158 self.to_owned()
159 }
160
161 pub fn ends_with_ci(&mut self, pattern: &'a str, is_positive: bool) -> Self {
163 self.ends_with(pattern, is_positive, true)
164 }
165
166 pub fn ends_with_ci_alphanum(&mut self, pattern: &'a str, is_positive: bool) -> Self {
168 self.string_bounds.push(StringBounds::EndsWith(pattern, is_positive, CaseMatchMode::AlphanumInsensitive));
169 self.to_owned()
170 }
171
172 pub fn ends_with_cs(&mut self, pattern: &'a str, is_positive: bool) -> Self {
174 self.ends_with(pattern, is_positive, false)
175 }
176
177 pub fn ending_with(&mut self, pattern: &'a str, case_insensitive: bool) -> Self {
179 self.ends_with(pattern, true, case_insensitive)
180 }
181
182 pub fn ending_with_ci(&mut self, pattern: &'a str) -> Self {
184 self.ending_with(pattern, true)
185 }
186
187 pub fn ending_with_ci_alphanum(&mut self, pattern: &'a str) -> Self {
189 self.ends_with_ci_alphanum(pattern, true)
190 }
191
192 pub fn ending_with_cs(&mut self, pattern: &'a str) -> Self {
194 self.ending_with(pattern, false)
195 }
196
197 pub fn not_ending_with(&mut self, pattern: &'a str, case_insensitive: bool) -> Self {
199 self.ends_with(pattern, false, case_insensitive)
200 }
201
202 pub fn not_ending_with_ci(&mut self, pattern: &'a str) -> Self {
204 self.not_ending_with(pattern, true)
205 }
206
207 pub fn not_ending_with_ci_alphanum(&mut self, pattern: &'a str) -> Self {
209 self.ends_with_ci_alphanum(pattern, false)
210 }
211
212 pub fn not_ending_with_cs(&mut self, pattern: &'a str) -> Self {
214 self.not_ending_with(pattern, false)
215 }
216
217 pub fn matches_whole(&mut self, pattern: &'a str, is_positive: bool, case_insensitive: bool) -> Self {
219 let cm = if case_insensitive {
220 CaseMatchMode::Insensitive
221 } else {
222 CaseMatchMode::Sensitive
223 };
224 self.string_bounds.push(StringBounds::Whole(pattern, is_positive, cm));
225 self.to_owned()
226 }
227
228 pub fn matches_whole_ci(&mut self, pattern: &'a str, is_positive: bool) -> Self {
230 self.matches_whole(pattern, is_positive, true)
231 }
232
233 pub fn matches_whole_cs(&mut self, pattern: &'a str, is_positive: bool) -> Self {
235 self.matches_whole(pattern, is_positive, false)
236 }
237
238 pub fn is(&mut self, pattern: &'a str, case_insensitive: bool) -> Self {
239 self.matches_whole(pattern, true, case_insensitive)
240 }
241
242 pub fn is_ci(&mut self, pattern: &'a str) -> Self {
243 self.matches_whole(pattern, true, true)
244 }
245
246 pub fn is_not(&mut self, pattern: &'a str, case_insensitive: bool) -> Self {
247 self.matches_whole(pattern, false, case_insensitive)
248 }
249
250 pub fn is_not_ci(&mut self, pattern: &'a str) -> Self {
251 self.matches_whole(pattern, false, true)
252 }
253
254 pub fn is_not_cs(&mut self, pattern: &'a str) -> Self {
255 self.matches_whole(pattern, false, false)
256 }
257
258 pub fn and(&mut self, rules: BoundsBuilder<'a>) -> Self {
261 self.string_bounds.push(StringBounds::And(rules.as_vec()));
262 self.to_owned()
263 }
264
265 pub fn or(&mut self, rules: BoundsBuilder<'a>) -> Self {
268 self.string_bounds.push(StringBounds::Or(rules.as_vec()));
269 self.to_owned()
270 }
271
272 pub fn or_true(&mut self, patterns: &'a [&str], case_mode: CaseMatchMode, position: BoundsPosition) -> Self {
275 let bounds: Vec<StringBounds<'a>> = strs_to_string_bounds(patterns, case_mode, position);
276 self.string_bounds.push(StringBounds::Or(bounds));
277 self.to_owned()
278 }
279
280 pub fn or_starts_with(&mut self, patterns: &'a [&str], case_mode: CaseMatchMode) -> Self {
281 self.or_true(patterns, case_mode, BoundsPosition::Starts);
282 self.to_owned()
283 }
284
285 pub fn or_starting_with_ci(&mut self, patterns: &'a [&str]) -> Self {
286 self.or_starts_with(patterns, CaseMatchMode::Insensitive);
287 self.to_owned()
288 }
289
290 pub fn or_starting_with_cs(&mut self, patterns: &'a [&str]) -> Self {
291 self.or_starts_with(patterns, CaseMatchMode::Sensitive);
292 self.to_owned()
293 }
294
295 pub fn or_starting_with_ci_alphanum(&mut self, patterns: &'a [&str]) -> Self {
296 self.or_starts_with(patterns, CaseMatchMode::AlphanumInsensitive);
297 self.to_owned()
298 }
299
300 pub fn or_contains(&mut self, patterns: &'a [&str], case_mode: CaseMatchMode) -> Self {
301 self.or_true(patterns, case_mode, BoundsPosition::Contains);
302 self.to_owned()
303 }
304
305 pub fn or_containing_ci(&mut self, patterns: &'a [&str]) -> Self {
306 self.or_contains(patterns, CaseMatchMode::Insensitive);
307 self.to_owned()
308 }
309
310 pub fn or_containing_cs(&mut self, patterns: &'a [&str]) -> Self {
311 self.or_contains(patterns, CaseMatchMode::Sensitive);
312 self.to_owned()
313 }
314
315 pub fn or_containing_ci_alphanum(&mut self, patterns: &'a [&str]) -> Self {
316 self.or_contains(patterns, CaseMatchMode::AlphanumInsensitive);
317 self.to_owned()
318 }
319
320 pub fn or_ends_with(&mut self, patterns: &'a [&str], case_mode: CaseMatchMode) -> Self {
321 self.or_true(patterns, case_mode, BoundsPosition::Ends);
322 self.to_owned()
323 }
324
325 pub fn or_ending_with_ci(&mut self, patterns: &'a [&str]) -> Self {
326 self.or_ends_with(patterns, CaseMatchMode::Insensitive);
327 self.to_owned()
328 }
329
330 pub fn or_ending_with_cs(&mut self, patterns: &'a [&str]) -> Self {
331 self.or_ends_with(patterns, CaseMatchMode::Sensitive);
332 self.to_owned()
333 }
334
335 pub fn or_ending_with_ci_alphanum(&mut self, patterns: &'a [&str]) -> Self {
336 self.or_ends_with(patterns, CaseMatchMode::AlphanumInsensitive);
337 self.to_owned()
338 }
339
340 pub fn or_is(&mut self, patterns: &'a [&str], case_mode: CaseMatchMode) -> Self {
341 self.or_true(patterns, case_mode, BoundsPosition::Whole);
342 self.to_owned()
343 }
344
345 pub fn or_is_ci(&mut self, patterns: &'a [&str]) -> Self {
346 self.or_is(patterns, CaseMatchMode::Insensitive);
347 self.to_owned()
348 }
349
350 pub fn or_is_cs(&mut self, patterns: &'a [&str]) -> Self {
351 self.or_is(patterns, CaseMatchMode::Sensitive);
352 self.to_owned()
353 }
354
355 pub fn or_is_ci_alphanum(&mut self, patterns: &'a [&str]) -> Self {
356 self.or_is(patterns, CaseMatchMode::AlphanumInsensitive);
357 self.to_owned()
358 }
359
360 pub fn and_true(&mut self, patterns: &'a [&str], case_mode: CaseMatchMode, position: BoundsPosition) -> Self {
363 let bounds: Vec<StringBounds<'a>> = strs_to_string_bounds(patterns, case_mode, position);
364 self.string_bounds.push(StringBounds::And(bounds));
365 self.to_owned()
366 }
367
368 pub fn and_false(&mut self, patterns: &'a [&str], case_mode: CaseMatchMode, position: BoundsPosition) -> Self {
371 let bounds: Vec<StringBounds<'a>> = strs_to_negative_string_bounds(patterns, case_mode, position);
372 self.string_bounds.push(StringBounds::And(bounds));
373 self.to_owned()
374 }
375
376 pub fn and_starts_with(&mut self, patterns: &'a [&str], case_mode: CaseMatchMode) -> Self {
377 self.and_true(patterns, case_mode, BoundsPosition::Starts);
378 self.to_owned()
379 }
380
381 pub fn and_not_starts_with(&mut self, patterns: &'a [&str], case_mode: CaseMatchMode) -> Self {
382 self.and_false(patterns, case_mode, BoundsPosition::Starts);
383 self.to_owned()
384 }
385
386 pub fn and_starting_with_ci(&mut self, patterns: &'a [&str]) -> Self {
387 self.and_not_starts_with(patterns, CaseMatchMode::Insensitive);
388 self.to_owned()
389 }
390
391 pub fn and_not_starting_with_ci(&mut self, patterns: &'a [&str]) -> Self {
392 self.and_not_starts_with(patterns, CaseMatchMode::Insensitive);
393 self.to_owned()
394 }
395
396 pub fn and_starting_with_cs(&mut self, patterns: &'a [&str]) -> Self {
397 self.and_starts_with(patterns, CaseMatchMode::Sensitive);
398 self.to_owned()
399 }
400
401 pub fn and_not_starting_with_cs(&mut self, patterns: &'a [&str]) -> Self {
402 self.and_not_starts_with(patterns, CaseMatchMode::Sensitive);
403 self.to_owned()
404 }
405
406 pub fn and_starting_with_ci_alphanum(&mut self, patterns: &'a [&str]) -> Self {
407 self.and_starts_with(patterns, CaseMatchMode::AlphanumInsensitive);
408 self.to_owned()
409 }
410
411 pub fn and_not_starting_with_ci_alphanum(&mut self, patterns: &'a [&str]) -> Self {
412 self.and_not_starts_with(patterns, CaseMatchMode::AlphanumInsensitive);
413 self.to_owned()
414 }
415
416 pub fn and_contains(&mut self, patterns: &'a [&str], case_mode: CaseMatchMode) -> Self {
417 self.and_true(patterns, case_mode, BoundsPosition::Contains);
418 self.to_owned()
419 }
420
421 pub fn and_not_contains(&mut self, patterns: &'a [&str], case_mode: CaseMatchMode) -> Self {
422 self.and_false(patterns, case_mode, BoundsPosition::Contains);
423 self.to_owned()
424 }
425
426 pub fn and_containing_ci(&mut self, patterns: &'a [&str]) -> Self {
427 self.and_contains(patterns, CaseMatchMode::Insensitive);
428 self.to_owned()
429 }
430
431 pub fn and_not_containing_ci(&mut self, patterns: &'a [&str]) -> Self {
432 self.and_not_contains(patterns, CaseMatchMode::Insensitive);
433 self.to_owned()
434 }
435
436 pub fn and_containing_cs(&mut self, patterns: &'a [&str]) -> Self {
437 self.and_contains(patterns, CaseMatchMode::Sensitive);
438 self.to_owned()
439 }
440
441 pub fn and_not_containing_cs(&mut self, patterns: &'a [&str]) -> Self {
442 self.and_not_contains(patterns, CaseMatchMode::Sensitive);
443 self.to_owned()
444 }
445
446 pub fn and_containing_ci_alphanum(&mut self, patterns: &'a [&str]) -> Self {
447 self.and_contains(patterns, CaseMatchMode::AlphanumInsensitive);
448 self.to_owned()
449 }
450
451 pub fn and_not_containing_ci_alphanum(&mut self, patterns: &'a [&str]) -> Self {
452 self.and_not_contains(patterns, CaseMatchMode::AlphanumInsensitive);
453 self.to_owned()
454 }
455
456 pub fn and_ends_with(&mut self, patterns: &'a [&str], case_mode: CaseMatchMode) -> Self {
457 self.and_true(patterns, case_mode, BoundsPosition::Ends);
458 self.to_owned()
459 }
460
461 pub fn and_not_ends_with(&mut self, patterns: &'a [&str], case_mode: CaseMatchMode) -> Self {
462 self.and_false(patterns, case_mode, BoundsPosition::Ends);
463 self.to_owned()
464 }
465
466 pub fn and_ending_with_ci(&mut self, patterns: &'a [&str]) -> Self {
467 self.and_ends_with(patterns, CaseMatchMode::Insensitive);
468 self.to_owned()
469 }
470
471 pub fn and_not_ending_with_ci(&mut self, patterns: &'a [&str]) -> Self {
472 self.and_not_ends_with(patterns, CaseMatchMode::Insensitive);
473 self.to_owned()
474 }
475
476 pub fn and_ending_with_cs(&mut self, patterns: &'a [&str]) -> Self {
477 self.and_ends_with(patterns, CaseMatchMode::Sensitive);
478 self.to_owned()
479 }
480
481 pub fn and_not_ending_with_cs(&mut self, patterns: &'a [&str]) -> Self {
482 self.and_not_ends_with(patterns, CaseMatchMode::Sensitive);
483 self.to_owned()
484 }
485
486 pub fn and_ending_with_ci_alphanum(&mut self, patterns: &'a [&str]) -> Self {
487 self.and_ends_with(patterns, CaseMatchMode::AlphanumInsensitive);
488 self.to_owned()
489 }
490
491 pub fn and_not_ending_with_ci_alphanum(&mut self, patterns: &'a [&str]) -> Self {
492 self.and_not_ends_with(patterns, CaseMatchMode::AlphanumInsensitive);
493 self.to_owned()
494 }
495
496 pub fn and_is(&mut self, patterns: &'a [&str], case_mode: CaseMatchMode) -> Self {
497 self.and_true(patterns, case_mode, BoundsPosition::Whole);
498 self.to_owned()
499 }
500
501 pub fn and_is_not(&mut self, patterns: &'a [&str], case_mode: CaseMatchMode) -> Self {
502 self.and_false(patterns, case_mode, BoundsPosition::Whole);
503 self.to_owned()
504 }
505
506 pub fn and_is_ci(&mut self, patterns: &'a [&str]) -> Self {
507 self.and_is(patterns, CaseMatchMode::Insensitive);
508 self.to_owned()
509 }
510
511 pub fn and_is_not_ci(&mut self, patterns: &'a [&str]) -> Self {
512 self.and_is_not(patterns, CaseMatchMode::Insensitive);
513 self.to_owned()
514 }
515
516 pub fn and_is_cs(&mut self, patterns: &'a [&str]) -> Self {
517 self.and_is(patterns, CaseMatchMode::Sensitive);
518 self.to_owned()
519 }
520
521 pub fn and_is_not_cs(&mut self, patterns: &'a [&str]) -> Self {
522 self.and_is_not(patterns, CaseMatchMode::Sensitive);
523 self.to_owned()
524 }
525
526 pub fn and_is_ci_alphanum(&mut self, patterns: &'a [&str]) -> Self {
527 self.and_is(patterns, CaseMatchMode::AlphanumInsensitive);
528 self.to_owned()
529 }
530
531 pub fn and_is_not_ci_alphanum(&mut self, patterns: &'a [&str]) -> Self {
532 self.and_is_not(patterns, CaseMatchMode::AlphanumInsensitive);
533 self.to_owned()
534 }
535
536}
537
538pub fn bounds_builder<'a>() -> BoundsBuilder<'a> {
541 BoundsBuilder::new()
542}