use std::ops::Deref;
use super::{List, Paginate, Query};
use crate::schema::Load;
use crate::{Executor, Result};
use toasty_core::stmt;
#[derive(Debug)]
pub struct Page<M> {
pub items: Vec<M>,
query: Query<List<M>>,
pub next_cursor: Option<stmt::Expr>,
pub prev_cursor: Option<stmt::Expr>,
}
impl<M> Page<M> {
pub(crate) fn new(
items: Vec<M>,
query: Query<List<M>>,
next_cursor: Option<stmt::Expr>,
prev_cursor: Option<stmt::Expr>,
) -> Self {
Self {
items,
query,
next_cursor,
prev_cursor,
}
}
pub fn has_next(&self) -> bool {
self.next_cursor.is_some()
}
pub fn has_prev(&self) -> bool {
self.prev_cursor.is_some()
}
}
impl<M: Load> Page<M> {
pub async fn next(&self, executor: &mut dyn Executor) -> Result<Option<Page<M::Output>>> {
match &self.next_cursor {
Some(cursor) => Ok(Some(
Paginate::from(self.query.clone())
.after(cursor.clone())
.exec(executor)
.await?,
)),
None => Ok(None),
}
}
pub async fn prev(&self, executor: &mut dyn Executor) -> Result<Option<Page<M::Output>>> {
match &self.prev_cursor {
Some(cursor) => Ok(Some(
Paginate::from(self.query.clone())
.before(cursor.clone())
.exec(executor)
.await?,
)),
None => Ok(None),
}
}
}
impl<M> Deref for Page<M> {
type Target = [M];
fn deref(&self) -> &Self::Target {
&self.items
}
}