use crate::database::{user_service_client::UserServiceClient, CreateUserRequest, CreateUserResponse, GetUserByEmailRequest, GetUserByUsernameRequest, GetUserRequest, GetUserResponse}; use async_trait::async_trait; use chrono::{DateTime, Utc}; use std::error::Error; use tonic::transport::Channel; #[async_trait] pub trait DatabaseClientTrait: Sized { async fn connect(endpoint: &str) -> Result>; async fn get_user_by_userid(&mut self, user_id: i32) -> Result>; async fn get_user_by_username(&mut self, user_id: &str) -> Result>; async fn get_user_by_email(&mut self, email: &str) -> Result>; async fn create_user(&mut self, username: &str, email: &str, password: &str) -> Result>; async fn store_password_reset(&mut self, email: &str, reset_token: &str, expires_at: DateTime) -> Result<(), Box>; async fn get_password_reset(&self, reset_token: &str) -> Result, Box>; async fn delete_password_reset(&self, reset_token: &str) -> Result<(), Box>; async fn update_user_password(&self, email: &str, hashed_password: &str) -> Result<(), Box>; } #[derive(Clone)] pub struct DatabaseClient { client: UserServiceClient, } #[derive(Debug)] pub struct PasswordReset { pub email: String, pub reset_token: String, pub expires_at: DateTime, } #[async_trait] impl DatabaseClientTrait for DatabaseClient { async fn connect(endpoint: &str) -> Result> { let client = UserServiceClient::connect(endpoint.to_string()).await?; Ok(Self { client }) } async fn get_user_by_userid( &mut self, user_id: i32, ) -> Result> { let request = tonic::Request::new(GetUserRequest { user_id, }); let response = self.client.get_user(request).await?; Ok(response.into_inner()) } async fn get_user_by_username( &mut self, username: &str, ) -> Result> { let request = tonic::Request::new(GetUserByUsernameRequest { username: username.to_string(), }); let response = self.client.get_user_by_username(request).await?; Ok(response.into_inner()) } async fn get_user_by_email(&mut self, email: &str) -> Result> { let request = tonic::Request::new(GetUserByEmailRequest { email: email.to_string(), }); let response = self.client.get_user_by_email(request).await?; Ok(response.into_inner()) } async fn create_user(&mut self, username: &str, email: &str, password: &str) -> Result> { let request = tonic::Request::new(CreateUserRequest { username: username.to_string(), email: email.to_string(), hashed_password: password.to_string(), }); let response = self.client.create_user(request).await?; Ok(response.into_inner()) } async fn store_password_reset( &mut self, _email: &str, _reset_token: &str, _expires_at: DateTime, ) -> Result<(), Box> { Ok(()) } async fn get_password_reset( &self, _reset_token: &str, ) -> Result, Box> { todo!() } async fn delete_password_reset( &self, _reset_token: &str, ) -> Result<(), Box> { Ok(()) } async fn update_user_password( &self, _email: &str, _hashed_password: &str, ) -> Result<(), Box> { Ok(()) } }