use crate::model::{logbook::Logbook, stat::Stat, user::User}; use serde::Serialize; #[derive(Serialize, PartialEq, Debug)] pub(crate) enum Level { None, Bronze, Silver, Gold, Diamond, Done, } impl Level { fn required_km(&self) -> i32 { match self { Level::Bronze => 40_000, Level::Silver => 80_000, Level::Gold => 100_000, Level::Diamond => 200_000, Level::Done => 0, Level::None => 0, } } fn next_level(km: i32) -> Self { if km < Level::Bronze.required_km() { Level::Bronze } else if km < Level::Silver.required_km() { Level::Silver } else if km < Level::Gold.required_km() { Level::Gold } else if km < Level::Diamond.required_km() { Level::Diamond } else { Level::Done } } pub(crate) fn curr_level(km: i32) -> Self { if km < Level::Bronze.required_km() { Level::None } else if km < Level::Silver.required_km() { Level::Bronze } else if km < Level::Gold.required_km() { Level::Silver } else if km < Level::Diamond.required_km() { Level::Gold } else { Level::Diamond } } pub(crate) fn desc(&self) -> &str { match self { Level::Bronze => "Bronze", Level::Silver => "Silber", Level::Gold => "Gold", Level::Diamond => "Diamant", Level::Done => "", Level::None => "-", } } } #[derive(Serialize)] pub(crate) struct Next { level: Level, desc: String, missing_km: i32, required_km: i32, rowed_km: i32, } impl Next { pub(crate) fn new(rowed_km: i32) -> Self { let level = Level::next_level(rowed_km); let required_km = level.required_km(); let missing_km = required_km - rowed_km; Self { desc: level.desc().to_string(), level, missing_km, required_km, rowed_km, } } } pub(crate) async fn new_level_with_last_log( db: &mut sqlx::Transaction<'_, sqlx::Sqlite>, user: &User, ) -> Option<String> { let rowed_km = Stat::total_km_tx(db, user).await.rowed_km; if let Some(last_logbookentry) = Logbook::completed_with_user_tx(db, user).await.last() { let last_trip_km = last_logbookentry.logbook.distance_in_km.unwrap(); if Level::curr_level(rowed_km) != Level::curr_level(rowed_km - last_trip_km as i32) { return Some(Level::curr_level(rowed_km).desc().to_string()); } } None }