backend/objects/
mod.rs

1use lettre::{
2    AsyncSmtpTransport, AsyncTransport, Message as Email, Tokio1Executor,
3    message::{Mailbox, MessageBuilder as EmailBuilder},
4    transport::smtp::authentication::Credentials,
5};
6use log::debug;
7use serde::Deserialize;
8use uuid::Uuid;
9
10mod channel;
11mod email_token;
12mod friends;
13mod guild;
14mod invite;
15mod me;
16mod member;
17mod message;
18mod password_reset_token;
19mod role;
20mod user;
21
22pub use channel::Channel;
23pub use email_token::EmailToken;
24pub use friends::Friend;
25pub use friends::FriendRequest;
26pub use guild::Guild;
27pub use invite::Invite;
28pub use me::Me;
29pub use member::Member;
30pub use message::Message;
31pub use password_reset_token::PasswordResetToken;
32pub use role::Permissions;
33pub use role::Role;
34pub use user::User;
35
36use crate::error::Error;
37
38pub trait HasUuid {
39    fn uuid(&self) -> &Uuid;
40}
41
42pub trait HasIsAbove {
43    fn is_above(&self) -> Option<&Uuid>;
44}
45
46fn load_or_empty<T>(
47    query_result: Result<Vec<T>, diesel::result::Error>,
48) -> Result<Vec<T>, diesel::result::Error> {
49    match query_result {
50        Ok(vec) => Ok(vec),
51        Err(diesel::result::Error::NotFound) => Ok(Vec::new()),
52        Err(e) => Err(e),
53    }
54}
55
56#[derive(PartialEq, Eq, Clone)]
57pub enum MailTls {
58    StartTls,
59    Tls,
60}
61
62impl From<String> for MailTls {
63    fn from(value: String) -> Self {
64        match &*value.to_lowercase() {
65            "starttls" => Self::StartTls,
66            _ => Self::Tls,
67        }
68    }
69}
70
71#[derive(Clone)]
72pub struct MailClient {
73    creds: Credentials,
74    smtp_server: String,
75    mbox: Mailbox,
76    tls: MailTls,
77}
78
79impl MailClient {
80    pub fn new<T: Into<MailTls>>(
81        creds: Credentials,
82        smtp_server: String,
83        mbox: String,
84        tls: T,
85    ) -> Result<Self, Error> {
86        Ok(Self {
87            creds,
88            smtp_server,
89            mbox: mbox.parse()?,
90            tls: tls.into(),
91        })
92    }
93
94    pub fn message_builder(&self) -> EmailBuilder {
95        Email::builder().from(self.mbox.clone())
96    }
97
98    pub async fn send_mail(&self, email: Email) -> Result<(), Error> {
99        let mailer: AsyncSmtpTransport<Tokio1Executor> = match self.tls {
100            MailTls::StartTls => {
101                AsyncSmtpTransport::<Tokio1Executor>::starttls_relay(&self.smtp_server)?
102                    .credentials(self.creds.clone())
103                    .build()
104            }
105            MailTls::Tls => AsyncSmtpTransport::<Tokio1Executor>::relay(&self.smtp_server)?
106                .credentials(self.creds.clone())
107                .build(),
108        };
109
110        let response = mailer.send(email).await?;
111
112        debug!("mail sending response: {response:?}");
113
114        Ok(())
115    }
116}
117
118#[derive(Deserialize)]
119pub struct StartAmountQuery {
120    pub start: Option<i64>,
121    pub amount: Option<i64>,
122}