cido 0.2.0

Core traits and implementations for indexing with cido
Documentation
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) {}
}