pub mod caps;
pub mod html;
pub mod json;
pub mod print;
pub mod rss;
pub mod use_raw_contents;
pub use self::html::Html;
pub use self::json::Json;
pub use self::rss::Rss;
use std::sync::Arc;
use tokio::sync::RwLock;
use crate::entry::Entry;
use crate::error::transform::Error as TransformError;
use crate::error::transform::Kind as TransformErrorKind;
use crate::read_filter::ReadFilter;
use crate::sink::Message;
use crate::source::with_shared_rf::http::TransformFromField;
use crate::source::Http;
#[allow(clippy::large_enum_variant)]
#[derive(Debug)]
pub enum Transform {
Http,
Html(Html),
Json(Json),
Rss(Rss),
ReadFilter(Arc<RwLock<ReadFilter>>),
UseRawContents,
Caps,
Print,
}
impl Transform {
pub async fn transform(&self, mut entries: Vec<Entry>) -> Result<Vec<Entry>, TransformError> {
Ok(if let Transform::ReadFilter(rf) = self {
rf.read().await.remove_read_from(&mut entries);
entries
} else {
let mut fully_transformed_entries = Vec::new();
for entry in entries {
fully_transformed_entries.extend(self.transform_one(entry).await?);
}
fully_transformed_entries
})
}
async fn transform_one(&self, entry: Entry) -> Result<Vec<Entry>, TransformError> {
let res: Result<_, TransformErrorKind> = match self {
Transform::Http => {
Http::transform(&entry, TransformFromField::MessageLink) .await
.map(|x| vec![x])
.map_err(Into::into)
}
Transform::Html(x) => x.transform(&entry).map_err(Into::into),
Transform::Json(x) => x.transform(&entry).map_err(Into::into),
Transform::Rss(x) => x.transform(&entry).map_err(Into::into),
Transform::ReadFilter(_) => {
unreachable!("Read filter doesn't support transforming one by one")
}
Transform::UseRawContents => Ok(vec![use_raw_contents::transform(&entry)]),
Transform::Caps => Ok(vec![caps::transform(&entry)]),
Transform::Print => {
print::transform(&entry).await;
Ok(vec![Entry::default()])
}
};
res.map_err(|kind| TransformError {
kind,
original_entry: entry.clone(),
})
.map(|v| {
v.into_iter()
.map(|new_entry| Entry {
id: new_entry.id.or_else(|| entry.id.clone()),
raw_contents: new_entry
.raw_contents
.or_else(|| entry.raw_contents.clone()),
msg: Message {
title: new_entry.msg.title.or_else(|| entry.msg.title.clone()),
body: new_entry.msg.body.or_else(|| entry.msg.body.clone()),
link: new_entry.msg.link.or_else(|| entry.msg.link.clone()),
media: new_entry.msg.media.or_else(|| entry.msg.media.clone()),
},
})
.collect()
})
}
}