From 4eea2c6135108f757eb20150468d0fc216237a70 Mon Sep 17 00:00:00 2001 From: Jeremiah Russell Date: Mon, 13 Oct 2025 17:21:39 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(processor):=20imp?= =?UTF-8?q?lement=20RuleProcessor=20trait=20for=20GmailClient?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - move rule processing logic into the GmailClient struct - implement RuleProcessor trait for GmailClient to handle trash and delete actions - add set_rule method to set the rule for processing - update trash_messages and delete_messages to use the GmailClient's internal state --- src/processor.rs | 190 +++++++++++++++++++++++++++-------------------- 1 file changed, 110 insertions(+), 80 deletions(-) diff --git a/src/processor.rs b/src/processor.rs index bfc0ca5..6292d1b 100644 --- a/src/processor.rs +++ b/src/processor.rs @@ -1,97 +1,123 @@ -// use crate::EolRule; - -use std::fmt; - use crate::{ EolAction, Error, GmailClient, Result, config::EolRule, delete::Delete, message_list::MessageList, trash::Trash, }; -/// Rule processor -#[derive()] -pub struct Processor<'a> { - client: GmailClient, - rule: &'a EolRule, - execute: bool, +// /// Rule processor +// #[derive()] +// pub struct Processor<'a> { +// client: GmailClient, +// rule: &'a EolRule, +// execute: bool, +// } + +// impl<'a> fmt::Debug for Processor<'a> { +// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +// f.debug_struct("Processor") +// .field("rule", &self.rule) +// .field("execute", &self.execute) +// .finish() +// } +// } + +// /// Rule processor builder +// #[derive()] +// pub struct ProcessorBuilder<'a> { +// client: GmailClient, +// rule: &'a EolRule, +// execute: bool, +// } + +// impl<'a> fmt::Debug for ProcessorBuilder<'a> { +// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +// f.debug_struct("ProcessorBuilder") +// .field("rule", &self.rule) +// .field("execute", &self.execute) +// .finish() +// } +// } + +// impl<'a> ProcessorBuilder<'a> { +// /// Set the execute flag +// pub fn set_execute(&mut self, value: bool) -> &mut Self { +// self.execute = value; +// self +// } + +// /// Build the Processor +// pub fn build(&'_ self) -> Processor<'_> { +// Processor { +// client: self.client.clone(), +// rule: self.rule, +// execute: self.execute, +// } +// } +// } + +/// Rules processor to apply the configured rules to the mailbox. +pub trait RuleProcessor { + /// Delete messages + fn delete_messages( + &mut self, + label: &str, + ) -> impl std::future::Future> + Send; + /// Trash Messages + fn trash_messages( + &mut self, + label: &str, + ) -> impl std::future::Future> + Send; + /// Set rule to process + fn set_rule(&mut self, action: EolRule); + /// Report the action from the rule + fn action(&self) -> Option; } -impl<'a> fmt::Debug for Processor<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Processor") - .field("rule", &self.rule) - .field("execute", &self.execute) - .finish() - } -} +impl RuleProcessor for GmailClient { + // /// Initialise a new processor + // pub fn builder(client: &GmailClient, rule: &'a EolRule) -> ProcessorBuilder<'a> { + // ProcessorBuilder { + // client: client.clone(), + // rule, + // execute: false, + // } + // } -/// Rule processor builder -#[derive()] -pub struct ProcessorBuilder<'a> { - client: GmailClient, - rule: &'a EolRule, - execute: bool, -} - -impl<'a> fmt::Debug for ProcessorBuilder<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("ProcessorBuilder") - .field("rule", &self.rule) - .field("execute", &self.execute) - .finish() - } -} - -impl<'a> ProcessorBuilder<'a> { - /// Set the execute flag - pub fn set_execute(&mut self, value: bool) -> &mut Self { - self.execute = value; - self - } - - /// Build the Processor - pub fn build(&'_ self) -> Processor<'_> { - Processor { - client: self.client.clone(), - rule: self.rule, - execute: self.execute, - } - } -} - -impl<'a> Processor<'a> { - /// Initialise a new processor - pub fn builder(client: &GmailClient, rule: &'a EolRule) -> ProcessorBuilder<'a> { - ProcessorBuilder { - client: client.clone(), - rule, - execute: false, - } + /// Add Action to the Client for processing + fn set_rule(&mut self, rule: EolRule) { + self.rule = Some(rule); } /// The action set in the rule - pub fn action(&self) -> Option { - self.rule.action() + fn action(&self) -> Option { + if let Some(rule) = &self.rule { + return rule.action(); + } + None } /// Trash the messages - pub async fn trash_messages(&mut self, label: &str) -> Result<()> { - self.client.add_labels(&[label.to_string()]).await?; + async fn trash_messages(&mut self, label: &str) -> Result<()> { + self.add_labels(&[label.to_string()]).await?; - if self.client.label_ids().is_empty() { + if self.label_ids().is_empty() { return Err(Error::LabelNotFoundInMailbox(label.to_string())); } - let Some(query) = self.rule.eol_query() else { - return Err(Error::NoQueryStringCalculated(self.rule.id())); + let Some(rule) = &self.rule else { + return Err(Error::RuleNotFound(0)); }; - self.client.set_query(&query); - log::info!("{:?}", self.client.messages()); + let Some(query) = rule.eol_query() else { + return Err(Error::NoQueryStringCalculated(rule.id())); + }; + self.set_query(&query); + + log::info!("{:?}", self.messages()); log::info!("Ready to run"); - self.client.prepare(0).await?; + self.prepare(0).await?; if self.execute { log::info!("***executing final delete messages***"); - self.client.batch_trash().await + self.batch_trash().await } else { log::warn!("Execution stopped for dry run"); Ok(()) @@ -99,24 +125,28 @@ impl<'a> Processor<'a> { } /// Delete the messages - pub async fn delete_messages(&mut self, label: &str) -> Result<()> { - self.client.add_labels(&[label.to_string()]).await?; + async fn delete_messages(&mut self, label: &str) -> Result<()> { + self.add_labels(&[label.to_string()]).await?; - if self.client.label_ids().is_empty() { + if self.label_ids().is_empty() { return Err(Error::LabelNotFoundInMailbox(label.to_string())); } - let Some(query) = self.rule.eol_query() else { - return Err(Error::NoQueryStringCalculated(self.rule.id())); + let Some(rule) = &self.rule else { + return Err(Error::RuleNotFound(0)); }; - self.client.set_query(&query); - log::info!("{:?}", self.client.messages()); + let Some(query) = rule.eol_query() else { + return Err(Error::NoQueryStringCalculated(rule.id())); + }; + self.set_query(&query); + + log::info!("{:?}", self.messages()); log::info!("Ready to run"); - self.client.prepare(0).await?; + self.prepare(0).await?; if self.execute { log::info!("***executing final delete messages***"); - self.client.batch_delete().await + self.batch_delete().await } else { log::warn!("Execution stopped for dry run");