From 4284c6c9082521188dbc1671ee9bcf6d7979efe6 Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Fri, 31 Jan 2020 23:21:24 -0500 Subject: [PATCH] Codeforces library minimally written Implement a lot of new structs Embed for User Implement more data structures impl Embed for Rating Change Move codeforces package outside --- Cargo.lock | 20 +++++++++ Cargo.toml | 1 + youmubot-cf/Cargo.toml | 12 +++++ youmubot-cf/src/embed.rs | 96 ++++++++++++++++++++++++++++++++++++++++ youmubot-cf/src/lib.rs | 1 + 5 files changed, 130 insertions(+) create mode 100644 youmubot-cf/Cargo.toml create mode 100644 youmubot-cf/src/embed.rs create mode 100644 youmubot-cf/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 3210d13..5941f03 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -151,6 +151,15 @@ dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "codeforces" +version = "0.1.0" +source = "git+https://github.com/natsukagami/rust-codeforces-api#2eb51a5ee5eb10b725ffbb33a4250a052eb6c60f" +dependencies = [ + "reqwest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "command_attr" version = "0.1.7" @@ -1685,6 +1694,16 @@ dependencies = [ "youmubot-prelude 0.1.0", ] +[[package]] +name = "youmubot-cf" +version = "0.1.0" +dependencies = [ + "codeforces 0.1.0 (git+https://github.com/natsukagami/rust-codeforces-api)", + "reqwest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serenity 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "youmubot-core" version = "0.1.0" @@ -1759,6 +1778,7 @@ dependencies = [ "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum codeforces 0.1.0 (git+https://github.com/natsukagami/rust-codeforces-api)" = "" "checksum command_attr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b61098146d3e0ad56c4918ae30ab9f32a7222cc859fc65fbc2a8475c1e48b336" "checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" diff --git a/Cargo.toml b/Cargo.toml index 828c358..7fd1f61 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "youmubot-prelude", "youmubot-db", "youmubot-core", + "youmubot-cf", "youmubot-osu", "youmubot", ] diff --git a/youmubot-cf/Cargo.toml b/youmubot-cf/Cargo.toml new file mode 100644 index 0000000..1a5ebde --- /dev/null +++ b/youmubot-cf/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "youmubot-cf" +version = "0.1.0" +authors = ["Natsu Kagami "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[dependencies] +serde = { version = "1", features = ["derive"] } +reqwest = "0.10.1" +serenity = "0.8" +codeforces = { git = "https://github.com/natsukagami/rust-codeforces-api" } diff --git a/youmubot-cf/src/embed.rs b/youmubot-cf/src/embed.rs new file mode 100644 index 0000000..1084f6e --- /dev/null +++ b/youmubot-cf/src/embed.rs @@ -0,0 +1,96 @@ +use codeforces::{Contest, RatingChange, User}; +use serenity::{builder::CreateEmbed, utils::MessageBuilder}; +use std::borrow::Borrow; + +fn unwrap_or_ref<'a, T: ?Sized, B: Borrow>(opt: &'a Option, default: &'a T) -> &'a T { + opt.as_ref().map(|v| v.borrow()).unwrap_or(default) +} + +/// Create an embed representing the user. +pub fn user_embed<'a>(user: &User, e: &'a mut CreateEmbed) -> &'a mut CreateEmbed { + let rank = unwrap_or_ref(&user.rank, "Unranked"); + let max_rank = unwrap_or_ref(&user.max_rank, "Unranked"); + let rating = user.rating.unwrap_or(1500); + let max_rating = user.max_rating.unwrap_or(1500); + let name = &[&user.first_name, &user.last_name] + .iter() + .filter_map(|v| v.as_ref().map(|v| v.as_str())) + .collect::>() + .join(" "); + let place = &[&user.organization, &user.city, &user.country] + .iter() + .filter_map(|v| v.as_ref().map(|v| v.as_str())) + .collect::>() + .join(" "); + e.color(user.color()) + .author(|a| a.name(rank)) + .title(&user.handle) + .description(format!( + "{}\n{}", + if name == "" { + "".to_owned() + } else { + format!("**{}**", name) + }, + if place == "" { + "".to_owned() + } else { + format!("from **{}**", place) + } + )) + .field( + "Rating", + format!("**{}** (max **{}**)", rating, max_rating), + true, + ) + .field("Contribution", format!("**{}**", user.contribution), true) + .field( + "Rank", + format!("**{}** (max **{}**)", rank, max_rank), + false, + ) +} + +/// Gets an embed of the Rating Change. +pub fn rating_change_embed<'a>( + rating_change: &RatingChange, + user: &User, + contest: &Contest, + tag: &str, + e: &'a mut CreateEmbed, +) -> &'a mut CreateEmbed { + let delta = (rating_change.new_rating as i64) - (rating_change.old_rating as i64); + let color = if delta < 0 { 0xff0000 } else { 0x00ff00 }; + let message = if delta < 0 { + MessageBuilder::new() + .push(tag) + .push(" competed in ") + .push_bold_safe(&contest.name) + .push(", gaining ") + .push_bold_safe(delta) + .push(" rating placing at ") + .push_bold(format!("#{}", rating_change.rank)) + .push("! 🎂🎂🎂") + .build() + } else { + MessageBuilder::new() + .push(tag) + .push(" competed in ") + .push_bold_safe(&contest.name) + .push(", but lost ") + .push_bold_safe(-delta) + .push(" rating placing at ") + .push_bold(format!("#{}", rating_change.rank)) + .push("... 😭😭😭") + .build() + }; + + e.author(|a| { + a.icon_url(&user.avatar) + .url(user.profile_url()) + .name(&user.handle) + }) + .color(color) + .description(message) + .field("Contest Link", contest.url(), true) +} diff --git a/youmubot-cf/src/lib.rs b/youmubot-cf/src/lib.rs new file mode 100644 index 0000000..057a3a2 --- /dev/null +++ b/youmubot-cf/src/lib.rs @@ -0,0 +1 @@ +pub mod embed;