use axum::{ http::StatusCode, response::{IntoResponse, Response}, Json, }; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; // Database models #[derive(Debug, Clone, Serialize, Deserialize)] pub struct User { pub id: String, pub username: String, pub email: String, pub password_hash: String, pub created_at: DateTime, } // API request/response types #[derive(Debug, Clone, Serialize, Deserialize)] pub struct UserInfo { pub id: String, pub username: String, pub email: String, } #[derive(Debug, Deserialize)] pub struct RegisterRequest { pub username: String, pub email: String, pub password: String, } #[derive(Debug, Deserialize)] pub struct LoginRequest { pub username: String, pub password: String, } #[derive(Debug, Serialize)] pub struct AuthResponse { pub token: String, pub user: UserInfo, } // Error handling #[derive(Debug)] pub enum ApiError { Database(String), NotFound(String), Unauthorized(String), BadRequest(String), Conflict(String), Internal(String), } impl IntoResponse for ApiError { fn into_response(self) -> Response { let (status, error_message) = match self { ApiError::Database(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg), ApiError::NotFound(msg) => (StatusCode::NOT_FOUND, msg), ApiError::Unauthorized(msg) => (StatusCode::UNAUTHORIZED, msg), ApiError::BadRequest(msg) => (StatusCode::BAD_REQUEST, msg), ApiError::Conflict(msg) => (StatusCode::CONFLICT, msg), ApiError::Internal(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg), }; let body = Json(serde_json::json!({ "error": error_message, "status": status.as_u16() })); (status, body).into_response() } } impl std::fmt::Display for ApiError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { ApiError::Database(msg) => write!(f, "Database error: {}", msg), ApiError::NotFound(msg) => write!(f, "Not found: {}", msg), ApiError::Unauthorized(msg) => write!(f, "Unauthorized: {}", msg), ApiError::BadRequest(msg) => write!(f, "Bad request: {}", msg), ApiError::Conflict(msg) => write!(f, "Conflict: {}", msg), ApiError::Internal(msg) => write!(f, "Internal error: {}", msg), } } } impl std::error::Error for ApiError {}