mod connection_type;
mod cursor;
mod edge;
mod page_info;
mod slice;
use crate::{Context, FieldResult, ObjectType};
pub use connection_type::Connection;
pub use cursor::{Cursor, ToGraphQLCursor};
pub use page_info::PageInfo;
pub enum QueryOperation {
None,
After {
after: Cursor,
},
Before {
before: Cursor,
},
Between {
after: Cursor,
before: Cursor,
},
First {
limit: usize,
},
FirstAfter {
limit: usize,
after: Cursor,
},
FirstBefore {
limit: usize,
before: Cursor,
},
FirstBetween {
limit: usize,
after: Cursor,
before: Cursor,
},
Last {
limit: usize,
},
LastAfter {
limit: usize,
after: Cursor,
},
LastBefore {
limit: usize,
before: Cursor,
},
LastBetween {
limit: usize,
after: Cursor,
before: Cursor,
},
Invalid,
}
#[async_graphql_derive::SimpleObject(internal)]
pub struct EmptyEdgeFields;
struct Pagination {
after: Option<Cursor>,
before: Option<Cursor>,
first: Option<i32>,
last: Option<i32>,
}
#[async_trait::async_trait]
pub trait DataSource: Sync + Send {
type Element;
type EdgeFieldsObj: ObjectType + Send + Sync;
async fn query(
&self,
ctx: &Context<'_>,
after: Option<Cursor>,
before: Option<Cursor>,
first: Option<i32>,
last: Option<i32>,
) -> FieldResult<Connection<Self::Element, Self::EdgeFieldsObj>> {
let pagination = Pagination {
first,
last,
before,
after,
};
let operation = match pagination {
Pagination {
first: Some(_),
last: Some(_),
before: _,
after: _,
} => QueryOperation::Invalid,
Pagination {
first: None,
last: None,
before: None,
after: None,
} => QueryOperation::None,
Pagination {
first: None,
last: None,
before: Some(before),
after: None,
} => QueryOperation::Before { before },
Pagination {
first: None,
last: None,
before: None,
after: Some(after),
} => QueryOperation::After { after },
Pagination {
first: None,
last: None,
before: Some(before),
after: Some(after),
} => QueryOperation::Between { after, before },
Pagination {
first: Some(limit),
last: None,
before: None,
after: None,
} => QueryOperation::First {
limit: limit.max(0) as usize,
},
Pagination {
first: Some(limit),
last: None,
before: Some(before),
after: None,
} => QueryOperation::FirstBefore {
limit: limit.max(0) as usize,
before,
},
Pagination {
first: Some(limit),
last: None,
before: None,
after: Some(after),
} => QueryOperation::FirstAfter {
limit: limit.max(0) as usize,
after,
},
Pagination {
first: Some(limit),
last: None,
before: Some(before),
after: Some(after),
} => QueryOperation::FirstBetween {
limit: limit.max(0) as usize,
after,
before,
},
Pagination {
first: None,
last: Some(limit),
before: None,
after: None,
} => QueryOperation::Last {
limit: limit.max(0) as usize,
},
Pagination {
first: None,
last: Some(limit),
before: Some(before),
after: None,
} => QueryOperation::LastBefore {
limit: limit.max(0) as usize,
before,
},
Pagination {
first: None,
last: Some(limit),
before: None,
after: Some(after),
} => QueryOperation::LastAfter {
limit: limit.max(0) as usize,
after,
},
Pagination {
first: None,
last: Some(limit),
before: Some(before),
after: Some(after),
} => QueryOperation::LastBetween {
limit: limit.max(0) as usize,
after,
before,
},
};
self.query_operation(ctx, &operation).await
}
async fn query_operation(
&self,
ctx: &Context<'_>,
operation: &QueryOperation,
) -> FieldResult<Connection<Self::Element, Self::EdgeFieldsObj>>;
}