#![warn(clippy::pedantic)]
#![allow(clippy::module_name_repetitions)] #![warn(missing_docs)]
#![warn(clippy::unwrap_used)]
pub mod auth;
pub mod entry;
pub mod error;
pub mod read_filter;
pub mod sink;
pub mod source;
pub mod task;
pub mod transform;
use crate::{
entry::Entry,
error::{transform::Error as TransformError, Error},
task::Task,
transform::Transform,
};
use std::collections::HashSet;
pub async fn run_task(t: &mut Task) -> Result<(), Error> {
tracing::trace!("Running task: {:#?}", t);
let entries = {
let untransformed = t.source.get().await?;
let transformed = match &t.transforms {
Some(transforms) => transform_entries(untransformed, transforms).await?,
None => untransformed,
};
remove_duplicates(transformed)
};
for entry in entries.into_iter().rev() {
t.sink.send(entry.msg, t.tag.as_deref()).await?;
if let Some(id) = &entry.id {
match &mut t.source {
source::Source::WithSharedReadFilter(_) => {
if let Some(rf) = &t.rf {
rf.write().await.mark_as_read(id).await?;
}
}
source::Source::WithCustomReadFilter(x) => x.mark_as_read(id).await?,
}
}
}
Ok(())
}
async fn transform_entries(
mut entries: Vec<Entry>,
transforms: &[Transform],
) -> Result<Vec<Entry>, TransformError> {
for tr in transforms {
entries = tr.transform(entries).await?;
}
Ok(entries)
}
fn remove_duplicates(entries: Vec<Entry>) -> Vec<Entry> {
let mut uniq = Vec::new();
let mut used_ids = HashSet::new();
for ent in entries {
match ent.id.as_deref() {
Some("") => panic!("An id should never be none but empty"),
Some(id) => {
if used_ids.insert(id.to_owned()) {
uniq.push(ent);
}
}
None => uniq.push(ent),
}
}
uniq
}