poke_data/models/
pokemon_type.rs

1use crate::data::link_context::LinkContext;
2use crate::data::linkable::Linkable;
3use crate::models::damage_class::{DamageClass, DamageClassId};
4use crate::models::generation::{Generation, GenerationId};
5use crate::models::localized_names::LocalizedStrings;
6use crate::types::pokemon_type::Type;
7use serde::{Deserialize, Serialize};
8use std::collections::HashMap;
9use std::sync::Arc;
10
11pub type PokemonTypeId = u16;
12
13#[derive(Debug)]
14pub struct PokemonType {
15    /// The ID which uniquely identifies this Pokémon type
16    pub id: PokemonTypeId,
17    /// A slug string for identification
18    pub identifier: String,
19    /// The enum value of this Pokémon type; can be used for easier identification
20    pub type_enum: Type,
21    /// Names in different languages (availability might differ between objects)
22    pub names: LocalizedStrings,
23    /// The generation this type was introduced in
24    pub generation: Arc<Generation>,
25    /// The type-based physical/special split ended in Generation 4
26    pub damage_class: Option<Arc<DamageClass>>,
27    /// The index this Pokémon type was displayed at in different generations
28    pub game_indices: PokemonTypeGameIndices,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct PokemonTypeGameIndices(HashMap<GenerationId, u16>);
33
34impl PokemonTypeGameIndices {
35    pub fn new(indices: HashMap<GenerationId, u16>) -> Self {
36        Self(indices)
37    }
38}
39
40#[derive(Debug, Clone, Serialize, Deserialize)]
41pub struct UnlinkedPokemonType {
42    pub id: PokemonTypeId,
43    pub identifier: String,
44    pub names: LocalizedStrings,
45    pub generation_id: GenerationId,
46    pub damage_class_id: Option<DamageClassId>,
47    pub game_indices: PokemonTypeGameIndices,
48}
49
50impl Linkable for UnlinkedPokemonType {
51    type Linked = Arc<PokemonType>;
52
53    fn link(&self, context: &LinkContext) -> Self::Linked {
54        let generation = context
55            .generations
56            .get(&self.generation_id)
57            .unwrap_or_else(|| {
58                panic!(
59                    "No generation '{}' found for pokemon type '{}'",
60                    self.generation_id, self.id
61                )
62            })
63            .clone();
64
65        let damage_class = self.damage_class_id.map(|damage_class_id| {
66            context
67                .damage_classes
68                .get(&damage_class_id)
69                .unwrap_or_else(|| {
70                    panic!(
71                        "No damage class '{}' found for pokemon type '{}'",
72                        damage_class_id, self.id
73                    )
74                })
75                .clone()
76        });
77
78        let pokemon_type = PokemonType {
79            id: self.id,
80            identifier: self.identifier.clone(),
81            type_enum: Type::from(self.id),
82            names: self.names.clone(),
83            generation,
84            damage_class,
85            game_indices: self.game_indices.clone(),
86        };
87
88        Arc::new(pokemon_type)
89    }
90}