cull_gmail/
rule_processor.rs1use google_gmail1::api::{BatchDeleteMessagesRequest, BatchModifyMessagesRequest};
2
3use crate::{EolAction, Error, GmailClient, Result, message_list::MessageList, rules::EolRule};
4
5pub trait RuleProcessor {
7 fn find_rule_and_messages_for_label(
9 &mut self,
10 label: &str,
11 ) -> impl std::future::Future<Output = Result<()>> + Send;
12 fn set_execute(&mut self, value: bool);
14 fn set_rule(&mut self, action: EolRule);
16 fn action(&self) -> Option<EolAction>;
18 fn prepare(&mut self, pages: u32) -> impl std::future::Future<Output = Result<()>> + Send;
20 fn batch_delete(&self) -> impl std::future::Future<Output = Result<()>> + Send;
22 fn batch_trash(&self) -> impl std::future::Future<Output = Result<()>> + Send;
24}
25
26impl RuleProcessor for GmailClient {
27 fn set_rule(&mut self, value: EolRule) {
29 self.rule = Some(value);
30 }
31
32 fn set_execute(&mut self, value: bool) {
34 self.execute = value;
35 }
36
37 fn action(&self) -> Option<EolAction> {
39 if let Some(rule) = &self.rule {
40 return rule.action();
41 }
42 None
43 }
44
45 async fn find_rule_and_messages_for_label(&mut self, label: &str) -> Result<()> {
47 self.add_labels(&[label.to_string()])?;
48
49 if self.label_ids().is_empty() {
50 return Err(Error::LabelNotFoundInMailbox(label.to_string()));
51 }
52
53 let Some(rule) = &self.rule else {
54 return Err(Error::RuleNotFound(0));
55 };
56
57 let Some(query) = rule.eol_query() else {
58 return Err(Error::NoQueryStringCalculated(rule.id()));
59 };
60 self.set_query(&query);
61
62 log::info!("{:?}", self.messages());
63 log::info!("Ready to run");
64 self.prepare(0).await?;
65 if self.execute {
66 log::info!("***executing final delete messages***");
67 self.batch_trash().await
68 } else {
69 log::warn!("Execution stopped for dry run");
70 Ok(())
71 }
72 }
73
74 async fn prepare(&mut self, pages: u32) -> Result<()> {
76 self.get_messages(pages).await
77 }
78
79 async fn batch_delete(&self) -> Result<()> {
81 let ids = Some(self.message_ids());
82
83 let batch_request = BatchDeleteMessagesRequest { ids };
84
85 log::trace!("{batch_request:#?}");
86
87 let _res = self
88 .hub()
89 .users()
90 .messages_batch_delete(batch_request, "me")
91 .add_scope("https://mail.google.com/")
92 .doit()
93 .await
94 .map_err(Box::new)?;
95
96 for m in self.messages() {
97 log::info!("Message with subject `{}` deleted.", m.subject());
98 }
99
100 Ok(())
101 }
102 async fn batch_trash(&self) -> Result<()> {
104 let add_label_ids = Some(Vec::from(["TRASH".to_string()]));
105 let ids = Some(self.message_ids());
106 let remove_label_ids = Some(self.label_ids());
107
108 let batch_request = BatchModifyMessagesRequest {
109 add_label_ids,
110 ids,
111 remove_label_ids,
112 };
113
114 log::trace!("{batch_request:#?}");
115
116 let _res = self
117 .hub()
118 .users()
119 .messages_batch_modify(batch_request, "me")
120 .add_scope("https://www.google.com/")
121 .doit()
122 .await
123 .map_err(Box::new)?;
124
125 for m in self.messages() {
126 log::info!("Message with subject `{}` moved to trash.", m.subject());
127 }
128
129 Ok(())
130 }
131}