1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
pub mod feed;
pub mod html;
pub mod json;
pub mod print;
pub mod use_raw_contents;
use self::feed::Feed;
use self::html::Html;
use self::json::Json;
use self::use_raw_contents::UseRawContents;
use super::result::TransformedEntry;
use crate::error::transform::Error as TransformError;
use crate::source::http::{self, Http};
use crate::{entry::Entry, error::transform::Kind as TransformErrorKind};
use derive_more::From;
pub trait TransformEntry {
type Error: Into<TransformErrorKind>;
#[allow(clippy::missing_errors_doc)]
fn transform_entry(&self, entry: &Entry) -> Result<Vec<TransformedEntry>, Self::Error>;
}
#[allow(missing_docs, clippy::large_enum_variant)]
#[derive(From, Debug)]
pub enum Kind {
Http,
Html(Html),
Json(Json),
Feed(Feed),
UseRawContents(UseRawContents),
Print,
}
impl Kind {
pub async fn transform(
&self,
entry: Entry,
output: &mut Vec<Entry>,
) -> Result<(), TransformError> {
macro_rules! delegate {
($($t:tt),+ custom => { $($custom_t:pat => $custom_impl:expr),+ }) => {
match self {
$(Self::$t(x) => x.transform_entry(&entry).map_err(Into::into),)+
$($custom_t => $custom_impl,)+
}
};
}
let v = delegate!(
Html, Json, Feed, UseRawContents
custom => {
Self::Http => {
Http::transform(&entry, http::TransformFromField::MessageLink) .await
.map(|x| vec![x])
.map_err(Into::into)
},
Self::Print => {
print::print(&entry).await;
Ok(vec![TransformedEntry::default()])
}
}
)
.map_err(|kind| TransformError {
kind,
original_entry: entry.clone(),
})?;
output.extend(
v.into_iter()
.map(|new_entry| new_entry.into_entry(entry.clone())),
);
Ok(())
}
}