use std::collections::VecDeque;
use grammers_mtsender::InvocationError;
use super::Client;
pub struct IterBuffer<R, T> {
pub(crate) client: Client,
pub(crate) limit: Option<usize>,
pub(crate) fetched: usize,
pub(crate) buffer: VecDeque<T>,
pub(crate) last_chunk: bool,
pub(crate) total: Option<usize>,
pub(crate) request: R,
}
impl<R, T> IterBuffer<R, T> {
pub(crate) fn from_request(client: &Client, capacity: usize, request: R) -> Self {
Self {
client: client.clone(),
limit: None,
fetched: 0,
buffer: VecDeque::with_capacity(capacity),
last_chunk: false,
total: None,
request,
}
}
pub fn limit(mut self, n: usize) -> Self {
self.limit = Some(n);
self
}
fn limit_reached(&self) -> bool {
if let Some(limit) = self.limit {
self.fetched >= limit
} else {
false
}
}
pub(crate) fn next_raw(&mut self) -> Option<Result<Option<T>, InvocationError>> {
if self.limit_reached() || (self.buffer.is_empty() && self.last_chunk) {
Some(Ok(None))
} else {
self.pop_item().map(|item| Ok(Some(item)))
}
}
pub(crate) fn determine_limit(&self, max: usize) -> i32 {
if let Some(limit) = self.limit {
if self.fetched < limit {
(limit - self.fetched).min(max) as i32
} else {
1 }
} else {
max as i32
}
}
pub(crate) fn pop_item(&mut self) -> Option<T> {
if let Some(item) = self.buffer.pop_front() {
self.fetched += 1;
Some(item)
} else {
None
}
}
}