feat(account): add MailerType to support Gmail API and other mailers

- Introduced `MailerType` enum in Account model
- Enables selection of different mailer backends (e.g., Gmail API)
This commit is contained in:
rustmailer
2025-08-28 03:20:49 +08:00
parent a9ef330418
commit fd64acc24f
65 changed files with 971 additions and 639 deletions
+2 -2
View File
@@ -14,7 +14,7 @@ use serde::{Deserialize, Serialize};
use crate::{
encode_mailbox_name,
modules::{
account::entity::Account,
account::v2::AccountV2,
context::executors::RUST_MAIL_CONTEXT,
error::{code::ErrorCode, RustMailerResult},
smtp::request::{reply::apply_references, EmailHandler},
@@ -51,7 +51,7 @@ pub struct AppendReplyToDraftRequest {
impl AppendReplyToDraftRequest {
pub async fn append_reply_to_draft(&self, account_id: u64) -> RustMailerResult<()> {
let account = Account::check_account_active(account_id).await?;
let account = AccountV2::check_account_active(account_id).await?;
let envelope = EmailHandler::get_envelope(&account, &self.mailbox_name, self.uid).await?;
let from = Address::new_address(
account.name.as_ref().map(|n| Cow::Owned(n.to_string())),
+2 -2
View File
@@ -6,7 +6,7 @@ use crate::modules::error::code::ErrorCode;
use crate::modules::message::get_minimal_meta;
use crate::{
encode_mailbox_name,
modules::account::entity::Account,
modules::account::v2::AccountV2,
modules::cache::disk::DISK_CACHE,
modules::context::executors::RUST_MAIL_CONTEXT,
modules::error::RustMailerResult,
@@ -59,7 +59,7 @@ pub async fn retrieve_email_attachment(
account_id: u64,
request: AttachmentRequest,
) -> RustMailerResult<cacache::Reader> {
Account::check_account_active(account_id).await?;
AccountV2::check_account_active(account_id).await?;
if request.attachment.size >= MAX_ATTACHMENT_SIZE {
return Err(raise_error!(
+2 -2
View File
@@ -2,13 +2,13 @@
// Licensed under RustMailer License Agreement v1.0
// Unauthorized copying, modification, or distribution is prohibited.
use crate::modules::account::v2::AccountV2;
use crate::modules::error::code::ErrorCode;
use crate::modules::imap::section::Encoding;
use crate::modules::message::attachment::inline_attachment_diskcache_key;
use crate::{
encode_mailbox_name,
modules::{
account::entity::Account,
cache::disk::DISK_CACHE,
context::executors::RUST_MAIL_CONTEXT,
error::RustMailerResult,
@@ -283,7 +283,7 @@ pub async fn retrieve_email_content(
request: MessageContentRequest,
skip_cache: bool,
) -> RustMailerResult<MessageContent> {
Account::check_account_active(account_id).await?;
AccountV2::check_account_active(account_id).await?;
let mut plain: Option<PlainText> = None;
let mut html: Option<String> = None;
+2 -2
View File
@@ -3,7 +3,7 @@
// Unauthorized copying, modification, or distribution is prohibited.
use crate::{
encode_mailbox_name, modules::account::entity::Account,
encode_mailbox_name, modules::account::v2::AccountV2,
modules::context::executors::RUST_MAIL_CONTEXT, modules::envelope::generate_uid_set,
modules::error::RustMailerResult,
};
@@ -33,7 +33,7 @@ pub async fn copy_mailbox_messages(
payload: &MailboxTransferRequest,
) -> RustMailerResult<()> {
// Ensure the account exists before proceeding
Account::check_account_active(account_id).await?;
AccountV2::check_account_active(account_id).await?;
// Generate a set of UIDs from the payload
let uid_set = generate_uid_set(payload.uids.clone());
+2 -2
View File
@@ -3,7 +3,7 @@
// Unauthorized copying, modification, or distribution is prohibited.
use crate::encode_mailbox_name;
use crate::modules::account::entity::Account;
use crate::modules::account::v2::AccountV2;
use crate::modules::cache::imap::mailbox::{AttributeEnum, MailBox};
use crate::modules::context::executors::RUST_MAIL_CONTEXT;
use crate::modules::{envelope::generate_uid_set, error::RustMailerResult};
@@ -25,7 +25,7 @@ pub async fn move_to_trash_or_delete_messages_directly(
account_id: u64,
request: &MessageDeleteRequest,
) -> RustMailerResult<()> {
Account::check_account_active(account_id).await?;
AccountV2::check_account_active(account_id).await?;
let uid_set = generate_uid_set(request.uids.clone());
let executor = RUST_MAIL_CONTEXT.imap(account_id).await?;
+2 -2
View File
@@ -4,7 +4,7 @@
use crate::{
modules::{
account::entity::Account,
account::v2::AccountV2,
cache::imap::mailbox::EnvelopeFlag,
context::executors::RUST_MAIL_CONTEXT,
envelope::generate_uid_set,
@@ -81,7 +81,7 @@ impl FlagAction {
}
pub async fn modify_flags(account_id: u64, request: FlagMessageRequest) -> RustMailerResult<()> {
Account::check_account_active(account_id).await?;
AccountV2::check_account_active(account_id).await?;
request.validate()?;
let executor = RUST_MAIL_CONTEXT.imap(account_id).await?;
+2 -2
View File
@@ -4,7 +4,7 @@
use crate::{
modules::{
account::entity::Account,
account::v2::AccountV2,
cache::disk::DISK_CACHE,
context::executors::RUST_MAIL_CONTEXT,
error::{code::ErrorCode, RustMailerResult},
@@ -35,7 +35,7 @@ pub async fn retrieve_full_email(
mailbox: String,
uid: u32,
) -> RustMailerResult<cacache::Reader> {
Account::check_account_active(account_id).await?;
AccountV2::check_account_active(account_id).await?;
let meta = get_minimal_meta(account_id, &mailbox, uid).await?;
if meta.size > MAX_EMAIL_TOTAL_SIZE {
return Err(raise_error!(format!(
+9 -9
View File
@@ -5,8 +5,8 @@
use crate::{
encode_mailbox_name,
modules::{
account::entity::Account,
cache::imap::{envelope_v2::EmailEnvelopeV2, mailbox::MailBox, thread::EmailThread},
account::v2::AccountV2,
cache::imap::{mailbox::MailBox, thread::EmailThread, v2::EmailEnvelopeV2},
context::executors::RUST_MAIL_CONTEXT,
envelope::extractor::extract_envelope,
error::{code::ErrorCode, RustMailerResult},
@@ -24,9 +24,9 @@ pub async fn list_messages_in_mailbox(
remote: bool,
desc: bool,
) -> RustMailerResult<DataPage<EmailEnvelopeV2>> {
let account = Account::check_account_active(account_id).await?;
let account = AccountV2::check_account_active(account_id).await?;
validate_pagination_params(page, page_size)?;
let remote = remote || account.minimal_sync;
let remote = remote || account.minimal_sync();
if remote {
fetch_remote_messages(account_id, mailbox_name, page, page_size, desc).await
@@ -99,7 +99,7 @@ async fn process_fetches(
}
async fn fetch_local_messages(
account: &Account,
account: &AccountV2,
mailbox_name: &str,
page: u64,
page_size: u64,
@@ -125,9 +125,9 @@ pub async fn list_threads_in_mailbox(
page_size: u64,
desc: bool,
) -> RustMailerResult<DataPage<EmailEnvelopeV2>> {
let account = Account::check_account_active(account_id).await?;
let account = AccountV2::check_account_active(account_id).await?;
validate_pagination_params(page, page_size)?;
if account.minimal_sync {
if account.minimal_sync() {
return Err(raise_error!(
format!(
"Account {} is in minimal sync mode. Listing threads in a mailbox is not supported. \
@@ -160,8 +160,8 @@ pub async fn get_thread_messages(
mailbox_name: &str,
thread_id: u64,
) -> RustMailerResult<Vec<EmailEnvelopeV2>> {
let account = Account::check_account_active(account_id).await?;
if account.minimal_sync {
let account = AccountV2::check_account_active(account_id).await?;
if account.minimal_sync() {
return Err(raise_error!(
format!(
"Account {} is in minimal sync mode. Listing threads in a mailbox is not supported. \
+2 -2
View File
@@ -4,7 +4,7 @@
use crate::modules::message::copy::MailboxTransferRequest;
use crate::{
encode_mailbox_name, modules::account::entity::Account,
encode_mailbox_name, modules::account::v2::AccountV2,
modules::context::executors::RUST_MAIL_CONTEXT, modules::envelope::generate_uid_set,
modules::error::RustMailerResult,
};
@@ -14,7 +14,7 @@ pub async fn move_mailbox_messages(
payload: &MailboxTransferRequest,
) -> RustMailerResult<()> {
// Ensure the account exists before proceeding
Account::check_account_active(account_id).await?;
AccountV2::check_account_active(account_id).await?;
// Generate a set of UIDs from the payload
let uid_set = generate_uid_set(payload.uids.clone());
+4 -4
View File
@@ -3,8 +3,8 @@
// Unauthorized copying, modification, or distribution is prohibited.
use crate::modules::cache::imap::address::AddressEntity;
use crate::modules::cache::imap::envelope_v2::EmailEnvelopeV2;
use crate::modules::cache::imap::sync::flow::generate_uid_sequence_hashset;
use crate::modules::cache::imap::v2::EmailEnvelopeV2;
use crate::modules::common::paginated::paginate_vec;
use crate::modules::database::Paginated;
use crate::modules::error::code::ErrorCode;
@@ -12,7 +12,7 @@ use crate::modules::message::search::cache::IMAP_SEARCH_CACHE;
use crate::{
encode_mailbox_name,
modules::{
account::entity::Account, context::executors::RUST_MAIL_CONTEXT,
account::v2::AccountV2, context::executors::RUST_MAIL_CONTEXT,
envelope::extractor::extract_envelope, error::RustMailerResult, rest::response::DataPage,
},
raise_error,
@@ -437,13 +437,13 @@ impl MessageSearchRequest {
page_size: u64,
desc: bool,
) -> RustMailerResult<DataPage<EmailEnvelopeV2>> {
let account = Account::check_account_active(account_id).await?;
let account = AccountV2::check_account_active(account_id).await?;
self.search_remote(&account, page, page_size, desc).await
}
async fn search_remote(
&self,
account: &Account,
account: &AccountV2,
page: u64,
page_size: u64,
desc: bool,