mod connection_type;
mod cursor;
mod edge;
mod page_info;
mod slice;
use crate::{Context, FieldResult, ObjectType, OutputValueType};
pub use connection_type::Connection;
pub use cursor::CursorType;
pub use edge::Edge;
pub use page_info::PageInfo;
use std::fmt::Display;
#[async_graphql_derive::SimpleObject(internal)]
pub struct EmptyFields;
#[async_trait::async_trait]
pub trait DataSource {
type CursorType: CursorType + Send + Sync;
type NodeType: OutputValueType + Send;
type ConnectionFieldsType: ObjectType + Send;
type EdgeFieldsType: ObjectType + Send;
async fn query(
&self,
ctx: &Context<'_>,
after: Option<String>,
before: Option<String>,
first: Option<i32>,
last: Option<i32>,
) -> FieldResult<
Connection<
Self::CursorType,
Self::NodeType,
Self::ConnectionFieldsType,
Self::EdgeFieldsType,
>,
>
where
<Self::CursorType as CursorType>::Error: Display + Send + Sync + 'static,
{
if first.is_some() && last.is_some() {
return Err(
"The \"first\" and \"last\" parameters cannot exist at the same time".into(),
);
}
let first = match first {
Some(first) if first < 0 => {
return Err("The \"first\" parameter must be a non-negative number".into())
}
Some(first) => Some(first as usize),
None => None,
};
let last = match last {
Some(last) if last < 0 => {
return Err("The \"last\" parameter must be a non-negative number".into())
}
Some(last) => Some(last as usize),
None => None,
};
let before = match before {
Some(before) => Some(Self::CursorType::decode_cursor(&before)?),
None => None,
};
let after = match after {
Some(after) => Some(Self::CursorType::decode_cursor(&after)?),
None => None,
};
self.execute_query(ctx, after, before, first, last).await
}
async fn execute_query(
&self,
ctx: &Context<'_>,
after: Option<Self::CursorType>,
before: Option<Self::CursorType>,
first: Option<usize>,
last: Option<usize>,
) -> FieldResult<
Connection<
Self::CursorType,
Self::NodeType,
Self::ConnectionFieldsType,
Self::EdgeFieldsType,
>,
>;
}