use crate::{
QueryProgress,
snapshot_cache::{PagedCollectionPage, PagedCollectionState},
sns::report::{
SnsHostError, SnsProposalRow,
cache_attempt::SnsRefreshContext,
cache_collection::{SnsCollectionPages, collect_sns_snapshot},
proposals_cache::model::CompleteSnsProposals,
source::{SnsProposalsSource, validate_mainnet_sns_proposal_page},
},
};
pub(in crate::sns::report::proposals_cache) async fn fetch_complete_sns_proposals(
context: SnsRefreshContext<'_>,
source: &dyn SnsProposalsSource,
progress: &mut dyn QueryProgress,
) -> Result<CompleteSnsProposals, SnsHostError> {
collect_sns_snapshot(context, SnsProposalsRefreshPages { source }, progress).await
}
struct SnsProposalsRefreshPages<'a> {
source: &'a dyn SnsProposalsSource,
}
impl SnsCollectionPages for SnsProposalsRefreshPages<'_> {
type Row = SnsProposalRow;
type Cursor = u64;
const COLLECTION: &'static str = "proposals";
fn fetch_next_page<'a>(
&'a mut self,
context: SnsRefreshContext<'a>,
pages: &'a mut PagedCollectionState<Self::Row, Self::Cursor>,
) -> crate::report::SourceFuture<'a, Result<PagedCollectionPage, SnsHostError>> {
Box::pin(async move {
let page = self
.source
.fetch_sns_proposal_page(
context.fetch_request,
context.sns,
context.request.page_size,
pages.next_cursor().copied(),
)
.await?;
validate_mainnet_sns_proposal_page(
&page,
context.request.page_size,
pages.next_cursor().copied(),
)?;
let last_cursor = page.iter().map(|proposal| proposal.proposal_id).min();
let page_len = page.len();
Ok(pages.ingest_page(page, page_len, last_cursor, ToString::to_string))
})
}
fn cursor_text(cursor: &Self::Cursor) -> String {
cursor.to_string()
}
}