use serde_json::Value::Null; use crate::grpc::{Character, CharacterRequest, CharacterListRequest, CharacterListResponse, CreateCharacterRequest, CreateCharacterResponse, DeleteCharacterRequest, DeleteCharacterResponse}; use crate::grpc::character_db_service_server::CharacterDbService; use crate::grpc::database_service::MyDatabaseService; use tonic::{Request, Response, Status}; #[tonic::async_trait] impl CharacterDbService 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 mut deleted_at= "".to_string(); if character.deleted_at.is_some() { deleted_at = character.deleted_at.unwrap().to_string(); } let response = Character { id: character.id, user_id: character.user_id, name: character.name, inventory: character.inventory.to_string(), stats: character.stats.to_string(), skills: character.skills.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(), deleted_at, 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 mut deleted_at= "".to_string(); if character.deleted_at.is_some() { deleted_at = character.deleted_at.unwrap_or_default().to_string(); } let character = Character { id: character.id, user_id: character.user_id, name: character.name, inventory: character.inventory.to_string(), stats: character.stats.to_string(), skills: character.skills.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(), deleted_at, 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 { result: 0, 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; let time_left_in_seconds = repo.delete_character(req.character_id, req.delete_type) .await .map_err(|_| Status::internal("Failed to delete character"))?; let response = DeleteCharacterResponse { remaining_time: time_left_in_seconds, name: "".to_string(), }; Ok(Response::new(response)) } }