cido 0.2.0

Core traits and implementations for indexing with cido
Documentation
use crate::cidomap::Identifiable;
use crate::{
  cidomap::{Cidomap, Transformer},
  filter::*,
  graphql::{GraphqlInputType, GraphqlQueryBuilder},
  network::Network,
};
use futures::future::{BoxFuture, FutureExt};
use std::borrow::Borrow;

pub trait TypeMap<T> {
  type Output: Sized;
  type Transformer: Transformer;

  fn map_entity_type<'b: 'a, 'a, 'ctx>(
      ctx: &'a async_graphql::Context<'ctx>,
      block_number: <<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber,
      end_block_number: Option<<<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber>,
      val: T,
      builder: GraphqlQueryBuilder<Self::Transformer>,
    ) -> BoxFuture<'a, async_graphql::Result<Self::Output>>
    where
      T: 'b + Send,
      <<Self::Transformer as Transformer>::GraphqlInput as GraphqlInputType>::Where: RootWhere<IdFilter = <<Self::Transformer as Identifiable>::Id as ToDbFilter>::Filter, BlockNumber = <<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber>,
      <Self::Transformer as Identifiable>::Id: ToDbFilter,
      <<Self::Transformer as Identifiable>::Id as ToDbFilter>::Filter: Filter
    ;

  fn map_event_type<'b: 'a, 'a, 'ctx>(
      ctx: &'a async_graphql::Context<'ctx>,
      block_number: <<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber,
      val: T,
      builder: GraphqlQueryBuilder<Self::Transformer>,
    ) -> BoxFuture<'a, async_graphql::Result<Self::Output>>
      where
        T: 'b + Send,
        <<Self::Transformer as Transformer>::GraphqlInput as GraphqlInputType>::Where: RootWhere<IdFilter = <<Self::Transformer as Identifiable>::Id as ToDbFilter>::Filter, BlockNumber = <<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber>,
        <Self::Transformer as Identifiable>::Id: ToDbFilter,
        <<Self::Transformer as Identifiable>::Id as ToDbFilter>::Filter: Filter
      ;
}

impl<T, U> TypeMap<&T> for U
where
  U: Transformer<Id = T>,
  <U as Identifiable>::Id: ToDbFilter,
  T: Send + Sync + Borrow<<U as Identifiable>::Id> + ToDbFilter,
{
  type Output = U::GraphqlOutput;
  type Transformer = U;

    fn map_entity_type<'b: 'a, 'a, 'ctx>(
      ctx: &'a async_graphql::Context<'ctx>,
      block_number: <<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber,
      _end_block_number: Option<<<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber>,
      id: &'b T,
      builder: GraphqlQueryBuilder<Self::Transformer>,
    ) -> BoxFuture<'a, async_graphql::Result<Self::Output>>
    where
      T: 'b,
      <<Self::Transformer as Transformer>::GraphqlInput as GraphqlInputType>::Where: RootWhere<IdFilter = <<Self::Transformer as Identifiable>::Id as ToDbFilter>::Filter, BlockNumber = <<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber>,
      <Self::Transformer as Identifiable>::Id: ToDbFilter,
      <<Self::Transformer as Identifiable>::Id as ToDbFilter>::Filter: Filter
    {
    async move {
      GraphqlQueryBuilder::<Self::Transformer>::fetch_optional_by_blocknumber(
        builder,
        ctx,
        id.borrow(),
        block_number,
      )
      .await
      .and_then(|opt| opt.ok_or_else(|| async_graphql::Error::new("not found")))
    }
    .boxed()
  }

    fn map_event_type<'b: 'a, 'a, 'ctx>(
      ctx: &'a async_graphql::Context<'ctx>,
      block_number: <<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber,
      id: &'b T,
      builder: GraphqlQueryBuilder<Self::Transformer>,
    ) -> BoxFuture<'a, async_graphql::Result<Self::Output>>
      where
        T: 'b + Send,
        <<Self::Transformer as Transformer>::GraphqlInput as GraphqlInputType>::Where: RootWhere<IdFilter = <<Self::Transformer as Identifiable>::Id as ToDbFilter>::Filter, BlockNumber = <<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber>,
        <Self::Transformer as Identifiable>::Id: ToDbFilter,
        <<Self::Transformer as Identifiable>::Id as ToDbFilter>::Filter: Filter
    {
    async move {
      GraphqlQueryBuilder::<Self::Transformer>::fetch_optional_by_blocknumber(
        builder,
        ctx,
        id.borrow(),
        block_number,
      )
      .await
      .and_then(|opt| opt.ok_or_else(|| async_graphql::Error::new("not found")))
    }
    .boxed()
  }
}

impl<T, U> TypeMap<&Option<T>> for Option<U>
where
  U: Transformer<Id = T>,
  <U as Identifiable>::Id: ToDbFilter,
  T: Send + Sync + Borrow<<U as Identifiable>::Id> + ToDbFilter,
{
  type Output = Option<U::GraphqlOutput>;
  type Transformer = U;

  fn map_entity_type<'b: 'a, 'a, 'ctx>(
    ctx: &'a async_graphql::Context<'ctx>,
    block_number: <<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber,
    _end_block_number: Option<<<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber>,
    val: &'b Option<T>,
    builder: GraphqlQueryBuilder<Self::Transformer>,
  ) -> BoxFuture<'a, async_graphql::Result<Self::Output>>
  where
    <<Self::Transformer as Transformer>::GraphqlInput as GraphqlInputType>::Where: RootWhere<IdFilter = <<Self::Transformer as Identifiable>::Id as ToDbFilter>::Filter, BlockNumber = <<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber>,
    <Self::Transformer as Identifiable>::Id: ToDbFilter,
    <<Self::Transformer as Identifiable>::Id as ToDbFilter>::Filter: Filter
  {
    async move {
      if let Some(id) = val {
        GraphqlQueryBuilder::<Self::Transformer>::fetch_optional_by_blocknumber(
          builder,
          ctx,
          id.borrow(),
          block_number,
        )
        .await
      } else {
        Ok(None)
      }
    }
    .boxed()
  }

    fn map_event_type<'b: 'a, 'a, 'ctx>(
      ctx: &'a async_graphql::Context<'ctx>,
      block_number: <<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber,
      val: &'b Option<T>,
      builder: GraphqlQueryBuilder<Self::Transformer>,
    ) -> BoxFuture<'a, async_graphql::Result<Self::Output>>
    where
      <<Self::Transformer as Transformer>::GraphqlInput as GraphqlInputType>::Where: RootWhere<IdFilter = <<Self::Transformer as Identifiable>::Id as ToDbFilter>::Filter, BlockNumber = <<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber>,
      <Self::Transformer as Identifiable>::Id: ToDbFilter,
      <<Self::Transformer as Identifiable>::Id as ToDbFilter>::Filter: Filter
    {
    async move {
      if let Some(id) = val {
        GraphqlQueryBuilder::<Self::Transformer>::fetch_optional_by_blocknumber(
          builder,
          ctx,
          id.borrow(),
          block_number,
        )
        .await
      } else {
        Ok(None)
      }
    }
    .boxed()
  }
}

#[cido_macros::_impls]
impl<T, U> TypeMap<&[T]> for Vec<U>
where
  U: Send + Transformer<Id = T>,
  <U as Identifiable>::Id: ToDbFilter,
  T: Send + Sync + Borrow<<U as Identifiable>::Id> + ToDbFilter,
{
  type Output = Vec<U::GraphqlOutput>;
  type Transformer = U;

  fn map_entity_type<'b: 'a, 'a, 'ctx>(
    ctx: &'a async_graphql::Context<'ctx>,
    block_number: <<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber,
    _end_block_number: Option<<<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber>,
    vals: &'b [T],
    builder: GraphqlQueryBuilder<Self::Transformer>,
  ) -> BoxFuture<'a, async_graphql::Result<Self::Output>>
  where
    T: 'b + Send,
    <<Self::Transformer as Transformer>::GraphqlInput as GraphqlInputType>::Where: RootWhere<IdFilter = <<Self::Transformer as Identifiable>::Id as ToDbFilter>::Filter, BlockNumber = <<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber>,
    <Self::Transformer as Identifiable>::Id: ToDbFilter,
    <<Self::Transformer as Identifiable>::Id as ToDbFilter>::Filter: Filter
  {
    unimplemented!()
  }

  fn map_event_type<'b: 'a, 'a, 'ctx>(
    ctx: &'a async_graphql::Context<'ctx>,
    block_number: <<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber,
    vals: &'b [T],
    builder: GraphqlQueryBuilder<Self::Transformer>,
  ) -> BoxFuture<'a, async_graphql::Result<Self::Output>>
    where
      T: 'b + Send,
      <<Self::Transformer as Transformer>::GraphqlInput as GraphqlInputType>::Where: RootWhere<IdFilter = <<Self::Transformer as Identifiable>::Id as ToDbFilter>::Filter, BlockNumber = <<<Self::Transformer as Transformer>::Cidomap as Cidomap>::Network as Network>::BlockNumber>,
      <Self::Transformer as Identifiable>::Id: ToDbFilter,
      <<Self::Transformer as Identifiable>::Id as ToDbFilter>::Filter: Filter
  {
    unimplemented!()
  }
}