1pub mod score;
5
6use crate::ruler::Ruler;
7use bon::Builder;
8use derive_more::Deref;
9use itertools::Itertools;
10use score::Score;
11use serde::{Deserialize, Serialize};
12
13#[derive(Clone, Debug, Deref, Deserialize, Serialize)]
14#[derive_const(Default)]
15#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
16pub struct Ranking(Vec<RankingEntry>);
17
18impl Ranking {
19 #[inline]
20 pub fn get(&self, ruler: &Ruler) -> Option<&RankingEntry> {
21 self
22 .0
23 .iter()
24 .find(|entry| &entry.ruler == ruler)
25 }
26
27 pub fn update<T>(&mut self, entries: T)
28 where
29 T: IntoIterator<Item = RankingEntry>,
30 {
31 self.0.clear();
32 let entries = entries
33 .into_iter()
34 .sorted_by_key(|it| it.score)
35 .rev()
36 .zip(1u32..)
37 .map(|(mut entry, rank)| {
38 entry.rank = Rank(rank);
39 entry
40 });
41
42 self.0.extend(entries);
43 }
44}
45
46#[derive(Builder, Clone, Debug, Deserialize, Serialize)]
47#[serde(rename_all = "camelCase")]
48#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
49pub struct RankingEntry {
50 #[builder(skip)]
51 rank: Rank,
52
53 #[builder(into)]
54 ruler: Ruler,
55
56 #[builder(into)]
57 score: Score,
58
59 #[builder(into)]
60 cities: u32,
61}
62
63#[derive(Copy, Debug, Deserialize, Serialize)]
64#[derive_const(Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
65#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
66pub struct Rank(u32);