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, guild: Id, 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::>() .join("\n"), Style::TiesBroken => placed .into_iter() .map(|placement| { format!( "`{:>2}` <@{}>: {}", placement.placement, placement.row.user_id, placement.row.points ) }) .collect::>() .join("\n"), }; let embed = EmbedBuilder::new().description(str).build(); InteractionResponseDataBuilder::new() .embeds([embed]) .build() } } }