pub mod score;
use crate::ruler::Ruler;
use bon::Builder;
use derive_more::Deref;
use itertools::Itertools;
use score::Score;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deref, Deserialize, Serialize)]
#[derive_const(Default)]
#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
pub struct Ranking(Vec<RankingEntry>);
impl Ranking {
#[inline]
pub fn get(&self, ruler: &Ruler) -> Option<&RankingEntry> {
self
.0
.iter()
.find(|entry| &entry.ruler == ruler)
}
pub fn update<T>(&mut self, entries: T)
where
T: IntoIterator<Item = RankingEntry>,
{
self.0.clear();
let entries = entries
.into_iter()
.sorted_by_key(|it| it.score)
.rev()
.zip(1u32..)
.map(|(mut entry, rank)| {
entry.rank = Rank(rank);
entry
});
self.0.extend(entries);
}
}
#[derive(Builder, Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
pub struct RankingEntry {
#[builder(skip)]
rank: Rank,
#[builder(into)]
ruler: Ruler,
#[builder(into)]
score: Score,
#[builder(into)]
cities: u32,
}
#[derive(Copy, Debug, Deserialize, Serialize)]
#[derive_const(Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
pub struct Rank(u32);