1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
use std::fmt::{Display, Formatter, Result}; use crate::query::Comparison; #[derive(Clone, Debug)] enum Operator { AND, OR, } impl Display for Operator { fn fmt(&self, f: &mut Formatter<'_>) -> Result { write!( f, "{}", match self { Self::AND => "&&", Self::OR => "||", } ) } } /// Allows to filter a query according to different [`Comparison`]. /// as an AQL string with the [`to_aql`] method. /// /// [`to_aql`]: struct.Filter.html#method.to_aql /// [`Comparison`]: struct.Comparison.html #[derive(Clone, Debug)] pub struct Filter { comparisons: Vec<Comparison>, operators: Vec<Operator>, } impl Filter { /// Instantiates a new query filter from a comparison item /// /// # Example /// /// ```rust /// # use aragog::query::{Comparison, Filter}; /// let filter = Filter::new(Comparison::field("age").greater_than(10)); /// ``` pub fn new(comparison: Comparison) -> Self { Self { comparisons: vec![comparison], operators: vec![], } } /// Appends the filter current condition(s) with a new one with a `AND` logic. /// /// # Example /// /// ```rust /// # use aragog::query::{Comparison, Filter}; /// let mut filter = Filter::new(Comparison::field("age").greater_than(10)); /// filter = filter.and(Comparison::field("username").in_str_array(&["felix", "felixm"])); /// ``` /// pub fn and(mut self, comparison: Comparison) -> Self { self.comparisons.push(comparison); self.operators.push(Operator::AND); self } /// Appends the filter current condition(s) with a new one with a `OR` logic. /// /// # Example /// /// ```rust /// # use aragog::query::{Comparison, Filter}; /// let mut filter = Filter::new(Comparison::field("age").greater_than(10)); /// filter = filter.or(Comparison::field("username").in_str_array(&["felix", "felixm"])); /// ``` /// pub fn or(mut self, comparison: Comparison) -> Self { self.comparisons.push(comparison); self.operators.push(Operator::OR); self } /// Renders the AQL string corresponding to the current `Filter`. The query will go out of scope. /// /// # Example /// /// ```rust /// # use aragog::query::{Comparison, Filter}; /// let mut filter = Filter::new(Comparison::field("age").greater_than(10)). /// or(Comparison::field("username").in_str_array(&["felix", "felixm"])); /// assert_eq!(filter.to_aql("i"), String::from(r#"i.age > 10 || i.username IN ["felix", "felixm"]"#)); /// ``` pub fn to_aql(&self, collection_id: &str) -> String { let mut res = String::new(); for (i, comparison) in self.comparisons.iter().enumerate() { let operator_str = if i >= self.operators.len() { String::new() } else { format!(" {}", self.operators[i].to_string()) }; res = format!( "{} {}{}", res, comparison.to_aql(collection_id), operator_str ) } String::from(res.trim_start()) } }