use crate::grpc::{Character, CharacterRequest, CharacterListRequest, CharacterListResponse, CreateCharacterRequest, CreateCharacterResponse, DeleteCharacterRequest, Empty}; use crate::grpc::character_service_server::CharacterService; use crate::grpc::database_service::MyDatabaseService; use tonic::{Request, Response, Status}; #[tonic::async_trait] impl CharacterService for MyDatabaseService { async fn get_character( &self, request: Request, ) -> Result, Status> { let req = request.into_inner(); let repo = &self.db.character_repo; let character = repo .get_character_by_id(req.character_id) .await .map_err(|_| Status::not_found("Character not found"))?; let response = Character { id: character.id, user_id: character.user_id, name: character.name, level: character.level as i32, experience: character.experience, inventory: character.inventory.to_string(), stats: character.stats.to_string(), looks: character.looks.to_string(), position: character.position.to_string(), created_at: character.created_at.to_string(), updated_at: character.updated_at.to_string(), is_active: character.is_active, }; Ok(Response::new(response)) } async fn get_character_list( &self, request: Request, ) -> Result, Status> { let req = request.into_inner(); let repo = &self.db.character_repo; let characters = repo .get_characters_by_user(req.user_id) .await .map_err(|_| Status::not_found("Character not found"))?; let mut character_list: Vec = Vec::new(); for character in characters { let character = Character { id: character.id, user_id: character.user_id, name: character.name, level: character.level as i32, experience: character.experience, inventory: character.inventory.to_string(), stats: character.stats.to_string(), looks: character.looks.to_string(), position: character.position.to_string(), created_at: character.created_at.to_string(), updated_at: character.updated_at.to_string(), is_active: character.is_active, }; character_list.push(character); } let response = CharacterListResponse { characters: character_list, }; Ok(Response::new(response)) } async fn create_character( &self, request: Request, ) -> Result, Status> { let req = request.into_inner(); let repo = &self.db.character_repo; //todo: we need to check if the character name exists already let character_id = repo .create_character( req.user_id, &req.name, serde_json::from_str(&req.inventory).unwrap_or_default(), serde_json::from_str(&req.stats).unwrap_or_default(), serde_json::from_str(&req.looks).unwrap_or_default(), serde_json::from_str(&req.position).unwrap_or_default(), ) .await .map_err(|_| Status::internal("Failed to create character"))?; let character = repo .get_character_by_id(character_id) .await .map_err(|_| Status::not_found("Character not found"))?; let response = CreateCharacterResponse { character_id: character.id, }; Ok(Response::new(response)) } async fn delete_character( &self, request: Request, ) -> Result, Status> { let req = request.into_inner(); let repo = &self.db.character_repo; repo.delete_character(req.character_id) .await .map_err(|_| Status::internal("Failed to delete character"))?; Ok(Response::new(Empty {})) } }