use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct PokemonMove {
pub name: String,
pub level: i32,
pub method: String,
}
impl PokemonMove {
#[must_use]
pub fn formatted_name(&self) -> String {
self.name.replace('-', " ")
}
#[must_use]
pub fn formatted_method(&self) -> String {
match self.method.as_str() {
"level-up" => {
if self.level > 0 {
format!("Level {}", self.level)
} else {
"Evolution / Start".to_string()
}
}
"machine" => "TM / HM".to_string(),
"tutor" => "Move Tutor".to_string(),
"egg" => "Egg Move".to_string(),
other => other.to_string(),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct Pokemon {
pub id: i32,
pub name: String,
pub display_name: String,
pub types: Vec<String>,
pub hp: i32,
pub attack: i32,
pub defense: i32,
pub sp_attack: i32,
pub sp_defense: i32,
pub speed: i32,
pub height: i32,
pub weight: i32,
pub sprite_url: String,
pub artwork_url: String,
pub genus: String,
pub description: String,
pub moves: Vec<PokemonMove>,
}
impl Pokemon {
#[must_use]
pub fn formatted_id(&self) -> String {
format!("#{:03}", self.id)
}
#[must_use]
pub fn total_stats(&self) -> i32 {
self.hp + self.attack + self.defense + self.sp_attack + self.sp_defense + self.speed
}
#[must_use]
pub fn height_meters(&self) -> String {
#[allow(clippy::cast_precision_loss)]
let m = f64::from(self.height) / 10.0;
format!("{m:.1} m")
}
#[must_use]
pub fn weight_kg(&self) -> String {
#[allow(clippy::cast_precision_loss)]
let kg = f64::from(self.weight) / 10.0;
format!("{kg:.1} kg")
}
#[must_use]
pub fn level_up_moves(&self) -> Vec<&PokemonMove> {
let mut list: Vec<&PokemonMove> = self
.moves
.iter()
.filter(|m| m.method == "level-up")
.collect();
list.sort_by_key(|m| m.level);
list
}
#[must_use]
pub fn machine_tutor_moves(&self) -> Vec<&PokemonMove> {
let mut list: Vec<&PokemonMove> = self
.moves
.iter()
.filter(|m| m.method != "level-up")
.collect();
list.sort_by(|a, b| a.name.cmp(&b.name));
list
}
}