use crate::error::Result;
use crate::features::examples::models::{CreateUserRequest, UpdateUserRequest};
use crate::features::examples::repository::UserRepository;
use crate::features::examples::service::UserService;
use crate::state::AppState;
use axum::{
extract::{Path, Query, State},
http::StatusCode,
response::IntoResponse,
Json,
};
use serde::Deserialize;
use uuid::Uuid;
#[derive(Debug, Deserialize)]
pub struct ListUsersQuery {
#[serde(default = "default_page")]
pub page: u64,
#[serde(default = "default_per_page")]
pub per_page: u64,
}
fn default_page() -> u64 {
1
}
fn default_per_page() -> u64 {
10
}
#[derive(Debug, Deserialize)]
pub struct SearchUsersQuery {
pub email: String,
}
pub async fn list_users(
State(state): State<AppState>,
Query(query): Query<ListUsersQuery>,
) -> Result<impl IntoResponse> {
let repository = UserRepository::new(state.db.clone());
let service = UserService::new(repository);
let response = service.list_users(query.page, query.per_page).await?;
Ok(Json(response))
}
pub async fn get_user(
State(state): State<AppState>,
Path(id): Path<Uuid>,
) -> Result<impl IntoResponse> {
let repository = UserRepository::new(state.db.clone());
let service = UserService::new(repository);
let user = service.get_user(id).await?;
Ok(Json(user))
}
pub async fn create_user(
State(state): State<AppState>,
Json(request): Json<CreateUserRequest>,
) -> Result<impl IntoResponse> {
let repository = UserRepository::new(state.db.clone());
let service = UserService::new(repository);
let user = service.create_user(request).await?;
Ok((StatusCode::CREATED, Json(user)))
}
pub async fn update_user(
State(state): State<AppState>,
Path(id): Path<Uuid>,
Json(request): Json<UpdateUserRequest>,
) -> Result<impl IntoResponse> {
let repository = UserRepository::new(state.db.clone());
let service = UserService::new(repository);
let user = service.update_user(id, request).await?;
Ok(Json(user))
}
pub async fn delete_user(
State(state): State<AppState>,
Path(id): Path<Uuid>,
) -> Result<impl IntoResponse> {
let repository = UserRepository::new(state.db.clone());
let service = UserService::new(repository);
service.delete_user(id).await?;
Ok(StatusCode::NO_CONTENT)
}
pub async fn search_users(
State(state): State<AppState>,
Query(query): Query<SearchUsersQuery>,
) -> Result<impl IntoResponse> {
let repository = UserRepository::new(state.db.clone());
let service = UserService::new(repository);
let user = service.search_by_email(&query.email).await?;
match user {
Some(user) => Ok(Json(Some(user))),
None => Ok(Json(None)),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_pagination() {
assert_eq!(default_page(), 1);
assert_eq!(default_per_page(), 10);
}
}