use super::{LabelerDefs, ModerationDecision, ModerationPrefs, moderate};
use jacquard_common::bos::BosStr;
use jacquard_common::types::string::Did;
pub trait Moderateable<S: BosStr> {
fn moderate_all(
&self,
prefs: &ModerationPrefs,
defs: &LabelerDefs,
accepted_labelers: &[Did],
) -> Vec<(&'static str, ModerationDecision)>;
}
pub trait ModeratableIterExt<'a, S: BosStr, T: Moderateable<S> + 'a>:
Iterator<Item = &'a T> + Sized
{
fn with_moderation(
self,
prefs: &'a ModerationPrefs,
defs: &'a LabelerDefs,
accepted_labelers: &'a [Did],
) -> impl Iterator<Item = (&'a T, Vec<(&'static str, ModerationDecision)>)> {
self.map(move |item| {
let scoped_decisions = item.moderate_all(prefs, defs, accepted_labelers);
(item, scoped_decisions)
})
}
fn filter_moderated(
self,
prefs: &'a ModerationPrefs,
defs: &'a LabelerDefs,
accepted_labelers: &'a [Did],
) -> impl Iterator<Item = &'a T> {
self.filter(move |item| {
let scoped_decisions = item.moderate_all(prefs, defs, accepted_labelers);
!scoped_decisions.iter().any(|(_, decision)| decision.filter)
})
}
}
impl<'a, S: BosStr, T: Moderateable<S> + 'a, I: Iterator<Item = &'a T>>
ModeratableIterExt<'a, S, T> for I
{
}
#[cfg(feature = "api_bluesky")]
mod bluesky_impls {
use super::*;
use jacquard_api::app_bsky::feed::{FeedViewPost, ReplyRefParent, ReplyRefRoot};
use jacquard_common::bos::DefaultStr;
impl Moderateable<DefaultStr> for FeedViewPost {
fn moderate_all(
&self,
prefs: &ModerationPrefs,
defs: &LabelerDefs,
accepted_labelers: &[Did],
) -> Vec<(&'static str, ModerationDecision)> {
let mut decisions = vec![
("post", moderate(&self.post, prefs, defs, accepted_labelers)),
(
"author",
moderate(&self.post.author, prefs, defs, accepted_labelers),
),
];
if let Some(reply) = &self.reply {
if let ReplyRefParent::PostView(parent) = &reply.parent {
decisions.push((
"reply_parent",
moderate(&**parent, prefs, defs, accepted_labelers),
));
decisions.push((
"reply_parent_author",
moderate(&parent.author, prefs, defs, accepted_labelers),
));
}
if let ReplyRefRoot::PostView(root) = &reply.root {
decisions.push((
"reply_root",
moderate(&**root, prefs, defs, accepted_labelers),
));
decisions.push((
"reply_root_author",
moderate(&root.author, prefs, defs, accepted_labelers),
));
}
if let Some(grandparent_author) = &reply.grandparent_author {
decisions.push((
"reply_grandparent_author",
moderate(grandparent_author, prefs, defs, accepted_labelers),
));
}
}
decisions
}
}
}