feat: send_mail

This commit is contained in:
Ahmet Kaan GÜMÜŞ 2024-12-18 04:53:14 +03:00
parent b3b93ab0cc
commit 032a19931d
5 changed files with 101 additions and 14 deletions

View file

@ -1,6 +1,7 @@
pub mod database;
pub mod error;
pub mod feature;
pub mod mail;
pub mod routing;
pub mod server;
pub mod utils;
@ -26,12 +27,12 @@ impl Default for DatabaseConfig {
if header == "[database_config]" {
Self {
connection_pool_size: database_configs.pop().unwrap().parse().unwrap(),
backend: database_configs.pop().unwrap(),
database: database_configs.pop().unwrap(),
password: database_configs.pop().unwrap(),
username: database_configs.pop().unwrap(),
address: database_configs.pop().unwrap(),
address: database_configs.pop_front().unwrap().parse().unwrap(),
username: database_configs.pop_front().unwrap().parse().unwrap(),
password: database_configs.pop_front().unwrap().parse().unwrap(),
database: database_configs.pop_front().unwrap().parse().unwrap(),
backend: database_configs.pop_front().unwrap().parse().unwrap(),
connection_pool_size: database_configs.pop_front().unwrap().parse().unwrap(),
}
} else {
panic!("Database Config File Must Include [database_config] at the First Line")
@ -50,7 +51,7 @@ impl Default for ServerConfig {
if header == "[server_config]" {
Self {
address: server_configs.pop().unwrap(),
address: server_configs.pop_front().unwrap().parse().unwrap(),
}
} else {
panic!("Server Config File Must Include [server_config] at the First Line")

77
src/mail.rs Normal file
View file

@ -0,0 +1,77 @@
use lettre::{
message::header::ContentType,
transport::smtp::{self, authentication::Credentials},
AsyncSmtpTransport, AsyncTransport, Message, Tokio1Executor,
};
use crate::utils::naive_toml_parser;
const MAIL_CONFIG_FILE_LOCATION: &str = "./configs/mail_config.toml";
pub struct MailConfig {
name: String,
mail_address: String,
username: String,
password: String,
relay_server: String,
port: u16,
starttls: bool,
}
impl Default for MailConfig {
fn default() -> Self {
let (header, mut mail_configs) = naive_toml_parser(MAIL_CONFIG_FILE_LOCATION);
if header == "[mail_config]" {
Self {
name: mail_configs.pop_front().unwrap().parse().unwrap(),
mail_address: mail_configs.pop_front().unwrap().parse().unwrap(),
username: mail_configs.pop_front().unwrap().parse().unwrap(),
password: mail_configs.pop_front().unwrap().parse().unwrap(),
relay_server: mail_configs.pop_front().unwrap().parse().unwrap(),
port: mail_configs.pop_front().unwrap().parse().unwrap(),
starttls: mail_configs.pop_front().unwrap().parse().unwrap(),
}
} else {
panic!("Mail Config File Must Include [mail_config] at the First Line")
}
}
}
pub async fn send_mail(
receiver: &String,
subject: &String,
body: &String,
) -> Result<smtp::response::Response, smtp::Error> {
let mail_config = MailConfig::default();
let message = Message::builder()
.from(
format!("{} <{}>", mail_config.name, mail_config.mail_address)
.parse()
.unwrap(),
)
.to(format!("<{}>", receiver).parse().unwrap())
.subject(subject)
.header(ContentType::TEXT_PLAIN)
.body(body.to_owned())
.unwrap();
let credentials = Credentials::new(
mail_config.username.to_owned(),
mail_config.password.to_owned(),
);
let mailer = match mail_config.starttls {
true => AsyncSmtpTransport::<Tokio1Executor>::starttls_relay(&mail_config.relay_server),
false => AsyncSmtpTransport::<Tokio1Executor>::relay(&mail_config.relay_server),
};
let mailer = mailer
.unwrap()
.credentials(credentials)
.port(mail_config.port)
.build();
mailer.send(message).await
}

View file

@ -1,14 +1,14 @@
use std::{fs::File, io::Read};
use std::{collections::VecDeque, fs::File, io::Read};
use crate::error::ForumInputError;
pub fn naive_toml_parser(file_location: &str) -> (String, Vec<String>) {
pub fn naive_toml_parser(file_location: &str) -> (String, VecDeque<String>) {
let mut toml_file = File::open(file_location).unwrap();
let mut toml_ingredients = String::default();
toml_file.read_to_string(&mut toml_ingredients).unwrap();
let mut toml_ingredients = toml_ingredients.lines().collect::<Vec<&str>>();
let mut toml_ingredients = toml_ingredients.lines().collect::<VecDeque<&str>>();
let header = toml_ingredients.remove(0).trim_end().to_string();
let header = toml_ingredients.pop_front().unwrap().trim_end().to_string();
let parsed = toml_ingredients
.iter()
.map(|ingredient| {