1pub mod config;
2mod error;
3
4use std::sync::Arc;
5
6use async_trait::async_trait;
7use tracing::info;
8
9use self::config::SendmailConfig;
10#[doc(inline)]
11pub use self::error::{Error, Result};
12use crate::{
13 account::config::AccountConfig,
14 backend::{
15 context::{BackendContext, BackendContextBuilder},
16 feature::{BackendFeature, CheckUp},
17 },
18 message::send::{sendmail::SendSendmailMessage, SendMessage},
19 AnyResult,
20};
21
22#[derive(Clone, Debug, Default, Eq, PartialEq)]
23pub struct SendmailContext {
24 pub account_config: Arc<AccountConfig>,
25 pub sendmail_config: Arc<SendmailConfig>,
26}
27
28impl SendmailContext {
29 pub fn new(account_config: Arc<AccountConfig>, sendmail_config: Arc<SendmailConfig>) -> Self {
30 Self {
31 account_config,
32 sendmail_config,
33 }
34 }
35}
36
37pub type SendmailContextSync = SendmailContext;
38
39impl BackendContext for SendmailContextSync {}
40
41#[derive(Clone, Debug, Default, Eq, PartialEq)]
42pub struct SendmailContextBuilder {
43 pub account_config: Arc<AccountConfig>,
45
46 pub sendmail_config: Arc<SendmailConfig>,
48}
49
50impl SendmailContextBuilder {
51 pub fn new(account_config: Arc<AccountConfig>, sendmail_config: Arc<SendmailConfig>) -> Self {
52 Self {
53 account_config,
54 sendmail_config,
55 }
56 }
57}
58
59#[async_trait]
60impl BackendContextBuilder for SendmailContextBuilder {
61 type Context = SendmailContextSync;
62
63 fn check_up(&self) -> Option<BackendFeature<Self::Context, dyn CheckUp>> {
64 Some(Arc::new(CheckUpSendmail::some_new_boxed))
65 }
66
67 fn send_message(&self) -> Option<BackendFeature<Self::Context, dyn SendMessage>> {
68 Some(Arc::new(SendSendmailMessage::some_new_boxed))
69 }
70
71 async fn build(self) -> AnyResult<Self::Context> {
77 info!("building new sendmail context");
78
79 Ok(SendmailContextSync {
80 account_config: self.account_config,
81 sendmail_config: self.sendmail_config,
82 })
83 }
84}
85
86#[derive(Clone)]
87pub struct CheckUpSendmail {
88 pub ctx: SendmailContextSync,
89}
90
91impl CheckUpSendmail {
92 pub fn new(ctx: &SendmailContext) -> Self {
93 Self { ctx: ctx.clone() }
94 }
95
96 pub fn new_boxed(ctx: &SendmailContext) -> Box<dyn CheckUp> {
97 Box::new(Self::new(ctx))
98 }
99
100 pub fn some_new_boxed(ctx: &SendmailContext) -> Option<Box<dyn CheckUp>> {
101 Some(Self::new_boxed(ctx))
102 }
103}
104
105#[async_trait]
106impl CheckUp for CheckUpSendmail {
107 async fn check_up(&self) -> AnyResult<()> {
108 self.ctx
109 .sendmail_config
110 .cmd()
111 .run()
112 .await
113 .map_err(Error::ExecuteCommandError)?;
114 Ok(())
115 }
116}