poke_data/models/
location.rs1use crate::data::link_context::LinkContext;
2use crate::data::linkable::Linkable;
3use crate::models::generation::GenerationId;
4use crate::models::language::LanguageId;
5use crate::models::region::{Region, RegionId};
6use crate::traits::has_identifier::HasIdentifier;
7use crate::types::language::Language;
8use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10use std::sync::Arc;
11
12pub type LocationId = u16;
13
14#[derive(Debug)]
15pub struct Location {
16 pub id: LocationId,
17 pub identifier: String,
18 pub region: Option<Arc<Region>>,
19 pub names: LocalizedLocationNames,
20 pub game_indices: LocationGameIndices,
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct LocationGameIndices(HashMap<GenerationId, u16>);
25
26impl LocationGameIndices {
27 pub fn new(indices: HashMap<GenerationId, u16>) -> Self {
28 Self(indices)
29 }
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct LocalizedLocationNames(HashMap<LanguageId, LocalizedLocationName>);
34
35impl LocalizedLocationNames {
36 pub fn new(localizations: HashMap<LanguageId, LocalizedLocationName>) -> Self {
37 Self(localizations)
38 }
39
40 pub fn get_by_language(&self, language: Language) -> Option<&LocalizedLocationName> {
41 let language_id = language as LanguageId;
42 if let Some(target) = self.0.get(&language_id) {
43 return Some(target);
44 }
45
46 let default_language_id = Language::default() as LanguageId;
47 if let Some(default) = self.0.get(&default_language_id) {
48 return Some(default);
49 }
50
51 None
52 }
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
56pub struct LocalizedLocationName {
57 pub name: String,
58 pub subtitle: String,
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct UnlinkedLocation {
63 pub id: LocationId,
64 pub identifier: String,
65 pub region_id: Option<RegionId>,
66 pub names: LocalizedLocationNames,
67 pub game_indices: LocationGameIndices,
68}
69
70impl Linkable for UnlinkedLocation {
71 type Linked = Arc<Location>;
72
73 fn link(&self, context: &LinkContext) -> Self::Linked {
74 let region = self.region_id.map(|region_id| {
75 context
76 .regions
77 .get(®ion_id)
78 .unwrap_or_else(|| {
79 panic!("No region '{}' found for location '{}'", region_id, self.id)
80 })
81 .clone()
82 });
83
84 let location = Location {
85 id: self.id,
86 identifier: self.identifier.clone(),
87 region,
88 names: self.names.clone(),
89 game_indices: self.game_indices.clone(),
90 };
91
92 Arc::new(location)
93 }
94}
95
96impl HasIdentifier for Location {
97 fn identifier(&self) -> &str {
98 &self.identifier
99 }
100}