use crate::error::ManagerError;
use crate::retry::{with_retry, RetryPolicy};
#[derive(Debug, Clone)]
pub struct Page<T> {
pub items: Vec<T>,
pub page: i32,
pub pages: i32,
pub total: Option<i32>,
}
pub(crate) async fn fetch_page<T, E, F, Fut, M>(
retry: &RetryPolicy,
map_err: M,
fetch: F,
) -> Result<Page<T>, ManagerError>
where
M: Fn(E) -> ManagerError,
F: Fn() -> Fut,
Fut: std::future::Future<Output = Result<(Vec<T>, i32, i32, Option<i32>), E>>,
{
let (items, pages, current, total) = with_retry(retry, true, fetch).await.map_err(map_err)?;
Ok(Page {
items,
page: current,
pages,
total,
})
}
pub(crate) async fn collect_all<T, E, F, Fut, M>(
retry: &RetryPolicy,
map_err: M,
mut fetch: F,
) -> Result<Vec<T>, ManagerError>
where
M: Fn(E) -> ManagerError,
F: FnMut(i32) -> Fut,
Fut: std::future::Future<Output = Result<(Vec<T>, i32, i32), E>>,
{
let mut out = Vec::new();
let mut page = 1;
loop {
let (items, pages, _current) = with_retry(retry, true, || fetch(page))
.await
.map_err(&map_err)?;
let empty = items.is_empty();
out.extend(items);
if empty || page >= pages {
return Ok(out);
}
page += 1;
}
}