use super::Filter;
#[derive(Debug)]
pub(crate) struct RelationFilter<I> {
pub(crate) contains: Option<I>,
}
impl<I> Default for RelationFilter<I> {
fn default() -> Self {
Self { contains: None }
}
}
impl<I> Clone for RelationFilter<I>
where
I: Clone,
{
fn clone(&self) -> Self {
Self {
contains: self.contains.clone(),
}
}
}
impl<I: Send + Sync + Clone> Filter for RelationFilter<I> {
type Primitive = I;
type Primitives = Vec<I>;
fn match_operator(
_name: &'static str,
_op: &'static str,
_registry: &mut async_graphql::registry::Registry,
) -> Option<async_graphql::registry::MetaInputValue>
where
Self::Primitive: async_graphql::InputType,
Self::Primitives: async_graphql::InputType + IntoIterator<Item = Self::Primitive>,
{
unreachable!("RelationFilter::match_operator")
}
fn parse<T: async_graphql::InputType>(
_field_name: &'static str,
_obj: &async_graphql::indexmap::IndexMap<async_graphql::Name, async_graphql::Value>,
) -> Result<Option<Self>, async_graphql::InputValueError<T>>
where
Self::Primitive: async_graphql::InputType,
Self::Primitives: async_graphql::InputType + IntoIterator<Item = Self::Primitive>,
{
unreachable!("RelationFilter::parse")
}
fn to_value(
&self,
_field_name: &'static str,
_map: &mut async_graphql::indexmap::IndexMap<async_graphql::Name, async_graphql::Value>,
) where
Self::Primitive: async_graphql::InputType,
Self::Primitives: async_graphql::InputType + IntoIterator<Item = Self::Primitive>,
{
unreachable!("RelationFilter::to_value")
}
fn apply_filter<'q, QB: core::borrow::BorrowMut<sqlx::QueryBuilder<'q, sqlx::Postgres>>>(
&'q self,
field: &str,
mut builder: QB,
) -> Result<(), async_graphql::Error>
where
Self::Primitive:
for<'a> sqlx::Encode<'a, sqlx::Postgres> + sqlx::Type<sqlx::Postgres> + Send + Sync,
{
let builder = builder.borrow_mut();
if let Some(val) = &self.contains {
builder.push(format_args!("{field} @> array["));
builder.push_bind(val);
builder.push("]");
}
Ok(())
}
fn is_empty(&self) -> bool {
self.contains.is_none()
}
fn merge(&mut self, _other: Self) {}
}