use super::CliError;
pub fn collect_pages<T, C>(
initial_cursor: Option<C>,
limit: u16,
max_pages: usize,
mut fetch: impl FnMut(Option<C>, u16) -> Result<(Vec<T>, Option<C>), CliError>,
mut validate_next: impl FnMut(Option<&C>, &C) -> Result<(), CliError>,
) -> Result<(Vec<T>, usize), CliError>
where
C: Clone,
{
let mut cursor = initial_cursor;
let mut items = Vec::new();
let mut pages = 0usize;
loop {
enforce_page_budget(pages, max_pages)?;
let (page_items, next_cursor) = fetch(cursor.clone(), limit)?;
pages += 1;
items.extend(page_items);
let Some(next_cursor) = next_cursor else {
return Ok((items, pages));
};
validate_next(cursor.as_ref(), &next_cursor)?;
cursor = Some(next_cursor);
}
}
const fn enforce_page_budget(pages: usize, maximum: usize) -> Result<(), CliError> {
if pages == maximum {
Err(CliError::PaginationLimit(maximum))
} else {
Ok(())
}
}