use crate::Builder;
macro_rules! scalar_filters {
($( $(#[$meta:meta])* $name:ident => $operator:literal; )*) => {
impl Builder {
$(
$(#[$meta])*
pub fn $name<T, U>(mut self, column: T, filter: U) -> Self
where
T: AsRef<str>,
U: AsRef<str>,
{
self.append_query(column.as_ref().to_owned(), format!(concat!($operator, ".{}"), filter.as_ref()));
self
}
)*
}
};
}
scalar_filters! {
eq => "eq";
neq => "neq";
gt => "gt";
gte => "gte";
lt => "lt";
lte => "lte";
like => "like";
ilike => "ilike";
is => "is";
cs => "cs";
}
macro_rules! owned_column_filters {
($( $(#[$meta:meta])* $name:ident => $operator:literal; )*) => {
impl Builder {
$(
$(#[$meta])*
pub fn $name<T, U>(mut self, column: T, filter: U) -> Self
where
T: Into<String>,
U: AsRef<str>,
{
self.append_query(column.into(), format!(concat!($operator, ".{}"), filter.as_ref()));
self
}
)*
}
};
}
owned_column_filters! {
cd => "cd";
ov => "ov";
}
macro_rules! range_filters {
($( $(#[$meta:meta])* $name:ident => $operator:literal; )*) => {
impl Builder {
$(
$(#[$meta])*
pub fn $name<T>(mut self, column: T, range: (i64, i64)) -> Self
where
T: Into<String>,
{
self.append_query(column.into(), format!(concat!($operator, ".({},{})"), range.0, range.1));
self
}
)*
}
};
}
range_filters! {
sl => "sl";
sr => "sr";
nxl => "nxl";
nxr => "nxr";
adj => "adj";
}
macro_rules! text_filters {
($( $(#[$meta:meta])* $name:ident => $operator:literal; )*) => {
impl Builder {
$(
$(#[$meta])*
pub fn $name<T, U>(mut self, column: T, tsquery: U, config: Option<&str>) -> Self
where
T: Into<String>,
U: AsRef<str>,
{
let value = match config {
Some(config) => format!(concat!($operator, "({}).{}"), config, tsquery.as_ref()),
None => format!(concat!($operator, ".{}"), tsquery.as_ref()),
};
self.append_query(column.into(), value);
self
}
)*
}
};
}
text_filters! {
/// Uses `to_tsquery`; query and optional configuration remain caller grammar.
fts => "fts";
/// Uses `plainto_tsquery`; query and optional configuration remain caller grammar.
plfts => "plfts";
/// Uses `phraseto_tsquery`; query and optional configuration remain caller grammar.
phfts => "phfts";
/// Uses `websearch_to_tsquery`; query and optional configuration remain caller grammar.
wfts => "wfts";
}
impl Builder {
/// Negates a raw operator and filter without changing their grammar.
pub fn not<T, U, V>(mut self, operator: T, column: U, filter: V) -> Self
where
T: AsRef<str>,
U: AsRef<str>,
V: AsRef<str>,
{
self.append_query(
column.as_ref().to_owned(),
format!("not.{}.{}", operator.as_ref(), filter.as_ref()),
);
self
}
/// Conjoins raw filter grammar, adding only the outer parentheses.
/// Quote reserved characters within the grammar yourself; do not URL-encode it.
pub fn and<T: AsRef<str>>(mut self, filters: T) -> Self {
self.append_query("and", format!("({})", filters.as_ref()));
self
}
/// Disjoins raw filter grammar, adding only the outer parentheses.
/// Quote reserved characters within the grammar yourself; do not URL-encode it.
pub fn or<T: AsRef<str>>(mut self, filters: T) -> Self {
self.append_query("or", format!("({})", filters.as_ref()));
self
}
/// Matches a list of raw `PostgREST` grammar fragments.
///
/// Elements are comma-separated without escaping or additional quoting.
/// For example, `["\"Paris,France\"", "null"]` retains the quoted first
pub fn in_<T, U, V>(mut self, column: T, values: U) -> Self
where
T: AsRef<str>,
U: IntoIterator<Item = V>,
V: AsRef<str>,
{
let mut filter = String::from("in.(");
for (index, value) in values.into_iter().enumerate() {
if index != 0 {
filter.push(',');
}
filter.push_str(value.as_ref());
}
filter.push(')');
self.append_query(column.as_ref().to_owned(), filter);
self
}
pub fn in_values<T, U, V>(mut self, column: T, values: U) -> Self
where
T: AsRef<str>,
U: IntoIterator<Item = V>,
V: AsRef<str>,
{
let mut filter = String::from("in.(");
for (index, value) in values.into_iter().enumerate() {
if index != 0 {
filter.push(',');
}
filter.push('"');
for character in value.as_ref().chars() {
if matches!(character, '"' | '\\') {
filter.push('\\');
}
filter.push(character);
}
filter.push('"');
}
filter.push(')');
self.append_query(column.as_ref().to_owned(), filter);
self
}
}