Skip to content

Commit

Permalink
refactor: simplify creating Contact + db query
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonribble committed Jul 8, 2024
1 parent 7af4466 commit 63f348e
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 64 deletions.
48 changes: 12 additions & 36 deletions src/db.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::sync::Arc;

use crate::models::{self, ContactWithId};
use crate::models;
use async_trait::async_trait;
use sqlx::postgres::PgPool;

Expand Down Expand Up @@ -44,29 +44,16 @@ impl ContactRepo for PostgresContactRepo {
}

async fn get_all(&self) -> anyhow::Result<Vec<models::ContactWithId>> {
let records = sqlx::query!(
r#"
let get_contacts_query = r#"
SELECT id, first_name, last_name, display_name, email, phone_number
FROM contacts
ORDER BY id
"#
)
.fetch_all(&*self.pg_pool)
.await?;

let contacts_with_id: Vec<models::ContactWithId> = records
.into_iter()
.map(|record| ContactWithId {
id: record.id,
contact: models::Contact {
first_name: record.first_name,
last_name: record.last_name,
display_name: record.display_name,
email: record.email,
phone_number: record.phone_number,
},
})
.collect();
"#;

let contacts_with_id: Vec<models::ContactWithId> =
sqlx::query_as::<_, models::ContactWithId>(get_contacts_query)
.fetch_all(&*self.pg_pool)
.await?;

Ok(contacts_with_id)
}
Expand All @@ -76,19 +63,13 @@ impl ContactRepo for PostgresContactRepo {
mod tests {
use super::*;
use mockall::predicate::*;
use models;

#[tokio::test]
async fn test_save_contact() {
let mut mock_contact_repo = MockContactRepo::new();

let test_contact = models::Contact {
first_name: "John".to_string(),
last_name: "Smith".to_string(),
display_name: "John Smith".to_string(),
email: "[email protected]".to_string(),
phone_number: "123-456-7890".to_string(),
};
let test_contact =
models::Contact::new("John", "Smith", "[email protected]", "123-456-7890").unwrap();

mock_contact_repo
.expect_save_contact()
Expand All @@ -109,13 +90,8 @@ mod tests {

let contacts = vec![models::ContactWithId {
id: 1,
contact: models::Contact {
first_name: "John".to_string(),
last_name: "Doe".to_string(),
display_name: "John Doe".to_string(),
email: "[email protected]".to_string(),
phone_number: "1234567890".to_string(),
},
contact: models::Contact::new("John", "Doe", "[email protected]", "1234567890")
.unwrap(),
}];

mock_contact_repo
Expand Down
10 changes: 2 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ mod utils;

use db::{ContactRepo, PostgresContactRepo};
use errors::AppError;
use models::Contact;
use sqlx::PgPool;

#[tokio::main]
Expand All @@ -33,7 +32,7 @@ async fn main() -> anyhow::Result<()> {
Ok(())
}

fn parse_arguments() -> Result<Contact, AppError> {
fn parse_arguments() -> Result<models::Contact, AppError> {
let args: Vec<String> = env::args().collect();

let has_correct_number_of_args = args.len() != 5;
Expand All @@ -42,10 +41,5 @@ fn parse_arguments() -> Result<Contact, AppError> {
return Err(AppError::InvalidArguments);
}

Contact::new(
args[1].clone(),
args[2].clone(),
args[3].clone(),
args[4].clone(),
)
models::Contact::new(&args[1], &args[2], &args[3], &args[4])
}
36 changes: 16 additions & 20 deletions src/models/contact.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{errors::AppError, utils};

#[derive(Debug, PartialEq, Eq, Clone)]
#[derive(Debug, PartialEq, Eq, Clone, sqlx::FromRow)]
pub struct Contact {
pub first_name: String,
pub last_name: String,
Expand All @@ -9,35 +9,36 @@ pub struct Contact {
pub phone_number: String,
}

#[derive(Debug, PartialEq, Eq, Clone)]
#[derive(Debug, PartialEq, Eq, Clone, sqlx::FromRow)]
pub struct ContactWithId {
pub id: i64,
#[sqlx(flatten)]
pub contact: Contact,
}

impl Contact {
pub fn new(
first_name: String,
last_name: String,
email: String,
phone_number: String,
first_name: &str,
last_name: &str,
email: &str,
phone_number: &str,
) -> Result<Self, AppError> {
let display_name = format!("{first_name} {last_name}");

if utils::is_not_valid_email(&email) {
return Err(AppError::InvalidEmail(email));
if utils::is_not_valid_email(email) {
return Err(AppError::InvalidEmail(email.to_owned()));
}

if utils::is_not_valid_phone_number(&phone_number) {
return Err(AppError::InvalidPhoneNumber(phone_number));
if utils::is_not_valid_phone_number(phone_number) {
return Err(AppError::InvalidPhoneNumber(phone_number.to_owned()));
}

Ok(Self {
first_name,
last_name,
first_name: first_name.to_owned(),
last_name: last_name.to_owned(),
display_name,
email,
phone_number,
email: email.to_owned(),
phone_number: phone_number.to_owned(),
})
}
}
Expand All @@ -47,12 +48,7 @@ mod tests {

#[test]
fn test_display_name() {
let person = Contact::new(
String::from("Jason"),
String::from("Ribble"),
String::from("[email protected]"),
String::from("123-456-7890"),
);
let person = Contact::new("Jason", "Ribble", "[email protected]", "123-456-7890");
let display_name = "Jason Ribble".to_string();

assert_eq!(person.unwrap().display_name, display_name)
Expand Down

0 comments on commit 63f348e

Please sign in to comment.