fish_lib/game/services/
specimen_service.rs1use crate::data::species_data::SpeciesData;
2use crate::game::errors::resource::GameResourceError;
3use crate::game::errors::GameResult;
4use crate::game::repositories::specimen_repository::SpecimenRepositoryInterface;
5use crate::models::specimen::{NewSpecimen, Specimen};
6use crate::models::user::User;
7use std::sync::Arc;
8
9pub trait SpecimenServiceInterface: Send + Sync {
10 fn generate_and_save_specimen(
11 &self,
12 owner_user: &User,
13 species_data: Arc<SpeciesData>,
14 ) -> GameResult<Specimen>;
15
16 fn process_catch(&self, user: &User, species_data: Arc<SpeciesData>) -> GameResult<Specimen>;
17}
18
19pub struct SpecimenService {
20 specimen_repository: Arc<dyn SpecimenRepositoryInterface>,
21}
22
23impl SpecimenService {
24 pub fn new(specimen_repository: Arc<dyn SpecimenRepositoryInterface>) -> Self {
25 Self {
26 specimen_repository,
27 }
28 }
29}
30
31impl SpecimenServiceInterface for SpecimenService {
32 fn generate_and_save_specimen(
33 &self,
34 owner_user: &User,
35 species_data: Arc<SpeciesData>,
36 ) -> GameResult<Specimen> {
37 let new_fish = NewSpecimen::generate(owner_user.id, species_data.id);
38 self.specimen_repository
39 .create(new_fish)
40 .map_err(|e| match e.get_database_error() {
41 Some(db_error) if db_error.is_foreign_key_violation() => {
42 GameResourceError::user_not_found(owner_user.external_id).into()
43 }
44 _ => e.into(),
45 })
46 }
47
48 fn process_catch(&self, user: &User, species_data: Arc<SpeciesData>) -> GameResult<Specimen> {
49 let fish = self.generate_and_save_specimen(user, species_data)?;
50 Ok(fish)
51 }
52}