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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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()
})
}
}