diff --git a/src/commands/add_server.rs b/src/commands/add_server.rs index eaf0971..a517162 100644 --- a/src/commands/add_server.rs +++ b/src/commands/add_server.rs @@ -10,31 +10,19 @@ use skynet_discord_bot::common::{ use sqlx::{Error, Pool, Sqlite}; pub async fn run(command: &CommandInteraction, ctx: &Context) -> String { - let sub_options = if let Some(CommandDataOption { - value: CommandDataOptionValue::SubCommand(options), + let Some(CommandDataOption { + value: CommandDataOptionValue::SubCommand(sub_options), .. }) = command.data.options.first() - { - options - } else { + else { return "Please provide sub options".to_string(); }; - let wolves_api = if let Some(x) = sub_options.first() { - match &x.value { - CommandDataOptionValue::String(key) => key.to_string(), - _ => return "Please provide a wolves API key".to_string(), - } - } else { + let Some(CommandDataOptionValue::String(wolves_api)) = sub_options.first().map(|opt| &opt.value) else { return "Please provide a wolves API key".to_string(); }; - let role_current = if let Some(x) = sub_options.get(1) { - match &x.value { - CommandDataOptionValue::Role(role) => role.to_owned(), - _ => return "Please provide a valid role for ``Role Current``".to_string(), - } - } else { + let Some(&CommandDataOptionValue::Role(role_current)) = sub_options.get(1).map(|opt| &opt.value) else { return "Please provide a valid role for ``Role Current``".to_string(); }; @@ -47,12 +35,7 @@ pub async fn run(command: &CommandInteraction, ctx: &Context) -> String { None }; - let bot_channel_id = if let Some(x) = sub_options.get(2) { - match &x.value { - CommandDataOptionValue::Channel(channel) => channel.to_owned(), - _ => return "Please provide a valid channel for ``Bot Channel``".to_string(), - } - } else { + let Some(&CommandDataOptionValue::Channel(bot_channel_id)) = sub_options.get(2).map(|opt| &opt.value) else { return "Please provide a valid channel for ``Bot Channel``".to_string(); }; @@ -63,7 +46,7 @@ pub async fn run(command: &CommandInteraction, ctx: &Context) -> String { let server_data = Servers { server: command.guild_id.unwrap_or_default(), - wolves_api, + wolves_api: wolves_api.to_string(), wolves_id: 0, role_past, role_current, @@ -72,12 +55,9 @@ pub async fn run(command: &CommandInteraction, ctx: &Context) -> String { bot_channel_id, }; - match add_server(&db, ctx, &server_data).await { - Ok(_) => {} - Err(e) => { - println!("{e:?}"); - return format!("Failure to insert into Servers {server_data:?}"); - } + if let Err(e) = add_server(&db, ctx, &server_data).await { + println!("{e:?}"); + return format!("Failure to insert into Servers {server_data:?}"); } "Added/Updated server info".to_string() diff --git a/src/commands/count.rs b/src/commands/count.rs index 41b9d81..e356c4f 100644 --- a/src/commands/count.rs +++ b/src/commands/count.rs @@ -8,24 +8,21 @@ pub mod committee { use skynet_discord_bot::common::{database::DataBase, set_roles::committee::db_roles_get}; pub async fn run(command: &CommandInteraction, ctx: &Context) -> String { - let sub_options = if let Some(CommandDataOption { - value: CommandDataOptionValue::SubCommand(key), + let Some(CommandDataOption { + value: CommandDataOptionValue::SubCommand(sub_options), .. }) = command.data.options.first() - { - key - } else { + else { return "Please provide a wolves API key".to_string(); }; - let all = if let Some(x) = sub_options.first() { - match x.value { + let all = sub_options + .first() + .map(|x| match x.value { CommandDataOptionValue::Boolean(y) => y, _ => false, - } - } else { - false - }; + }) + .unwrap_or(false); let db = { let data_read = ctx.data.read().await; @@ -41,30 +38,24 @@ pub mod committee { cs.push((committee.count, committee.name_role.to_owned())); } - cs.sort_by_key(|(count, _)| *count); - cs.reverse(); + cs.sort_by_key(|(count, _)| std::cmp::Reverse(*count)); // msg can be a max 2000 chars long - let mut limit = 2000 - 3; + let limit = 2000 - 3; - let mut response = vec!["```".to_string()]; + let mut response = "```".to_string(); for (count, name) in cs { - let leading = if count < 10 { " " } else { "" }; - - let line = format!("{leading}{count} {name}"); - - let length = line.len() + 1; - - if length < (limit + 3) { - response.push(line); - limit -= length; - } else { + use std::fmt::Write; + let len_before = response.len(); + _ = writeln!(response, "{count:>2} {name}"); + if response.len() >= limit { + // Discard the line that didn't fit + response.truncate(len_before); break; } } - response.push("```".to_string()); - - response.join("\n") + response.push_str("```"); + response } pub fn register() -> CreateCommand { @@ -99,12 +90,8 @@ pub mod servers { data_read.get::().expect("Expected Databse in TypeMap.").clone() }; - let mut committees = HashMap::new(); - if let Some(x) = get_committees(&db).await { - for committee in x { - committees.insert(committee.id, committee.to_owned()); - } - } + let committees = get_committees(&db).await.into_iter().flatten().map(|committee| (committee.id, committee)); + let committees: HashMap<_, _> = committees.collect(); let mut cs = vec![]; // pull it from a DB @@ -127,40 +114,22 @@ pub mod servers { cs.reverse(); // msg can be a max 2000 chars long - let mut limit = 2000 - 3; + let limit = 2000 - 3; - let mut response = vec!["```".to_string()]; + let mut response = "```".to_string(); for (current, past, name) in cs { - let current_leading = if current < 10 { - " " - } else if current < 100 { - " " - } else { - "" - }; - let past_leading = if past < 10 { - " " - } else if past < 100 { - " " - } else { - "" - }; - - let line = format!("{current_leading}{current} {past_leading}{past} {name}"); - - let length = line.len() + 1; - - // +3 is to account for the closing fence - if length < (limit + 3) { - response.push(line); - limit -= length; - } else { + use std::fmt::Write; + let len_before = response.len(); + _ = writeln!(response, "{current:>3} {past:>} {name}"); + if response.len() >= limit { + // Discard the line that didn't fit + response.truncate(len_before); break; } } - response.push("```".to_string()); + response.push_str("```"); - response.join("\n") + response } #[derive(Debug, Clone, Deserialize, Serialize, sqlx::FromRow)] diff --git a/src/common/database.rs b/src/common/database.rs index 2eaf5df..8ed9bd9 100644 --- a/src/common/database.rs +++ b/src/common/database.rs @@ -67,17 +67,11 @@ impl<'r> FromRow<'r, SqliteRow> for ServerMembersWolves { } fn get_discord_from_row(row: &SqliteRow) -> Option { - match row.try_get("discord") { - Ok(x) => { - let tmp: i64 = x; - if tmp == 0 { - None - } else { - Some(UserId::from(tmp as u64)) - } - } - _ => None, + let x: i64 = row.try_get("discord").ok()?; + if x == 0 { + return None; } + Some(UserId::from(x as u64)) } #[derive(Debug, Clone, Deserialize, Serialize)] diff --git a/src/common/minecraft.rs b/src/common/minecraft.rs index 77cd754..0946a47 100644 --- a/src/common/minecraft.rs +++ b/src/common/minecraft.rs @@ -49,7 +49,7 @@ pub async fn post(url: &str, bearer: &str, data: &T) { .body_json(&data) { Ok(req) => { - req.await.ok(); + _ = req.await; } Err(e) => { dbg!(e); @@ -71,20 +71,14 @@ pub struct ServerDetailsRes { } async fn get(url: &str, bearer: &str) -> Option { - match surf::get(url) + surf::get(url) .header("Authorization", bearer) .header("Content-Type", "application/json") .header("Accept", "Application/vnd.pterodactyl.v1+json") .recv_json() .await - { - Ok(res) => Some(res), - Err(e) => { - dbg!(e); - - None - } - } + .map_err(|e| dbg!(e)) + .ok() } #[derive(Deserialize, Serialize, Debug)] @@ -157,14 +151,9 @@ pub async fn whitelist_update(add: &Vec<(String, bool)>, server: &str, token: &s let bearer = format!("Bearer {token}"); for (name, java) in add { - let data = if *java { - BodyCommand { - command: format!("whitelist add {name}"), - } - } else { - BodyCommand { - command: format!("fwhitelist add {name}"), - } + let command = if *java { format!("whitelist add {name}") } else { format!("fwhitelist add {name}") }; + let data = BodyCommand { + command, }; post(&format!("{url_base}/command"), &bearer, &data).await; } diff --git a/src/common/renderer.rs b/src/common/renderer.rs index f2c50cc..9540a4d 100644 --- a/src/common/renderer.rs +++ b/src/common/renderer.rs @@ -54,62 +54,47 @@ impl Renderer { count: 0, }; - let colors = if args.colors.contains(':') { - //? object - let obj = args - .colors - .split(',') - .map(|s| { - let s = s.split(':').collect::>(); + this.colors = if args.colors.contains(':') { + let obj = args.colors.split(',').map(|s| { + let mut iter = s.split(':'); + let [Some(a), Some(b), None] = std::array::from_fn(|_| iter.next()) else { + dbg!("Invalid color object, try checking help"); + return None; + }; - if s.len() < 2 { - dbg!("Invalid color object, try checking help"); - return None; - } + Some((a.to_string(), b.to_string())) + }); - Some((s[0].to_string(), s[1].to_string())) + let colors = obj + .flatten() + .map(|c| { + std::fs::create_dir_all(args.output.join(&c.0))?; + Ok(c) }) - .collect::>>(); - - let mut colors = Vec::new(); - - for c in obj.into_iter().flatten() { - std::fs::create_dir_all(args.output.join(&c.0))?; - - colors.push(c); - } + .collect::>()?; ColorType::Object(colors) } else { - //? list - // let colors = args.colors.split(",").map(|s| { - // s.to_string() - // }) - // .collect::>(); - - let mut colors = Vec::new(); - - for color in args.colors.split(',') { - std::fs::create_dir_all(args.output.join(color))?; - colors.push(color.to_string()) - } + let colors = args + .colors + .split(',') + .map(|color| -> std::io::Result { + std::fs::create_dir_all(args.output.join(color))?; + Ok(color.to_string()) + }) + .collect::>()?; ColorType::Array(colors) }; - - this.colors = colors; Ok(this) } pub fn render(&mut self, fi: &Path, args: &Args) -> Result<()> { - match fi.extension() { - Some(e) if e.to_str() == Some("svg") => {} - Some(_) | None => { - dbg!("Filer {:?} is not of type SVG", fi); - // util::logger::warning(format!("File '{}' is not of SVG type", fi.clone().to_str().unwrap())); - bail!("Failed to render"); - } - }; + if fi.extension().is_none_or(|ext| ext != "svg") { + dbg!("Filer {:?} is not of type SVG", fi); + // util::logger::warning(format!("File '{}' is not of SVG type", fi.clone().to_str().unwrap())); + bail!("Failed to render"); + } match self.colors.clone() { ColorType::Array(c) => { diff --git a/src/common/server_icon.rs b/src/common/server_icon.rs index 1a7c2ef..325839b 100644 --- a/src/common/server_icon.rs +++ b/src/common/server_icon.rs @@ -60,17 +60,11 @@ pub mod get_config_icons { let config_source = minimal(); let file_path = format!("{}/open-governance/{}/{}", &config.home, &config_source.source.directory, &config_source.source.file); - let contents = fs::read_to_string(file_path).unwrap_or_else(|e| { - dbg!(e); - "".to_string() - }); - let festivals = match toml::from_str::(&contents) { - Ok(config_festivals) => config_festivals.festivals, - Err(e) => { - dbg!(e); - vec![] - } - }; + let contents = fs::read_to_string(file_path).map_err(|e| dbg!(e)).unwrap_or_default(); + let festivals = toml::from_str::(&contents) + .map(|config| config.festivals) + .map_err(|e| dbg!(e)) + .unwrap_or_default(); ConfigToml { source: config_source.source, @@ -248,12 +242,9 @@ pub mod update_icon { for tmp in paths.flatten() { let path_local = tmp.path().to_owned(); let path_local2 = tmp.path().to_owned(); - let name = match path_local2.file_name() { - None => { - dbg!(path_local2); - continue; - } - Some(x) => x.to_owned(), + let Some(name) = path_local2.file_name().map(ToOwned::to_owned) else { + dbg!(path_local2); + continue; }; let mut path = tmp.path(); @@ -308,16 +299,15 @@ pub mod update_icon { fn logos_filter(festival_data: &FestivalData, existing: Vec) -> Vec { let mut filtered: Vec = vec![]; - let allowed_files = vec![".png", ".jpeg", ".gif", ".svg"]; + let allowed_extensions = ["png", "jpeg", "gif", "svg"]; 'outer: for logo in existing { - let name_lowercase0 = logo.name.to_ascii_lowercase(); - let name_lowercase = name_lowercase0.to_str().unwrap_or_default(); - let mut allowed = false; - for allowed_type in &allowed_files { - if name_lowercase.ends_with(allowed_type) { - allowed = true; - } - } + let name_lowercase = logo.name.to_ascii_lowercase(); + let name_lowercase = name_lowercase.to_str().unwrap_or_default(); + + let allowed = { + let extension = name_lowercase.split('.').next_back().unwrap_or_default(); + allowed_extensions.contains(&extension) + }; if !allowed { continue; } @@ -332,13 +322,7 @@ pub mod update_icon { } } else { // else filter using the excluded ones - let mut excluded = false; - for festival in &festival_data.exclusions { - if name_lowercase.contains(festival) { - excluded = true; - } - } - + let excluded = festival_data.exclusions.iter().any(|festival| name_lowercase.contains(festival)); if !excluded { filtered.push(logo); } @@ -349,39 +333,34 @@ pub mod update_icon { } async fn logo_set(ctx: &Context, db: &Pool, server: &GuildId, logo_selected: &LogoData) { - // add to teh database - if !logo_set_db(db, logo_selected).await { + // add to the database + if logo_set_db(db, logo_selected).await.is_err() { // something went wrong return; } - if let Some(logo_path) = logo_selected.path.to_str() { - match CreateAttachment::path(logo_path).await { - Ok(icon) => { - // assuming a `guild` has already been bound - let builder = EditGuild::new().icon(Some(&icon)); - if let Err(e) = server.edit(ctx, builder).await { - dbg!(e); - } - } - Err(e) => { + let Some(logo_path) = logo_selected.path.to_str() else { + return; + }; + match CreateAttachment::path(logo_path).await { + Ok(icon) => { + // assuming a `guild` has already been bound + let builder = EditGuild::new().icon(Some(&icon)); + if let Err(e) = server.edit(ctx, builder).await { dbg!(e); } } + Err(e) => { + dbg!(e); + } } } - async fn logo_set_db(db: &Pool, logo_selected: &LogoData) -> bool { - let name = match logo_selected.name.to_str() { - None => return false, - Some(x) => x, - }; - let path = match logo_selected.path.to_str() { - None => return false, - Some(x) => x, - }; + async fn logo_set_db(db: &Pool, logo_selected: &LogoData) -> Result<(), ()> { + let name = logo_selected.name.to_str().ok_or(())?; + let path = logo_selected.path.to_str().ok_or(())?; - match sqlx::query_as::<_, ServerIcons>( + sqlx::query_as::<_, ServerIcons>( " INSERT OR REPLACE INTO server_icons (name, date, path) VALUES (?1, ?2, ?3) @@ -392,13 +371,9 @@ pub mod update_icon { .bind(path) .fetch_optional(db) .await - { - Ok(_) => {} - Err(e) => { - dbg!(e); - return false; - } - } - true + .map_err(|e| { + dbg!(e); + })?; + Ok(()) } } diff --git a/src/common/wolves.rs b/src/common/wolves.rs index 3744558..76debef 100644 --- a/src/common/wolves.rs +++ b/src/common/wolves.rs @@ -24,7 +24,7 @@ struct WolvesResultUserMin { } async fn add_users_wolves(db: &Pool, user: &WolvesResultUserMin) { // expiry - match sqlx::query_as::<_, Wolves>( + if let Err(e) = sqlx::query_as::<_, Wolves>( " INSERT INTO wolves (id_wolves, email) VALUES ($1, $2) @@ -36,11 +36,8 @@ async fn add_users_wolves(db: &Pool, user: &WolvesResultUserMin) { .fetch_optional(db) .await { - Ok(_) => {} - Err(e) => { - println!("Failure to insert into Wolves {user:?}"); - println!("{e:?}"); - } + println!("Failure to insert into Wolves {user:?}"); + println!("{e:?}"); } } @@ -91,7 +88,6 @@ pub mod cns { wolves_id, .. } = &server_config; - // dbg!(&server_config); let existing_tmp = get_server_member(&db, server).await; let existing = existing_tmp.iter().map(|data| (data.id_wolves, data)).collect::>(); @@ -99,7 +95,6 @@ pub mod cns { // list of users that need to be updated for this server let mut server_name_tmp = None; for user in wolves.get_members(wolves_api).await { - // dbg!(&user.committee); if server_name_tmp.is_none() { server_name_tmp = Some(user.committee_id); } diff --git a/src/lib.rs b/src/lib.rs index 1a6afb1..abb9dbe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -106,21 +106,19 @@ pub fn get_config() -> Config { } } if let Ok(x) = env::var("COMMITTEE_ROLE") { - if let Ok(x) = x.trim().parse::() { + if let Ok(x) = x.trim().parse() { config.committee_role = RoleId::new(x); } } if let Ok(x) = env::var("COMMITTEE_CATEGORY") { - for part in x.split(',') { - if let Ok(x) = part.trim().parse::() { - config.committee_category.push(ChannelId::new(x)); - } + for id in x.split(',').flat_map(|part| part.trim().parse()) { + config.committee_category.push(ChannelId::new(id)); } } if let Ok(x) = env::var("COMPSOC_DISCORD") { - if let Ok(x) = x.trim().parse::() { - config.compsoc_server = GuildId::new(x); + if let Ok(x) = x.trim().parse() { + config.compsoc_server = GuildId::new(x) } } diff --git a/src/main.rs b/src/main.rs index 8dff675..9666652 100644 --- a/src/main.rs +++ b/src/main.rs @@ -54,15 +54,14 @@ impl EventHandler for Handler { // committee server takes priority let committee_server = config_global.committee_server; - if new_member.guild_id.get() == committee_server.get() { + if new_member.guild_id == committee_server { let mut member = vec![new_member.clone()]; update_committees(&db, &ctx, &config_global, &mut member).await; return; } - let config_server = match get_server_config(&db, &new_member.guild_id).await { - None => return, - Some(x) => x, + let Some(config_server) = get_server_config(&db, &new_member.guild_id).await else { + return; }; if get_server_member(&db, &new_member.guild_id, &new_member).await.is_ok() { @@ -81,26 +80,26 @@ impl EventHandler for Handler { if let Err(e) = new_member.add_roles(&ctx, &roles).await { println!("{e:?}"); } - } else { - let tmp = get_committee(&db, config_server.wolves_id).await; - if !tmp.is_empty() { - let committee = &tmp[0]; - let msg = format!( - r#" + return; + } + let tmp = get_committee(&db, config_server.wolves_id).await; + let Some(committee) = tmp.first() else { + return; + }; + let msg = format!( + r#" Welcome {} to the {} server! Sign up on [UL Wolves]({}) and go to https://discord.com/channels/{}/{} and use ``/wolves link email_here`` with the email associated with your wolves account, to get full access. "#, - new_member.display_name(), - committee.name_full, - committee.link, - &config_server.server, - &config_server.bot_channel_id - ); + new_member.display_name(), + committee.name_full, + committee.link, + &config_server.server, + &config_server.bot_channel_id + ); - if let Err(err) = new_member.user.direct_message(&ctx, CreateMessage::new().content(&msg)).await { - dbg!(err); - } - } + if let Err(err) = new_member.user.direct_message(&ctx, CreateMessage::new().content(&msg)).await { + dbg!(err); } } @@ -113,9 +112,8 @@ Sign up on [UL Wolves]({}) and go to https://discord.com/channels/{}/{} and use }; // check if the role changed is part of the ones for this server - if let Some(x) = new_data { - on_role_change(&db, &ctx, x).await; - } + let Some(x) = new_data else { return }; + on_role_change(&db, &ctx, x).await; } async fn ready(&self, ctx: Context, ready: Ready) { @@ -128,7 +126,7 @@ Sign up on [UL Wolves]({}) and go to https://discord.com/channels/{}/{} and use }; let config = config_lock.read().await; - match Command::set_global_commands( + if let Err(e) = Command::set_global_commands( &ctx.http, vec![ commands::wolves::register(), @@ -140,22 +138,16 @@ Sign up on [UL Wolves]({}) and go to https://discord.com/channels/{}/{} and use ) .await { - Ok(_) => {} - Err(e) => { - println!("{e:?}") - } + println!("{e:?}") } // Inter-Committee server - match config.committee_server.set_commands(&ctx.http, vec![commands::count::committee::register()]).await { - Ok(_) => {} - Err(e) => { - println!("{e:?}") - } + if let Err(e) = config.committee_server.set_commands(&ctx.http, vec![commands::count::committee::register()]).await { + println!("{e:?}") } // CompSoc Server - match config + if let Err(e) = config .compsoc_server .set_commands( &ctx.http, @@ -167,16 +159,13 @@ Sign up on [UL Wolves]({}) and go to https://discord.com/channels/{}/{} and use ) .await { - Ok(_) => {} - Err(e) => { - println!("{e:?}") - } + println!("{e:?}") } } async fn interaction_create(&self, ctx: Context, interaction: Interaction) { if let Interaction::Command(command) = interaction { - let _ = command.defer_ephemeral(&ctx.http).await; + _ = command.defer_ephemeral(&ctx.http).await; // println!("Received command interaction: {:#?}", command); let content = match command.data.name.as_str() { @@ -190,7 +179,7 @@ Sign up on [UL Wolves]({}) and go to https://discord.com/channels/{}/{} and use "link_minecraft" => commands::minecraft::user::add::run(&command, &ctx).await, "docs" => commands::wolves::link_docs::users::run(&command, &ctx).await, // "link" => commands::count::servers::run(&command, &ctx).await, - &_ => format!("not implemented :( wolves {}", x.name.as_str()), + _ => format!("not implemented :( wolves {}", x.name.as_str()), }, }, @@ -205,7 +194,7 @@ Sign up on [UL Wolves]({}) and go to https://discord.com/channels/{}/{} and use None => "error".to_string(), Some(z) => match z.name.as_str() { "change" => commands::server_icon::admin::change::run(&command, &ctx).await, - &_ => format!("not implemented :( count {}", x.name.as_str()), + _ => format!("not implemented :( count {}", x.name.as_str()), }, }, _ => { @@ -214,7 +203,7 @@ Sign up on [UL Wolves]({}) and go to https://discord.com/channels/{}/{} and use }, // TODO: move teh minecraft commands in here as a subgroup // "link" => commands::count::servers::run(&command, &ctx).await, - &_ => format!("not implemented :( committee {}", x.name.as_str()), + _ => format!("not implemented :( committee {}", x.name.as_str()), }, }, "minecraft_add" => commands::minecraft::server::add::run(&command, &ctx).await, @@ -226,7 +215,7 @@ Sign up on [UL Wolves]({}) and go to https://discord.com/channels/{}/{} and use Some(x) => match x.name.as_str() { "committee" => commands::count::committee::run(&command, &ctx).await, "servers" => commands::count::servers::run(&command, &ctx).await, - &_ => format!("not implemented :( count {}", x.name.as_str()), + _ => format!("not implemented :( count {}", x.name.as_str()), }, }, @@ -240,16 +229,16 @@ Sign up on [UL Wolves]({}) and go to https://discord.com/channels/{}/{} and use Some(z) => match z.name.as_str() { "icon" => commands::server_icon::user::current::icon::run(&command, &ctx).await, "festival" => commands::server_icon::user::current::festival::run(&command, &ctx).await, - &_ => format!("not implemented :( count {}", x.name.as_str()), + _ => format!("not implemented :( count {}", x.name.as_str()), }, }, - &_ => format!("not implemented :( {}", command.data.name.as_str()), + _ => format!("not implemented :( {}", command.data.name.as_str()), }; result } "stats" => commands::server_icon::user::stats::run(&command, &ctx).await, - &_ => format!("not implemented :( count {}", x.name.as_str()), + _ => format!("not implemented :( count {}", x.name.as_str()), }, }, _ => format!("not implemented :( {}", command.data.name.as_str()),