use async_graphql::connection::Edge;
use koan_core::db::connection::Database;
use koan_core::db::queries;
use super::types::Conn;
pub(super) const DEFAULT_PAGE: usize = 50;
pub(super) const MAX_PAGE: usize = 500;
pub(super) fn page_size(first: Option<i32>) -> usize {
match first {
Some(f) => (f.max(0) as usize).min(MAX_PAGE),
None => DEFAULT_PAGE,
}
}
pub(super) fn page_offset(after: Option<&str>) -> usize {
after
.and_then(|c| c.parse::<usize>().ok())
.map(|i| i.saturating_add(1))
.unwrap_or(0)
}
pub(super) fn paginate<T: async_graphql::OutputType>(
items: Vec<T>,
after: Option<String>,
first: Option<i32>,
) -> async_graphql::Result<Conn<T>> {
let total = items.len();
let start = page_offset(after.as_deref()).min(total);
let end = start.saturating_add(page_size(first)).min(total);
let mut conn = Conn::new(start > 0, end < total);
for (i, item) in items.into_iter().enumerate().skip(start).take(end - start) {
conn.edges.push(Edge::new(i, item));
}
Ok(conn)
}
pub(super) fn paginate_window<T: async_graphql::OutputType>(
mut rows: Vec<T>,
offset: usize,
limit: usize,
) -> Conn<T> {
let has_next = rows.len() > limit;
rows.truncate(limit);
let mut conn = Conn::new(offset > 0, has_next);
for (i, item) in rows.into_iter().enumerate() {
conn.edges.push(Edge::new(offset + i, item));
}
conn
}
pub(super) fn extract_year(date: &str) -> Option<i32> {
date.get(..4).and_then(|s| s.parse().ok())
}
pub(super) fn album_year(album: &queries::AlbumRow) -> Option<i32> {
album.date.as_deref().and_then(extract_year)
}
pub(super) fn sync_favourite_to_remote(db: &Database, track_id: i64, star: bool) {
koan_core::helpers::sync_favourite_to_remote(db, track_id, star);
}