pub mod entry;
pub mod field;
pub mod result;
use self::field::{Field, TransformField};
pub use self::{
entry::{feed::Feed, html::Html, json::Json, use_raw_contents::UseRawContents},
field::{caps::Caps, shorten::Shorten, trim::Trim},
};
use crate::utils::OptionExt;
use crate::{
entry::Entry, error::transform::Error as TransformError, error::transform::InvalidUrlError,
error::transform::Kind as TransformErrorKind, sink::Message,
};
use reqwest::Url;
#[allow(clippy::large_enum_variant)]
#[derive(Debug)]
pub enum Transform {
Entry(entry::Kind),
#[allow(missing_docs)]
Field { field: Field, kind: field::Kind },
}
impl Transform {
pub async fn transform(
&self,
mut entry: Entry,
output: &mut Vec<Entry>,
) -> Result<(), TransformError> {
match self {
Self::Entry(ent_tr) => ent_tr.transform(entry, output).await,
Self::Field { field, kind } => {
let old_val = match field {
Field::Title => entry.msg.title.take(),
Field::Body => entry.msg.body.take(),
Field::Link => entry.msg.link.take().map(|u| u.to_string()),
};
let new_val =
kind.transform_field(old_val.as_deref())
.map_err(|kind| TransformError {
kind,
original_entry: entry.clone(),
})?;
let final_val = new_val.get(old_val);
let new_entry = match field {
Field::Title => Entry {
msg: Message {
title: final_val,
..entry.msg
},
..entry
},
Field::Body => Entry {
msg: Message {
body: final_val,
..entry.msg
},
..entry
},
Field::Link => {
let link = final_val.try_map(|s| {
Url::try_from(s.as_str()).map_err(|e| TransformError {
kind: TransformErrorKind::FieldLinkTransformInvalidUrl(
InvalidUrlError(e, s),
),
original_entry: entry.clone(),
})
})?;
Entry {
msg: Message { link, ..entry.msg },
..entry
}
}
};
output.push(new_entry);
Ok(())
}
}
}
}
impl<T: Into<entry::Kind>> From<T> for Transform {
fn from(kind: T) -> Self {
Self::Entry(kind.into())
}
}