mirror of
https://github.com/soywod/himalaya.git
synced 2024-07-08 10:35:13 +00:00
make smtp service lazy with instance()
This commit is contained in:
parent
979c6ef1c9
commit
07833c2fc7
68
src/domain/smtp.rs
Normal file
68
src/domain/smtp.rs
Normal file
|
@ -0,0 +1,68 @@
|
|||
use anyhow::Result;
|
||||
use lettre::{
|
||||
self,
|
||||
transport::smtp::{
|
||||
client::{Tls, TlsParameters},
|
||||
SmtpTransport,
|
||||
},
|
||||
Transport,
|
||||
};
|
||||
|
||||
use crate::domain::account::entity::Account;
|
||||
|
||||
pub trait SmtpServiceInterface {
|
||||
fn send(&mut self, msg: &lettre::Message) -> Result<()>;
|
||||
}
|
||||
|
||||
pub struct SmtpService<'a> {
|
||||
account: &'a Account,
|
||||
transport: Option<SmtpTransport>,
|
||||
}
|
||||
|
||||
impl<'a> SmtpService<'a> {
|
||||
pub fn new(account: &'a Account) -> Result<Self> {
|
||||
Ok(Self {
|
||||
account,
|
||||
transport: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn transport(&mut self) -> Result<&SmtpTransport> {
|
||||
if let Some(ref transport) = self.transport {
|
||||
Ok(transport)
|
||||
} else {
|
||||
let builder = if self.account.smtp_starttls {
|
||||
SmtpTransport::starttls_relay(&self.account.smtp_host)
|
||||
} else {
|
||||
SmtpTransport::relay(&self.account.smtp_host)
|
||||
}?;
|
||||
|
||||
let tls = TlsParameters::builder(self.account.smtp_host.to_owned())
|
||||
.dangerous_accept_invalid_hostnames(self.account.smtp_insecure)
|
||||
.dangerous_accept_invalid_certs(self.account.smtp_insecure)
|
||||
.build()?;
|
||||
let tls = if self.account.smtp_starttls {
|
||||
Tls::Required(tls)
|
||||
} else {
|
||||
Tls::Wrapper(tls)
|
||||
};
|
||||
|
||||
self.transport = Some(
|
||||
builder
|
||||
.tls(tls)
|
||||
.port(self.account.smtp_port)
|
||||
.credentials(self.account.smtp_creds()?)
|
||||
.build(),
|
||||
);
|
||||
|
||||
Ok(self.transport.as_ref().unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SmtpServiceInterface for SmtpService<'a> {
|
||||
fn send(&mut self, msg: &lettre::Message) -> Result<()> {
|
||||
self.transport()?.send(msg)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
//! Modules related to SMTP.
|
||||
|
||||
pub mod service;
|
|
@ -1,51 +0,0 @@
|
|||
use anyhow::Result;
|
||||
use lettre::{
|
||||
self,
|
||||
transport::{smtp::client::Tls, smtp::client::TlsParameters, smtp::SmtpTransport},
|
||||
Transport,
|
||||
};
|
||||
|
||||
use crate::domain::account::entity::Account;
|
||||
|
||||
pub trait SMTPServiceInterface {
|
||||
fn send(&self, msg: &lettre::Message) -> Result<()>;
|
||||
}
|
||||
|
||||
pub struct SMTPService<'a> {
|
||||
account: &'a Account,
|
||||
}
|
||||
|
||||
impl<'a> SMTPService<'a> {
|
||||
pub fn new(account: &'a Account) -> Result<Self> {
|
||||
Ok(Self { account })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SMTPServiceInterface for SMTPService<'a> {
|
||||
fn send(&self, msg: &lettre::Message) -> Result<()> {
|
||||
let smtp_relay = if self.account.smtp_starttls {
|
||||
SmtpTransport::starttls_relay
|
||||
} else {
|
||||
SmtpTransport::relay
|
||||
};
|
||||
|
||||
let tls = TlsParameters::builder(self.account.smtp_host.to_string())
|
||||
.dangerous_accept_invalid_hostnames(self.account.smtp_insecure)
|
||||
.dangerous_accept_invalid_certs(self.account.smtp_insecure)
|
||||
.build()?;
|
||||
let tls = if self.account.smtp_starttls {
|
||||
Tls::Required(tls)
|
||||
} else {
|
||||
Tls::Wrapper(tls)
|
||||
};
|
||||
|
||||
smtp_relay(&self.account.smtp_host)?
|
||||
.port(self.account.smtp_port)
|
||||
.tls(tls)
|
||||
.credentials(self.account.smtp_creds()?)
|
||||
.build()
|
||||
.send(msg)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -43,4 +43,5 @@ pub mod msg;
|
|||
pub mod output;
|
||||
|
||||
pub mod domain;
|
||||
pub mod infra;
|
||||
pub mod ui;
|
||||
|
|
|
@ -8,7 +8,7 @@ use himalaya::{
|
|||
comp,
|
||||
config::cli::config_args,
|
||||
ctx::Ctx,
|
||||
domain::{account::entity::Account, config::entity::Config, smtp::service::SMTPService},
|
||||
domain::{account::entity::Account, config::entity::Config, smtp::SmtpService},
|
||||
flag, imap, mbox, msg,
|
||||
output::{cli::output_args, model::Output},
|
||||
};
|
||||
|
@ -73,7 +73,7 @@ fn main() -> Result<()> {
|
|||
|
||||
let account_name = arg_matches.value_of("account");
|
||||
let account = Account::try_from((&config, account_name))?;
|
||||
let smtp_service = SMTPService::new(&account)?;
|
||||
let smtp_service = SmtpService::new(&account)?;
|
||||
debug!("account name: {}", account_name.unwrap_or("default"));
|
||||
trace!("account: {:?}", account);
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ use super::{
|
|||
};
|
||||
use crate::{
|
||||
ctx::Ctx,
|
||||
domain::{account::entity::Account, smtp},
|
||||
domain::{account::entity::Account, smtp::*},
|
||||
flag::model::Flags,
|
||||
imap::model::ImapConnector,
|
||||
input,
|
||||
|
@ -127,10 +127,10 @@ pub fn subcmds<'a>() -> Vec<clap::App<'a, 'a>> {
|
|||
]
|
||||
}
|
||||
|
||||
pub fn matches<SMTP: smtp::service::SMTPServiceInterface>(
|
||||
pub fn matches<SmtpService: SmtpServiceInterface>(
|
||||
ctx: &Ctx,
|
||||
account: &Account,
|
||||
smtp: SMTP,
|
||||
smtp: SmtpService,
|
||||
) -> Result<bool> {
|
||||
match ctx.arg_matches.subcommand() {
|
||||
("attachments", Some(matches)) => msg_matches_attachments(&ctx, &account, &matches),
|
||||
|
@ -399,11 +399,11 @@ fn msg_matches_attachments(
|
|||
Ok(true)
|
||||
}
|
||||
|
||||
fn msg_matches_write<'a, SMTP: smtp::service::SMTPServiceInterface>(
|
||||
fn msg_matches_write<SmtpService: SmtpServiceInterface>(
|
||||
ctx: &Ctx,
|
||||
account: &Account,
|
||||
matches: &clap::ArgMatches,
|
||||
smtp: SMTP,
|
||||
smtp: SmtpService,
|
||||
) -> Result<bool> {
|
||||
debug!("write command matched");
|
||||
|
||||
|
@ -438,11 +438,11 @@ fn msg_matches_write<'a, SMTP: smtp::service::SMTPServiceInterface>(
|
|||
Ok(true)
|
||||
}
|
||||
|
||||
fn msg_matches_reply<'a, SMTP: smtp::service::SMTPServiceInterface>(
|
||||
fn msg_matches_reply<SmtpService: SmtpServiceInterface>(
|
||||
ctx: &Ctx,
|
||||
account: &Account,
|
||||
matches: &clap::ArgMatches,
|
||||
smtp: SMTP,
|
||||
smtp: SmtpService,
|
||||
) -> Result<bool> {
|
||||
debug!("reply command matched");
|
||||
|
||||
|
@ -473,11 +473,11 @@ fn msg_matches_reply<'a, SMTP: smtp::service::SMTPServiceInterface>(
|
|||
Ok(true)
|
||||
}
|
||||
|
||||
pub fn msg_matches_mailto<'a, SMTP: smtp::service::SMTPServiceInterface>(
|
||||
pub fn msg_matches_mailto<SmtpService: SmtpServiceInterface>(
|
||||
ctx: &Ctx,
|
||||
account: &Account,
|
||||
url: &Url,
|
||||
smtp: SMTP,
|
||||
smtp: SmtpService,
|
||||
) -> Result<()> {
|
||||
debug!("mailto command matched");
|
||||
|
||||
|
@ -525,11 +525,11 @@ pub fn msg_matches_mailto<'a, SMTP: smtp::service::SMTPServiceInterface>(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn msg_matches_forward<'a, SMTP: smtp::service::SMTPServiceInterface>(
|
||||
fn msg_matches_forward<SmtpService: SmtpServiceInterface>(
|
||||
ctx: &Ctx,
|
||||
account: &Account,
|
||||
matches: &clap::ArgMatches,
|
||||
smtp: SMTP,
|
||||
smtp: SmtpService,
|
||||
) -> Result<bool> {
|
||||
debug!("forward command matched");
|
||||
|
||||
|
@ -639,11 +639,11 @@ fn msg_matches_delete(ctx: &Ctx, account: &Account, matches: &clap::ArgMatches)
|
|||
Ok(true)
|
||||
}
|
||||
|
||||
fn msg_matches_send<'a, SMTP: smtp::service::SMTPServiceInterface>(
|
||||
fn msg_matches_send<SmtpService: SmtpServiceInterface>(
|
||||
ctx: &Ctx,
|
||||
account: &Account,
|
||||
matches: &clap::ArgMatches,
|
||||
smtp: SMTP,
|
||||
mut smtp: SmtpService,
|
||||
) -> Result<bool> {
|
||||
debug!("send command matched");
|
||||
|
||||
|
@ -849,11 +849,11 @@ fn tpl_matches_forward(ctx: &Ctx, account: &Account, matches: &clap::ArgMatches)
|
|||
|
||||
/// This function opens the prompt to do some actions to the msg like sending, editing it again and
|
||||
/// so on.
|
||||
fn msg_interaction<SMTP: smtp::service::SMTPServiceInterface>(
|
||||
fn msg_interaction<SmtpService: SmtpServiceInterface>(
|
||||
ctx: &Ctx,
|
||||
msg: &mut Msg,
|
||||
imap_conn: &mut ImapConnector,
|
||||
smtp: SMTP,
|
||||
mut smtp: SmtpService,
|
||||
) -> Result<bool> {
|
||||
// let the user change the body a little bit first, before opening the prompt
|
||||
msg.edit_body()?;
|
||||
|
|
Loading…
Reference in a new issue