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!()
}
}