Skip to content

Commit 5aff7ca

Browse files
committed
chore: updated rust.toml
1 parent 17377e0 commit 5aff7ca

32 files changed

+283
-402
lines changed

rustfmt.toml

+22-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,22 @@
1-
# Run `cargo +nightly fmt` to properly group imports
1+
# Run `cargo +nightly fmt` to properly group imports
2+
3+
edition = "2021"
4+
newline_style = "unix"
5+
use_field_init_shorthand = true
6+
use_small_heuristics = "Max"
7+
use_try_shorthand = true
8+
max_width = 100
9+
10+
# Unstable features below
11+
unstable_features = true
12+
version = "Two"
13+
comment_width = 100
14+
format_code_in_doc_comments = true
15+
format_macro_bodies = true
16+
format_macro_matchers = true
17+
format_strings = true
18+
imports_granularity = "Module"
19+
group_imports = "StdExternalCrate"
20+
normalize_comments = true
21+
normalize_doc_attributes = true
22+
wrap_comments = true

src/authentication/middleware.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1-
use crate::{
2-
session_state::TypedSession,
3-
utils::{e500, see_other},
4-
};
5-
use actix_web::{
6-
body::MessageBody,
7-
dev::{ServiceRequest, ServiceResponse},
8-
error::InternalError,
9-
{FromRequest, HttpMessage},
10-
};
11-
use actix_web_lab::middleware::Next;
121
use std::ops::Deref;
2+
3+
use actix_web::body::MessageBody;
4+
use actix_web::dev::{ServiceRequest, ServiceResponse};
5+
use actix_web::error::InternalError;
6+
use actix_web::{FromRequest, HttpMessage};
7+
use actix_web_lab::middleware::Next;
138
use uuid::Uuid;
149

10+
use crate::session_state::TypedSession;
11+
use crate::utils::{e500, see_other};
12+
1513
#[derive(Copy, Clone, Debug)]
1614
pub struct UserId(Uuid);
1715

src/authentication/password.rs

+9-18
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
use anyhow::Context;
2-
use argon2::{
3-
password_hash::SaltString, Algorithm, Argon2, Params, PasswordHash, PasswordHasher,
4-
PasswordVerifier, Version,
5-
};
2+
use argon2::password_hash::SaltString;
3+
use argon2::{Algorithm, Argon2, Params, PasswordHash, PasswordHasher, PasswordVerifier, Version};
64
use secrecy::{ExposeSecret, Secret};
75
use sqlx::PgPool;
86

@@ -49,9 +47,8 @@ pub async fn validate_credentials(
4947
) -> Result<uuid::Uuid, AuthError> {
5048
let mut user_id = None;
5149
let mut expected_password_hash = Secret::new(
52-
"$argon2id$v=19$m=15000,t=2,p=1$\
53-
gZiV/M1gPc22ElAH/Jh1Hw$\
54-
CWOrkoo7oJBQ/iyh7uJ0LO2aLEfrHwTWllSAxT0zRno"
50+
"$argon2id$v=19$m=15000,t=2,p=1$gZiV/M1gPc22ElAH/Jh1Hw$CWOrkoo7oJBQ/\
51+
iyh7uJ0LO2aLEfrHwTWllSAxT0zRno"
5552
.to_string(),
5653
);
5754

@@ -86,10 +83,7 @@ fn verify_password_hash(
8683
.context("Failed to parse hash in PHC string format.")?;
8784

8885
Argon2::default()
89-
.verify_password(
90-
password_candidate.expose_secret().as_bytes(),
91-
&expected_password_hash,
92-
)
86+
.verify_password(password_candidate.expose_secret().as_bytes(), &expected_password_hash)
9387
.context("Invalid password.")
9488
.map_err(AuthError::InvalidCredentials)
9589
}
@@ -120,12 +114,9 @@ pub async fn change_password(
120114

121115
fn compute_password_hash(password: Secret<String>) -> Result<Secret<String>, anyhow::Error> {
122116
let salt = SaltString::generate(&mut rand::thread_rng());
123-
let password_hash = Argon2::new(
124-
Algorithm::Argon2id,
125-
Version::V0x13,
126-
Params::new(15000, 2, 1, None).unwrap(),
127-
)
128-
.hash_password(password.expose_secret().as_bytes(), &salt)?
129-
.to_string();
117+
let password_hash =
118+
Argon2::new(Algorithm::Argon2id, Version::V0x13, Params::new(15000, 2, 1, None).unwrap())
119+
.hash_password(password.expose_secret().as_bytes(), &salt)?
120+
.to_string();
130121
Ok(Secret::new(password_hash))
131122
}

src/configuration.rs

+9-21
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
use crate::{domain::SubscriberEmail, email_client::EmailClient};
1+
use std::convert::{TryFrom, TryInto};
2+
23
use secrecy::{ExposeSecret, Secret};
34
use serde_aux::field_attributes::deserialize_number_from_string;
45
use sqlx::postgres::{PgConnectOptions, PgSslMode};
56
use sqlx::ConnectOptions;
6-
use std::convert::{TryFrom, TryInto};
77
use tracing_log::log;
88

9+
use crate::domain::SubscriberEmail;
10+
use crate::email_client::EmailClient;
11+
912
#[derive(serde::Deserialize, Clone)]
1013
pub struct Settings {
1114
pub database: DatabaseSettings,
@@ -35,12 +38,7 @@ impl EmailClientSettings {
3538
pub fn client(self) -> EmailClient {
3639
let sender_email = self.sender().expect("Invalid sender email address");
3740
let timeout = std::time::Duration::from_millis(self.timeout_ms);
38-
EmailClient::new(
39-
self.base_url,
40-
sender_email,
41-
self.authorization_token,
42-
timeout,
43-
)
41+
EmailClient::new(self.base_url, sender_email, self.authorization_token, timeout)
4442
}
4543

4644
pub fn sender(&self) -> Result<SubscriberEmail, String> {
@@ -65,11 +63,7 @@ pub struct DatabaseSettings {
6563

6664
impl DatabaseSettings {
6765
pub fn without_db(&self) -> PgConnectOptions {
68-
let ssl_mode = if self.require_ssl {
69-
PgSslMode::Require
70-
} else {
71-
PgSslMode::Prefer
72-
};
66+
let ssl_mode = if self.require_ssl { PgSslMode::Require } else { PgSslMode::Prefer };
7367
PgConnectOptions::new()
7468
.host(&self.host)
7569
.username(&self.username)
@@ -102,14 +96,8 @@ pub fn get_configuration() -> Result<Settings, config::ConfigError> {
10296

10397
let settings = config::Config::builder()
10498
.add_source(config::File::from(configuration_directory.join("base")))
105-
.add_source(config::File::from(
106-
configuration_directory.join(environment_filename),
107-
))
108-
.add_source(
109-
config::Environment::with_prefix("app")
110-
.prefix_separator("_")
111-
.separator("__"),
112-
)
99+
.add_source(config::File::from(configuration_directory.join(environment_filename)))
100+
.add_source(config::Environment::with_prefix("app").prefix_separator("_").separator("__"))
113101
.build()?;
114102

115103
settings.try_deserialize::<Settings>()

src/domain/new_subscriber.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use crate::domain::{subscriber_email::SubscriberEmail, subscriber_name::SubscriberName};
1+
use crate::domain::subscriber_email::SubscriberEmail;
2+
use crate::domain::subscriber_name::SubscriberName;
23

34
pub struct NewSubscriber {
45
pub email: SubscriberEmail,

src/domain/subscriber_email.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@ impl std::fmt::Display for SubscriberEmail {
2929

3030
#[cfg(test)]
3131
mod tests {
32-
use super::*;
3332
use claim::{assert_err, assert_ok};
3433
use fake::faker::internet::en::SafeEmail;
3534
use fake::Fake;
3635
use quickcheck::Gen;
37-
use rand::{rngs::StdRng, SeedableRng};
36+
use rand::rngs::StdRng;
37+
use rand::SeedableRng;
38+
39+
use super::*;
3840

3941
#[test]
4042
fn empty_string_is_rejected() {

src/domain/subscriber_name.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,14 @@ impl SubscriberName {
1414
let is_too_long = name.len() > 256;
1515
let forbidden_characters = ['/', '(', ')', '"', '<', '>', '\\', '{', '}'];
1616
// Check if the name contains any of the forbidden characters.
17-
let contains_forbidden_characters = name
18-
.chars()
19-
.any(|char| forbidden_characters.contains(&char));
17+
let contains_forbidden_characters =
18+
name.chars().any(|char| forbidden_characters.contains(&char));
2019
// If any of the above checks returns true, return an error.
2120
if is_empty_or_whitespace || is_too_long || contains_forbidden_characters {
2221
Err(format!(
23-
"`{}` is not a valid subscriber name. Subscriber name cannot be empty, more than 256 characters long, or contain the following characters: {:?}",
24-
name,
25-
forbidden_characters,
22+
"`{}` is not a valid subscriber name. Subscriber name cannot be empty, more than \
23+
256 characters long, or contain the following characters: {:?}",
24+
name, forbidden_characters,
2625
))
2726
} else {
2827
Ok(Self(name))
@@ -32,9 +31,10 @@ impl SubscriberName {
3231

3332
#[cfg(test)]
3433
mod tests {
35-
use super::*;
3634
use claim::{assert_err, assert_ok};
3735

36+
use super::*;
37+
3838
#[test]
3939
fn a_256_graheme_long_name_is_valid() {
4040
let name = "a".repeat(256);

src/email_client.rs

+14-32
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
use crate::domain::SubscriberEmail;
21
use reqwest::Client;
32
use secrecy::{ExposeSecret, Secret};
43

4+
use crate::domain::SubscriberEmail;
5+
56
#[derive(Clone)]
67
pub struct EmailClient {
78
http_client: Client,
@@ -18,12 +19,7 @@ impl EmailClient {
1819
timeout: std::time::Duration,
1920
) -> Self {
2021
let http_client = Client::builder().timeout(timeout).build().unwrap();
21-
Self {
22-
http_client,
23-
base_url,
24-
sender,
25-
authorization_token,
26-
}
22+
Self { http_client, base_url, sender, authorization_token }
2723
}
2824
}
2925

@@ -46,10 +42,7 @@ impl EmailClient {
4642

4743
self.http_client
4844
.post(&url)
49-
.header(
50-
"X-Postmark-Server-Token",
51-
self.authorization_token.expose_secret(),
52-
)
45+
.header("X-Postmark-Server-Token", self.authorization_token.expose_secret())
5346
.json(&request_body)
5447
.send()
5548
.await?
@@ -70,18 +63,16 @@ pub struct SendEmailRequest<'a> {
7063

7164
#[cfg(test)]
7265
mod tests {
73-
use crate::{domain::SubscriberEmail, email_client::EmailClient};
7466
use claim::{assert_err, assert_ok};
75-
use fake::{
76-
faker::internet::en::SafeEmail,
77-
faker::lorem::en::{Paragraph, Sentence},
78-
Fake, Faker,
79-
};
67+
use fake::faker::internet::en::SafeEmail;
68+
use fake::faker::lorem::en::{Paragraph, Sentence};
69+
use fake::{Fake, Faker};
8070
use secrecy::Secret;
81-
use wiremock::{
82-
matchers::{any, header, header_exists, method, path},
83-
Mock, MockServer, Request, ResponseTemplate,
84-
};
71+
use wiremock::matchers::{any, header, header_exists, method, path};
72+
use wiremock::{Mock, MockServer, Request, ResponseTemplate};
73+
74+
use crate::domain::SubscriberEmail;
75+
use crate::email_client::EmailClient;
8576

8677
struct SendEmailBodyMatcher;
8778

@@ -140,12 +131,7 @@ mod tests {
140131
let recipient = get_email();
141132

142133
let _ = email_client
143-
.send_email(
144-
&recipient,
145-
&generate_subject(),
146-
&generate_content(),
147-
&generate_content(),
148-
)
134+
.send_email(&recipient, &generate_subject(), &generate_content(), &generate_content())
149135
.await;
150136
}
151137

@@ -208,11 +194,7 @@ mod tests {
208194

209195
let response = ResponseTemplate::new(200).set_delay(std::time::Duration::from_secs(180));
210196

211-
Mock::given(any())
212-
.respond_with(response)
213-
.expect(1)
214-
.mount(&mock_server)
215-
.await;
197+
Mock::given(any()).respond_with(response).expect(1).mount(&mock_server).await;
216198

217199
let outcome = email_client
218200
.send_email(

src/idempotency/persistence.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
use super::IdempotencyKey;
2-
use actix_web::{body::to_bytes, http::StatusCode, HttpResponse};
3-
use sqlx::{postgres::PgHasArrayType, PgPool, Postgres, Transaction};
1+
use actix_web::body::to_bytes;
2+
use actix_web::http::StatusCode;
3+
use actix_web::HttpResponse;
4+
use sqlx::postgres::PgHasArrayType;
5+
use sqlx::{PgPool, Postgres, Transaction};
46
use uuid::Uuid;
57

8+
use super::IdempotencyKey;
9+
610
#[derive(Debug, sqlx::Type)]
711
#[sqlx(type_name = "header_pair")]
812
struct HeaderPairRecord {

src/issue_delivery_worker.rs

+11-17
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
use crate::{
2-
configuration::Settings, domain::SubscriberEmail, email_client::EmailClient,
3-
startup::get_connection_pool,
4-
};
5-
use sqlx::{PgPool, Postgres, Transaction};
61
use std::time::Duration;
7-
use tracing::{field::display, Span};
2+
3+
use sqlx::{PgPool, Postgres, Transaction};
4+
use tracing::field::display;
5+
use tracing::Span;
86
use uuid::Uuid;
97

8+
use crate::configuration::Settings;
9+
use crate::domain::SubscriberEmail;
10+
use crate::email_client::EmailClient;
11+
use crate::startup::get_connection_pool;
12+
1013
pub enum ExecutionOutcome {
1114
TaskCompleted,
1215
EmptyQueue,
@@ -38,12 +41,7 @@ pub async fn try_execute_task(
3841
Ok(email) => {
3942
let issue = get_issue(pool, issue_id).await?;
4043
if let Err(e) = email_client
41-
.send_email(
42-
&email,
43-
&issue.title,
44-
&issue.html_content,
45-
&issue.text_content,
46-
)
44+
.send_email(&email, &issue.title, &issue.html_content, &issue.text_content)
4745
.await
4846
{
4947
tracing::error!(
@@ -88,11 +86,7 @@ async fn dequeue_task(
8886
.fetch_optional(&mut *transaction)
8987
.await?;
9088
if let Some(r) = r {
91-
Ok(Some((
92-
transaction,
93-
r.newsletter_issue_id,
94-
r.subscriber_email,
95-
)))
89+
Ok(Some((transaction, r.newsletter_issue_id, r.subscriber_email)))
9690
} else {
9791
Ok(None)
9892
}

src/main.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
use robust_rust::{
2-
configuration::get_configuration, issue_delivery_worker::run_worker_until_stopped,
3-
startup::Application, telemetry::get_subscriber, telemetry::init_subscriber,
4-
};
51
use std::fmt::{Debug, Display};
2+
3+
use robust_rust::configuration::get_configuration;
4+
use robust_rust::issue_delivery_worker::run_worker_until_stopped;
5+
use robust_rust::startup::Application;
6+
use robust_rust::telemetry::{get_subscriber, init_subscriber};
67
use tokio::task::JoinError;
78

89
#[tokio::main]

0 commit comments

Comments
 (0)