264 lines
8.2 KiB
Rust
264 lines
8.2 KiB
Rust
use crate::pagination::{Pagination, SearchPagination};
|
|
use hyaenidae_profiles::store::{Comment, File, Profile, Report, ReportKind, Server, Submission};
|
|
use std::collections::HashMap;
|
|
use uuid::Uuid;
|
|
|
|
pub(super) struct ReportPager<'b> {
|
|
pub(super) store: &'b hyaenidae_profiles::store::Store,
|
|
pub(super) reports: &'b mut HashMap<Uuid, Report>,
|
|
pub(super) profiles: &'b mut HashMap<Uuid, Profile>,
|
|
pub(super) submissions: &'b mut HashMap<Uuid, Submission>,
|
|
pub(super) comments: &'b mut HashMap<Uuid, Comment>,
|
|
pub(super) files: &'b mut HashMap<Uuid, File>,
|
|
}
|
|
|
|
pub(super) struct OpenPager<'b>(pub(super) ReportPager<'b>);
|
|
pub(super) struct ClosedPager<'b>(pub(super) ReportPager<'b>);
|
|
|
|
pub(super) struct ServerPager<'b> {
|
|
pub(super) self_id: Uuid,
|
|
pub(super) store: &'b hyaenidae_profiles::store::Store,
|
|
pub(super) servers: &'b mut HashMap<Uuid, Server>,
|
|
}
|
|
|
|
pub(super) struct FederatedPager<'a>(pub(super) ServerPager<'a>);
|
|
pub(super) struct InboundPager<'a>(pub(super) ServerPager<'a>);
|
|
pub(super) struct OutboundPager<'a>(pub(super) ServerPager<'a>);
|
|
pub(super) struct BlockedPager<'a>(pub(super) ServerPager<'a>);
|
|
pub(super) struct KnownPager<'a>(pub(super) ServerPager<'a>);
|
|
|
|
impl<'b> Pagination for OpenPager<'b> {
|
|
fn from_max<'a>(&'a mut self, max: Uuid) -> Box<dyn DoubleEndedIterator<Item = Uuid> + 'a> {
|
|
Box::new(
|
|
self.0
|
|
.store
|
|
.reports
|
|
.open_reports_older_than(max)
|
|
.filter_map(move |report_id| self.0.filter_report(report_id)),
|
|
)
|
|
}
|
|
|
|
fn from_min<'a>(&'a mut self, min: Uuid) -> Box<dyn DoubleEndedIterator<Item = Uuid> + 'a> {
|
|
Box::new(
|
|
self.0
|
|
.store
|
|
.reports
|
|
.open_reports_newer_than(min)
|
|
.filter_map(move |report_id| self.0.filter_report(report_id)),
|
|
)
|
|
}
|
|
|
|
fn from_start<'a>(&'a mut self) -> Box<dyn DoubleEndedIterator<Item = Uuid> + 'a> {
|
|
Box::new(
|
|
self.0
|
|
.store
|
|
.reports
|
|
.open_reports()
|
|
.filter_map(move |report_id| self.0.filter_report(report_id)),
|
|
)
|
|
}
|
|
}
|
|
|
|
impl<'b> Pagination for ClosedPager<'b> {
|
|
fn from_max<'a>(&'a mut self, max: Uuid) -> Box<dyn DoubleEndedIterator<Item = Uuid> + 'a> {
|
|
Box::new(
|
|
self.0
|
|
.store
|
|
.reports
|
|
.closed_reports_older_than(max)
|
|
.filter_map(move |report_id| self.0.filter_report(report_id)),
|
|
)
|
|
}
|
|
|
|
fn from_min<'a>(&'a mut self, min: Uuid) -> Box<dyn DoubleEndedIterator<Item = Uuid> + 'a> {
|
|
Box::new(
|
|
self.0
|
|
.store
|
|
.reports
|
|
.closed_reports_newer_than(min)
|
|
.filter_map(move |report_id| self.0.filter_report(report_id)),
|
|
)
|
|
}
|
|
|
|
fn from_start<'a>(&'a mut self) -> Box<dyn DoubleEndedIterator<Item = Uuid> + 'a> {
|
|
Box::new(
|
|
self.0
|
|
.store
|
|
.reports
|
|
.closed_reports()
|
|
.filter_map(move |report_id| self.0.filter_report(report_id)),
|
|
)
|
|
}
|
|
}
|
|
|
|
impl<'b> ReportPager<'b> {
|
|
fn filter_report(&mut self, report_id: Uuid) -> Option<Uuid> {
|
|
if !self.reports.contains_key(&report_id) {
|
|
let report = self.store.reports.by_id(report_id).ok()??;
|
|
|
|
if let Some(id) = report.reporter_profile() {
|
|
self.cache_profile(id)?;
|
|
}
|
|
|
|
match report.kind() {
|
|
ReportKind::Profile => {
|
|
self.cache_profile(report.item())?;
|
|
}
|
|
ReportKind::Submission => {
|
|
self.cache_submission(report.item())?;
|
|
}
|
|
ReportKind::Comment => {
|
|
self.cache_comment(report.item())?;
|
|
}
|
|
ReportKind::Post => {
|
|
unimplemented!();
|
|
}
|
|
}
|
|
|
|
self.reports.insert(report.id(), report);
|
|
|
|
Some(report_id)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
fn cache_comment(&mut self, comment_id: Uuid) -> Option<()> {
|
|
if !self.comments.contains_key(&comment_id) {
|
|
let comment = self.store.comments.by_id(comment_id).ok()??;
|
|
|
|
self.cache_profile(comment.profile_id())?;
|
|
self.comments.insert(comment.id(), comment);
|
|
}
|
|
|
|
Some(())
|
|
}
|
|
|
|
fn cache_submission(&mut self, submission_id: Uuid) -> Option<()> {
|
|
if !self.submissions.contains_key(&submission_id) {
|
|
let submission = self.store.submissions.by_id(submission_id).ok()??;
|
|
|
|
self.cache_profile(submission.profile_id())?;
|
|
|
|
for file_id in submission.files() {
|
|
self.cache_file(*file_id)?;
|
|
}
|
|
|
|
self.submissions.insert(submission.id(), submission);
|
|
}
|
|
|
|
Some(())
|
|
}
|
|
|
|
fn cache_profile(&mut self, profile_id: Uuid) -> Option<()> {
|
|
if !self.profiles.contains_key(&profile_id) {
|
|
let profile = self.store.profiles.by_id(profile_id).ok()??;
|
|
|
|
for file_id in profile.icon().into_iter().chain(profile.banner()) {
|
|
self.cache_file(file_id)?;
|
|
}
|
|
|
|
self.profiles.insert(profile.id(), profile);
|
|
}
|
|
|
|
Some(())
|
|
}
|
|
|
|
fn cache_file(&mut self, file_id: Uuid) -> Option<()> {
|
|
if !self.files.contains_key(&file_id) {
|
|
let file = self.store.files.by_id(file_id).ok()??;
|
|
self.files.insert(file.id(), file);
|
|
}
|
|
|
|
Some(())
|
|
}
|
|
}
|
|
|
|
impl<'b> SearchPagination for FederatedPager<'b> {
|
|
fn from_term<'a>(&'a mut self, _: &'a str) -> Box<dyn DoubleEndedIterator<Item = Uuid> + 'a> {
|
|
Box::new(
|
|
self.0
|
|
.store
|
|
.view
|
|
.server_follows
|
|
.forward_iter(self.0.self_id)
|
|
.chain(
|
|
self.0
|
|
.store
|
|
.view
|
|
.server_follows
|
|
.backward_iter(self.0.self_id),
|
|
)
|
|
.filter_map(move |server_id| self.0.filter_server(server_id))
|
|
.rev(),
|
|
)
|
|
}
|
|
}
|
|
|
|
impl<'b> SearchPagination for InboundPager<'b> {
|
|
fn from_term<'a>(&'a mut self, _: &'a str) -> Box<dyn DoubleEndedIterator<Item = Uuid> + 'a> {
|
|
Box::new(
|
|
self.0
|
|
.store
|
|
.view
|
|
.server_follow_requests
|
|
.forward_iter(self.0.self_id)
|
|
.filter_map(move |server_id| self.0.filter_server(server_id))
|
|
.rev(),
|
|
)
|
|
}
|
|
}
|
|
|
|
impl<'b> SearchPagination for OutboundPager<'b> {
|
|
fn from_term<'a>(&'a mut self, _: &'a str) -> Box<dyn DoubleEndedIterator<Item = Uuid> + 'a> {
|
|
Box::new(
|
|
self.0
|
|
.store
|
|
.view
|
|
.server_follow_requests
|
|
.backward_iter(self.0.self_id)
|
|
.filter_map(move |server_id| self.0.filter_server(server_id))
|
|
.rev(),
|
|
)
|
|
}
|
|
}
|
|
|
|
impl<'b> SearchPagination for BlockedPager<'b> {
|
|
fn from_term<'a>(&'a mut self, _: &'a str) -> Box<dyn DoubleEndedIterator<Item = Uuid> + 'a> {
|
|
Box::new(
|
|
self.0
|
|
.store
|
|
.view
|
|
.server_blocks
|
|
.backward_iter(self.0.self_id)
|
|
.filter_map(move |server_id| self.0.filter_server(server_id))
|
|
.rev(),
|
|
)
|
|
}
|
|
}
|
|
|
|
impl<'b> SearchPagination for KnownPager<'b> {
|
|
fn from_term<'a>(&'a mut self, _: &'a str) -> Box<dyn DoubleEndedIterator<Item = Uuid> + 'a> {
|
|
Box::new(
|
|
self.0
|
|
.store
|
|
.servers
|
|
.known()
|
|
.filter_map(move |server_id| self.0.filter_server(server_id))
|
|
.rev(),
|
|
)
|
|
}
|
|
}
|
|
|
|
impl<'b> ServerPager<'b> {
|
|
fn filter_server(&mut self, server_id: Uuid) -> Option<Uuid> {
|
|
if !self.servers.contains_key(&server_id) {
|
|
let server = self.store.servers.by_id(server_id).ok()??;
|
|
self.servers.insert(server.id(), server);
|
|
Some(server_id)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|