From a47d8fdb605258ac301edf6c0fa0c48e01785db8 Mon Sep 17 00:00:00 2001 From: 1Kill2Steal <171241044+1Git2Clone@users.noreply.github.com> Date: Mon, 16 Dec 2024 00:03:12 +0200 Subject: [PATCH] Add more emoji features + valid url testing --- Cargo.toml | 1 + serenity_discord_bot_derive/Cargo.lock | 46 ++++++++++++++++++++++++++ serenity_discord_bot_derive/Cargo.toml | 11 ++++++ serenity_discord_bot_derive/src/lib.rs | 30 +++++++++++++++++ src/enums/emojis.rs | 27 +++++++++++++++ src/tests/emojis.rs | 24 ++++++++++++++ src/tests/mod.rs | 2 ++ 7 files changed, 141 insertions(+) create mode 100644 serenity_discord_bot_derive/Cargo.lock create mode 100644 serenity_discord_bot_derive/Cargo.toml create mode 100644 serenity_discord_bot_derive/src/lib.rs create mode 100644 src/tests/emojis.rs diff --git a/Cargo.toml b/Cargo.toml index 3c977d7..631cb15 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ chrono = "0.4.35" rayon = "1.10.0" regex = "1.11.1" reqwest = "0.12.9" +serenity_discord_bot_derive = { path = "./serenity_discord_bot_derive" } [features] serde = ["dep:serde"] diff --git a/serenity_discord_bot_derive/Cargo.lock b/serenity_discord_bot_derive/Cargo.lock new file mode 100644 index 0000000..7456b9b --- /dev/null +++ b/serenity_discord_bot_derive/Cargo.lock @@ -0,0 +1,46 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "serenity_discord_bot_derive" +version = "0.1.0" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "2.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" diff --git a/serenity_discord_bot_derive/Cargo.toml b/serenity_discord_bot_derive/Cargo.toml new file mode 100644 index 0000000..346c200 --- /dev/null +++ b/serenity_discord_bot_derive/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "serenity_discord_bot_derive" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +quote = "1.0.37" +syn = "2.0.90" diff --git a/serenity_discord_bot_derive/src/lib.rs b/serenity_discord_bot_derive/src/lib.rs new file mode 100644 index 0000000..0cc1b4a --- /dev/null +++ b/serenity_discord_bot_derive/src/lib.rs @@ -0,0 +1,30 @@ +extern crate proc_macro; + +use proc_macro::TokenStream; +use quote::quote; + +// Credit: +// https://stackoverflow.com/questions/68025264/how-to-get-all-the-variants-of-an-enum-in-a-vect-with-a-proc-macro/69812881#69812881 +#[proc_macro_derive(IterateVariants)] +pub fn derive_all_variants(input: TokenStream) -> TokenStream { + let ast = syn::parse_macro_input!(input as syn::DeriveInput); + + let syn::Data::Enum(enum_item) = ast.data else { + return quote!(compile_error!("AllVariants only works on enums")).into(); + }; + + let enum_name = ast.ident; + let variant_idents = enum_item.variants.into_iter().map(|v| v.ident); + + quote! { + impl #enum_name { + pub fn variants() -> &'static[Self] { + &[ #(#enum_name::#variant_idents),* ] + } + pub fn iter_variants() -> impl Iterator { + #enum_name::variants().iter() + } + } + } + .into() +} diff --git a/src/enums/emojis.rs b/src/enums/emojis.rs index 7b546c3..40aa1e8 100644 --- a/src/enums/emojis.rs +++ b/src/enums/emojis.rs @@ -1,3 +1,5 @@ +use serenity_discord_bot_derive::IterateVariants; + /// Discord emojis are sent like this: /// /// `` @@ -45,13 +47,38 @@ macro_rules! display_emoji_impl { } } } + impl $crate::enums::emojis::GetId for $enum_name { + fn get_id(&self) -> &'static str { + match self { + $(Self::$variant => $id,)* + } + } + } + impl $crate::enums::emojis::GetVariantStr for $enum_name { + fn get_variant_str(&self) -> &'static str { + match self { + $(Self::$variant => stringify!($variant),)* + } + } + } }; } +#[allow(dead_code)] +pub trait GetId { + fn get_id(&self) -> &'static str; +} + +#[allow(dead_code)] +pub trait GetVariantStr { + fn get_variant_str(&self) -> &'static str; +} + /// NOTE: This allows non-PascalCase because the emoji itself could have a non-PascalCase name. I'd /// still try to have them all be PascalCase though. #[allow(non_camel_case_types)] #[allow(dead_code)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, IterateVariants)] pub enum Emojis { HuTaoHeh, } diff --git a/src/tests/emojis.rs b/src/tests/emojis.rs new file mode 100644 index 0000000..17e8448 --- /dev/null +++ b/src/tests/emojis.rs @@ -0,0 +1,24 @@ +use reqwest::StatusCode; + +use crate::data::command_data::Error; +use crate::enums::emojis::{Emojis, GetId}; + +#[tokio::test] +async fn test_valid_emoji_urls() -> Result<(), Error> { + use reqwest::Client; + + let client = Client::new(); + + let make_discord_emoji_url = + |emoji_id: &str| format!("https://cdn.discordapp.com/emojis/{}", emoji_id); + + for variant in Emojis::iter_variants() { + let response = client + .head(make_discord_emoji_url(variant.get_id())) + .send() + .await?; + assert_eq!(response.status(), StatusCode::OK); + } + + Ok(()) +} diff --git a/src/tests/mod.rs b/src/tests/mod.rs index ed824a8..80b526a 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -1,5 +1,7 @@ #![cfg(test)] +#[cfg(feature = "network_test")] +mod emojis; #[cfg(feature = "network_test")] mod urls;