diff --git a/src/feature/user_contact.rs b/src/feature/user_contact.rs index 13427e0..0ea8bc3 100644 --- a/src/feature/user_contact.rs +++ b/src/feature/user_contact.rs @@ -1,7 +1,58 @@ use serde::{Deserialize, Serialize}; +use sqlx::{Pool, Postgres}; + +use crate::database::user_contact; #[derive(Debug, Serialize, Deserialize)] pub struct UserContact { pub user_id: i64, pub contact_id: i64, } + +impl UserContact { + pub async fn create( + user_id: &i64, + contact_id: &i64, + database_connection: &Pool, + ) -> Result { + user_contact::create(user_id, contact_id, database_connection).await + } + + pub async fn read( + user_id: &i64, + contact_id: &i64, + database_connection: &Pool, + ) -> Result { + user_contact::read(user_id, contact_id, database_connection).await + } + + pub async fn update( + user_id: &i64, + contact_id: &i64, + database_connection: &Pool, + ) -> Result { + user_contact::update(user_id, contact_id, database_connection).await + } + + pub async fn delete( + user_id: &i64, + contact_id: &i64, + database_connection: &Pool, + ) -> Result { + user_contact::delete(user_id, contact_id, database_connection).await + } + + pub async fn read_all_for_user( + user_id: &i64, + database_connection: &Pool, + ) -> Result, sqlx::Error> { + user_contact::read_all_for_user(user_id, database_connection).await + } + + pub async fn delete_all_for_user( + user_id: &i64, + database_connection: &Pool, + ) -> Result, sqlx::Error> { + user_contact::delete_all_for_user(user_id, database_connection).await + } +} diff --git a/src/routing.rs b/src/routing.rs index 8aa28db..dc0bbd5 100644 --- a/src/routing.rs +++ b/src/routing.rs @@ -8,6 +8,7 @@ pub mod post_interaction; pub mod role; pub mod role_permission; pub mod user; +pub mod user_contact; use axum::{extract::State, http::StatusCode, response::IntoResponse, routing::get, Router}; use tower_http::cors::CorsLayer; @@ -53,6 +54,10 @@ pub async fn route(State(app_state): State) -> Router { "/contacts", contact::route(axum::extract::State(app_state.clone())), ) + .nest( + "/user_contacts", + user_contact::route(axum::extract::State(app_state.clone())), + ) .layer(CorsLayer::permissive()) .with_state(app_state) } diff --git a/src/routing/role_permission.rs b/src/routing/role_permission.rs index 8a5a55c..13ac4f4 100644 --- a/src/routing/role_permission.rs +++ b/src/routing/role_permission.rs @@ -30,8 +30,8 @@ pub fn route(State(app_state): State) -> Router { "/roles/:role_id/permissions/:permission_id", delete(delete_), ) - .route("/role/:role_id", get(read_all_for_role)) - .route("/role/:role_id", delete(delete_all_for_role)) + .route("/roles/:role_id", get(read_all_for_role)) + .route("/roles/:role_id", delete(delete_all_for_role)) .with_state(app_state) } diff --git a/src/routing/user_contact.rs b/src/routing/user_contact.rs new file mode 100644 index 0000000..de5397a --- /dev/null +++ b/src/routing/user_contact.rs @@ -0,0 +1,126 @@ +use axum::{ + extract::{Path, State}, + http::StatusCode, + response::IntoResponse, + routing::{delete, get, patch, post}, + Json, Router, +}; +use serde::{Deserialize, Serialize}; + +use crate::{feature::user_contact::UserContact, AppState}; + +#[derive(Debug, Serialize, Deserialize)] +struct CreateUserContact { + pub user_id: i64, + pub contact_id: i64, +} + +#[derive(Debug, Serialize, Deserialize)] +struct UpdateUserContact { + pub user_id: i64, + pub contact_id: i64, +} + +pub fn route(State(app_state): State) -> Router { + Router::new() + .route("/", post(create)) + .route("/roles/:user_id/contacts/:contact_id", get(read)) + .route("/", patch(update)) + .route("/roles/:user_id/contacts/:contact_id", delete(delete_)) + .route("/users/:user_id", get(read_all_for_user)) + .route("/users/:user_id", delete(delete_all_for_user)) + .with_state(app_state) +} + +async fn create( + State(app_state): State, + Json(create_user_contact): Json, +) -> impl IntoResponse { + match UserContact::create( + &create_user_contact.user_id, + &create_user_contact.contact_id, + &app_state.database_connection, + ) + .await + { + Ok(user_contact) => (StatusCode::CREATED, Json(serde_json::json!(user_contact))), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +} + +async fn read( + State(app_state): State, + Path((user_id, contact_id)): Path<(i64, i64)>, +) -> impl IntoResponse { + match UserContact::read(&user_id, &contact_id, &app_state.database_connection).await { + Ok(user_contact) => (StatusCode::OK, Json(serde_json::json!(user_contact))), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +} + +async fn update( + State(app_state): State, + Json(update_role): Json, +) -> impl IntoResponse { + match UserContact::update( + &update_role.user_id, + &update_role.contact_id, + &app_state.database_connection, + ) + .await + { + Ok(user_contact) => (StatusCode::ACCEPTED, Json(serde_json::json!(user_contact))), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +} + +async fn delete_( + State(app_state): State, + Path((user_id, contact_id)): Path<(i64, i64)>, +) -> impl IntoResponse { + match UserContact::delete(&user_id, &contact_id, &app_state.database_connection).await { + Ok(user_contact) => ( + StatusCode::NO_CONTENT, + Json(serde_json::json!(user_contact)), + ), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +} + +async fn read_all_for_user( + State(app_state): State, + Path(user_id): Path, +) -> impl IntoResponse { + match UserContact::read_all_for_user(&user_id, &app_state.database_connection).await { + Ok(role_contacts) => (StatusCode::OK, Json(serde_json::json!(role_contacts))), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +} + +async fn delete_all_for_user( + State(app_state): State, + Path(user_id): Path, +) -> impl IntoResponse { + match UserContact::delete_all_for_user(&user_id, &app_state.database_connection).await { + Ok(role_contacts) => (StatusCode::OK, Json(serde_json::json!(role_contacts))), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +}