1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
use std::sync::Arc;
use twilight_model::{
application::interaction::application_command::{CommandData, CommandOptionValue},
http::interaction::InteractionResponseData,
id::{Id, marker::GuildMarker},
};
use twilight_util::builder::{InteractionResponseDataBuilder, embed::EmbedBuilder};
use crate::{brain::Brain, database::Error as DbError, fail, util};
enum Style {
TiesEqual,
TiesBroken,
}
pub fn leaderboard(
brain: Arc<Brain>,
guild: Id<GuildMarker>,
data: Option<&CommandData>,
) -> InteractionResponseData {
let board = brain.db.get_leaderboard(guild.get());
let mut style = Style::TiesBroken;
if let Some(data) = data {
for opt in &data.options {
match opt.name.as_str() {
"style" => match &opt.value {
CommandOptionValue::String(raw) => match raw.as_str() {
"equal" => style = Style::TiesEqual,
"broken" => style = Style::TiesBroken,
_ => {
return fail!(format!(
"{raw} is not a valid style option. Try 'equal' or 'broken'"
));
}
},
_ => unreachable!(),
},
_ => unreachable!(),
}
}
}
match board {
Err(DbError::TableNotExist) => {
fail!("No leaderboard exists for this server! Create one by giving someone points.")
}
Err(DbError::UserNotExist) => unreachable!(),
Ok(data) => {
let placed = util::tiebreak_shared_positions(data);
let str = match style {
Style::TiesEqual => placed
.into_iter()
.map(|placement| {
if placement.placement_first_of_tie {
format!(
"`{:>2}` <@{}>: {}",
placement.placement_tie,
placement.row.user_id,
placement.row.points
)
} else {
format!(
"` ` <@{}>: {}",
placement.row.user_id, placement.row.points
)
}
})
.collect::<Vec<String>>()
.join("\n"),
Style::TiesBroken => placed
.into_iter()
.map(|placement| {
format!(
"`{:>2}` <@{}>: {}",
placement.placement, placement.row.user_id, placement.row.points
)
})
.collect::<Vec<String>>()
.join("\n"),
};
let embed = EmbedBuilder::new().description(str).build();
InteractionResponseDataBuilder::new()
.embeds([embed])
.build()
}
}
}
|