use std::collections::VecDeque;
use crate::client::FyuzClient;
use crate::error::Result;
use crate::models::Token;
use crate::params::ListTokensParams;
#[derive(Debug)]
pub struct TokenPager {
client: FyuzClient,
params: ListTokensParams,
next_page_number: i64,
fetched: i64,
total: Option<i64>,
buffer: VecDeque<Token>,
exhausted: bool,
}
impl TokenPager {
pub(crate) fn new(client: FyuzClient, params: ListTokensParams) -> Self {
let next_page_number = params.page_number.unwrap_or(1).max(1);
Self {
client,
params,
next_page_number,
fetched: 0,
total: None,
buffer: VecDeque::new(),
exhausted: false,
}
}
pub fn total_count(&self) -> Option<i64> {
self.total
}
pub fn fetched_count(&self) -> i64 {
self.fetched
}
pub async fn next_page(&mut self) -> Result<Option<Vec<Token>>> {
if self.exhausted {
return Ok(None);
}
let params = self.params.clone().page_number(self.next_page_number);
let page = self.client.list_tokens(¶ms).await?;
self.total = Some(page.token_count);
self.next_page_number += 1;
self.fetched += page.token_list.len() as i64;
if page.token_list.is_empty() {
self.exhausted = true;
return Ok(None);
}
if self.fetched >= page.token_count {
self.exhausted = true;
}
Ok(Some(page.token_list))
}
pub async fn next_token(&mut self) -> Result<Option<Token>> {
loop {
if let Some(token) = self.buffer.pop_front() {
return Ok(Some(token));
}
match self.next_page().await? {
Some(page) => self.buffer.extend(page),
None => return Ok(None),
}
}
}
pub async fn collect_all(&mut self) -> Result<Vec<Token>> {
let mut all = Vec::new();
all.extend(self.buffer.drain(..));
while let Some(page) = self.next_page().await? {
all.extend(page);
}
Ok(all)
}
}