+47 -11 +/-1 browse
1 | diff --git a/core/src/message_filters.rs b/core/src/message_filters.rs |
2 | index 2a0ecbd..7da07c7 100644 |
3 | --- a/core/src/message_filters.rs |
4 | +++ b/core/src/message_filters.rs |
5 | @@ -51,9 +51,10 @@ impl Connection { |
6 | /// Return the post filters of a mailing list. |
7 | pub fn list_filters(&self, _list: &DbVal<MailingList>) -> Vec<Box<dyn PostFilter>> { |
8 | vec![ |
9 | - Box::new(FixCRLF), |
10 | Box::new(PostRightsCheck), |
11 | + Box::new(FixCRLF), |
12 | Box::new(AddListHeaders), |
13 | + Box::new(AddSubjectTagPrefix), |
14 | Box::new(FinalizeRecipients), |
15 | ] |
16 | } |
17 | @@ -163,16 +164,6 @@ impl PostFilter for AddListHeaders { |
18 | let (mut headers, body) = melib::email::parser::mail(&post.bytes).unwrap(); |
19 | let sender = format!("<{}>", ctx.list.address); |
20 | headers.push((&b"Sender"[..], sender.as_bytes())); |
21 | - let mut subject = format!("[{}] ", ctx.list.id).into_bytes(); |
22 | - if let Some((_, subj_val)) = headers |
23 | - .iter_mut() |
24 | - .find(|(k, _)| k.eq_ignore_ascii_case(b"Subject")) |
25 | - { |
26 | - subject.extend(subj_val.iter().cloned()); |
27 | - *subj_val = subject.as_slice(); |
28 | - } else { |
29 | - headers.push((&b"Subject"[..], subject.as_slice())); |
30 | - } |
31 | |
32 | let list_id = Some(ctx.list.id_header()); |
33 | let list_help = ctx.list.help_header(); |
34 | @@ -220,6 +211,51 @@ impl PostFilter for AddListHeaders { |
35 | } |
36 | } |
37 | |
38 | + /// Add List ID prefix in Subject header (e.g. `[list-id] ...`) |
39 | + pub struct AddSubjectTagPrefix; |
40 | + impl PostFilter for AddSubjectTagPrefix { |
41 | + fn feed<'p, 'list>( |
42 | + self: Box<Self>, |
43 | + post: &'p mut PostEntry, |
44 | + ctx: &'p mut ListContext<'list>, |
45 | + ) -> std::result::Result<(&'p mut PostEntry, &'p mut ListContext<'list>), ()> { |
46 | + trace!("Running AddSubjectTagPrefix filter"); |
47 | + let (mut headers, body) = melib::email::parser::mail(&post.bytes).unwrap(); |
48 | + let mut subject; |
49 | + if let Some((_, subj_val)) = headers |
50 | + .iter_mut() |
51 | + .find(|(k, _)| k.eq_ignore_ascii_case(b"Subject")) |
52 | + { |
53 | + subject = format!("[{}] ", ctx.list.id).into_bytes(); |
54 | + subject.extend(subj_val.iter().cloned()); |
55 | + *subj_val = subject.as_slice(); |
56 | + } else { |
57 | + subject = format!("[{}] (no subject)", ctx.list.id).into_bytes(); |
58 | + headers.push((&b"Subject"[..], subject.as_slice())); |
59 | + } |
60 | + |
61 | + let mut new_vec = Vec::with_capacity( |
62 | + headers |
63 | + .iter() |
64 | + .map(|(h, v)| h.len() + v.len() + ": \r\n".len()) |
65 | + .sum::<usize>() |
66 | + + "\r\n\r\n".len() |
67 | + + body.len(), |
68 | + ); |
69 | + for (h, v) in headers { |
70 | + new_vec.extend_from_slice(h); |
71 | + new_vec.extend_from_slice(b": "); |
72 | + new_vec.extend_from_slice(v); |
73 | + new_vec.extend_from_slice(b"\r\n"); |
74 | + } |
75 | + new_vec.extend_from_slice(b"\r\n\r\n"); |
76 | + new_vec.extend_from_slice(body); |
77 | + |
78 | + post.bytes = new_vec; |
79 | + Ok((post, ctx)) |
80 | + } |
81 | + } |
82 | + |
83 | /// Adds `Archived-At` field, if configured. |
84 | pub struct ArchivedAtLink; |
85 | impl PostFilter for ArchivedAtLink { |