From 2967c743d65cfa3f9d9bb90fa51d9511892d1a47 Mon Sep 17 00:00:00 2001 From: shibedrill Date: Sat, 5 Oct 2024 00:30:56 -0400 Subject: [PATCH] Major refactor to prepare for database stuff --- Cargo.lock | 167 ++++++++++++++++++++++++++++++++++--------- Cargo.toml | 9 ++- README.md | 2 +- build.rs | 16 +++++ src/command/devel.rs | 21 +++++- src/command/util.rs | 76 +------------------- src/definitions.rs | 30 ++++++++ src/main.rs | 75 ++++--------------- src/schema.rs | 19 +++++ src/settings.rs | 1 + 10 files changed, 243 insertions(+), 173 deletions(-) create mode 100644 build.rs create mode 100644 src/definitions.rs create mode 100644 src/schema.rs diff --git a/Cargo.lock b/Cargo.lock index 5a77135..aa5d86e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,6 +41,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anyhow" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" + [[package]] name = "arrayvec" version = "0.7.4" @@ -109,19 +115,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "build-time" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1219c19fc29b7bfd74b7968b420aff5bc951cf517800176e795d6b2300dd382" -dependencies = [ - "chrono", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.59", -] - [[package]] name = "bumpalo" version = "3.16.0" @@ -177,6 +170,20 @@ dependencies = [ "serde_json", ] +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "cc" version = "1.0.94" @@ -337,6 +344,37 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_builder" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd33f37ee6a119146a1781d3356a7c26028f83d779b2e04ecd45fdc75c76877b" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7431fa049613920234f22c47fdc33e6cf3ee83067091ea4277a3f8c4587aae38" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.59", +] + +[[package]] +name = "derive_builder_macro" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4abae7035bf79b9877b779505d8cf3749285b80c43941eda66604841889451dc" +dependencies = [ + "derive_builder_core", + "syn 2.0.59", +] + [[package]] name = "digest" version = "0.10.7" @@ -590,6 +628,12 @@ version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -915,6 +959,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + [[package]] name = "object" version = "0.32.2" @@ -1142,9 +1195,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", @@ -1154,9 +1207,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", @@ -1165,9 +1218,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" @@ -1258,16 +1311,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rustc_version_runtime" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dd18cd2bae1820af0b6ad5e54f4a51d0f3fcc53b05f845675074efcc7af071d" -dependencies = [ - "rustc_version", - "semver", -] - [[package]] name = "rustix" version = "0.38.32" @@ -1343,6 +1386,12 @@ dependencies = [ "untrusted", ] +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + [[package]] name = "ryu" version = "1.0.17" @@ -1514,19 +1563,20 @@ dependencies = [ [[package]] name = "shibe-bot" -version = "0.3.4" +version = "0.4.0" dependencies = [ - "build-time", + "anyhow", "dotenvy", "log", "poise", "pretty_env_logger", "rand", "roux", - "rustc_version_runtime", "serde", "serde_json", + "structstruck", "tokio", + "vergen", ] [[package]] @@ -1536,7 +1586,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16d23b015676c90a0f01c197bfdc786c20342c73a0afdda9025adb0bc42940a8" dependencies = [ "bytecount", - "cargo_metadata", + "cargo_metadata 0.14.2", "error-chain", "glob", "pulldown-cmark", @@ -1581,6 +1631,18 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "structstruck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a052ec87a2d9bdd3a35f85ec6a07a5ac0816e4190b1cbede9d67cccb47ea66d" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "venial", +] + [[package]] name = "subtle" version = "2.5.0" @@ -1691,7 +1753,9 @@ checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "libc", "num-conv", + "num_threads", "powerfmt", "serde", "time-core", @@ -1989,6 +2053,43 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "venial" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61584a325b16f97b5b25fcc852eb9550843a251057a5e3e5992d2376f3df4bb2" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "vergen" +version = "9.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349ed9e45296a581f455bc18039878f409992999bc1d5da12a6800eb18c8752f" +dependencies = [ + "anyhow", + "cargo_metadata 0.18.1", + "derive_builder", + "regex", + "rustc_version", + "rustversion", + "time", + "vergen-lib", +] + +[[package]] +name = "vergen-lib" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229eaddb0050920816cf051e619affaf18caa3dd512de8de5839ccbc8e53abb0" +dependencies = [ + "anyhow", + "derive_builder", + "rustversion", +] + [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index 7cfa9d2..04a2dd1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,10 +3,14 @@ name = "shibe-bot" description = "A Discord bot written in Rust, using Poise." license = "MIT" readme = "README.md" -version = "0.3.4" +version = "0.4.0" edition = "2021" +build = "build.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[build-dependencies] +vergen = { version = "9.0.1", features = ["build", "cargo", "rustc"] } +anyhow = "1.0.89" [dependencies] dotenvy = "0.15.0" @@ -18,5 +22,4 @@ rand = "0.8.5" serde = { version = "1.0.210", features = ["serde_derive"] } serde_json = "1.0.128" roux = "2.2.13" -rustc_version_runtime = "0.3.0" -build-time = "0.1.3" +structstruck = "0.4.1" diff --git a/README.md b/README.md index dce9411..7d4f3e8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Shibe Bot 0.3.4 +# Shibe Bot 0.4.0 [![Rust](https://github.com/shibedrill/shibe-bot/actions/workflows/rust.yml/badge.svg)](https://github.com/shibedrill/shibe-bot/actions/workflows/rust.yml) [![GitHub License](https://img.shields.io/github/license/shibedrill/shibe-bot)](LICENSE.txt) diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..95eaa26 --- /dev/null +++ b/build.rs @@ -0,0 +1,16 @@ + +use vergen::*; +use anyhow::Error; + +fn main() -> Result<(), Error> { + let build = BuildBuilder::all_build()?; + let cargo = CargoBuilder::all_cargo()?; + let rustc = RustcBuilder::all_rustc()?; + + Emitter::default() + .add_instructions(&build)? + .add_instructions(&cargo)? + .add_instructions(&rustc)? + .emit()?; + Ok(()) +} \ No newline at end of file diff --git a/src/command/devel.rs b/src/command/devel.rs index c4265ce..46ef861 100644 --- a/src/command/devel.rs +++ b/src/command/devel.rs @@ -1,8 +1,25 @@ -use build_time::build_time_local; use crate::Context; use crate::Error; +#[poise::command(slash_command)] +pub async fn version(ctx: Context<'_>) -> Result<(), Error> { + ctx.say(format!( + "Bot version: {}\n\ + Build:\n\ + \tBuild date: {}\n\ + \tBuild timestamp: {}\n\ + \tTarget triple: {}\n\ + \trustc version: {}\n", + env!("CARGO_PKG_VERSION"), + env!("VERGEN_BUILD_DATE"), + env!("VERGEN_BUILD_TIMESTAMP"), + env!("VERGEN_CARGO_TARGET_TRIPLE"), + env!("VERGEN_RUSTC_SEMVER"), + )).await?; + Ok(()) +} + /// Update the bot remotely (Requires updater systemd service) #[poise::command(slash_command, owners_only, hide_in_help)] pub async fn update(ctx: Context<'_>) -> Result<(), Error> { @@ -19,7 +36,7 @@ pub async fn update(ctx: Context<'_>) -> Result<(), Error> { Current version: {}\n\ Timestamp of last build: {}", env!("CARGO_PKG_VERSION"), - build_time_local!() + env!("VERGEN_BUILD_TIMESTAMP") )) .await?; info!("Initialized restart service successfully"); diff --git a/src/command/util.rs b/src/command/util.rs index 7e8ed0a..a96a1ba 100644 --- a/src/command/util.rs +++ b/src/command/util.rs @@ -4,8 +4,6 @@ use rand::Rng; use crate::Context; use crate::Error; -use build_time::build_time_local; - const INVITE_LINK: &str = "https://discord.com/oauth2/authorize?client_id=1030701552941412382&permissions=116736&response_type=code&redirect_uri=https%3A%2F%2Fdiscordapp.com%2Foauth2%2Fauthorize%3F%26client_id%3D1030701552941412382%26scope%3Dbot&scope=guilds+bot"; /// Add this bot to your server @@ -48,84 +46,14 @@ pub async fn info(ctx: Context<'_>) -> Result<(), Error> { Poise: \n\ Rust: ", env!("CARGO_PKG_VERSION"), - rustc_version_runtime::version(), - build_time_local!() + env!("VERGEN_RUSTC_SEMVER"), + env!("VERGEN_BUILD_TIMESTAMP"), )) .await?; info!("Executed command `info` successfully"); Ok(()) } -/// Add channel to the registry -#[poise::command(slash_command, required_permissions = "MANAGE_CHANNELS")] -pub async fn add_channel( - ctx: Context<'_>, - #[description = "Selected channel"] channel: serenity::Channel, -) -> Result<(), Error> { - ctx.defer_ephemeral().await?; - let config = &mut ctx.data().config_manager.lock().await; - let channel_id = { u64::from(channel.id()) }; - match config.channels.iter().find(|item| **item == channel_id) { - None => { - config.channels.push(channel_id); - ctx.say(format!( - "Successfully added <#{channel_id}> to the channel registry." - )) - .await?; - } - Some(_) => { - ctx.say(format!("Channel <#{channel_id}> is already in registry.")) - .await?; - } - } - config.store().expect("Unable to store config"); - info!("Executed command `add_channel` successfully"); - Ok(()) -} - -/// Remove channel from the registry -#[poise::command(slash_command, required_permissions = "MANAGE_CHANNELS")] -pub async fn remove_channel( - ctx: Context<'_>, - #[description = "Selected channel"] channel: serenity::Channel, -) -> Result<(), Error> { - ctx.defer_ephemeral().await?; - let config = &mut ctx.data().config_manager.lock().await; - let channel_id = { u64::from(channel.id()) }; - match config.channels.iter().position(|item| *item == channel_id) { - None => { - ctx.say(format!( - "Channel <#{channel_id}> was not in the channel registry." - )) - .await?; - } - Some(found) => { - config.channels.remove(found); - ctx.say(format!( - "Successfully removed <#{channel_id}> from the channel registry." - )) - .await?; - } - } - config.store().expect("Unable to store config"); - info!("Executed command `remove_channel` successfully"); - Ok(()) -} - -/// List channels held in the registry -#[poise::command(slash_command, required_permissions = "MANAGE_CHANNELS")] -pub async fn list_channels(ctx: Context<'_>) -> Result<(), Error> { - ctx.defer_ephemeral().await?; - let config = &mut ctx.data().config_manager.lock().await; - ctx.say(format!( - "Current channel IDs in registry: \n{:#?}", - config.channels - )) - .await?; - info!("Executed command `list_channels` successfully"); - Ok(()) -} - /// Roll a dice with a certain amount of sides, 2 sides is a coin toss #[poise::command(slash_command)] pub async fn dice( diff --git a/src/definitions.rs b/src/definitions.rs new file mode 100644 index 0000000..e95ca7d --- /dev/null +++ b/src/definitions.rs @@ -0,0 +1,30 @@ +// Tokio async crap + +use poise::serenity_prelude as serenity; + +#[allow(unused_imports)] +use crate::settings::*; + +// Data passed to every command (shared state) +pub struct Data { + +} + +// Errors returnable by a command +pub type Error = Box; + +// The full context passed to a command +pub type Context<'a> = poise::Context<'a, Data, Error>; + +pub async fn event_handler( + _ctx: &serenity::Context, + _event: &serenity::FullEvent, + _framework: poise::FrameworkContext<'_, Data, Error>, + _data: &Data, +) -> Result<(), Error> { + + // Future event handling will go here + // Data will contain the database connection + + Ok(()) +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 3ba4a20..83ddd97 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,5 @@ #![forbid(unsafe_code)] -// Tokio async crap -use poise::serenity_prelude::FullEvent; -use std::sync::Arc; -use tokio::sync::Mutex; - // For secure credential handling use dotenvy::dotenv; @@ -16,10 +11,20 @@ extern crate pretty_env_logger; #[macro_use] extern crate log; -// For managing config storage -use serde::{Deserialize, Serialize}; +// Definitions +mod definitions; +use crate::definitions::*; +use crate::definitions::event_handler as event_handler; + +// Settings manager mod settings; -use crate::settings::Manager; +#[allow(unused_imports)] +use crate::settings::*; + +// Schema in preparation for database +mod schema; +#[allow(unused_imports)] +use crate::schema::*; // Bot commands mod command; @@ -32,46 +37,8 @@ use crate::command::{ util::*, }; -// Data passed to every command (shared state) -struct Data { - config_manager: Arc>>, -} - -// Errors returnable by a command -type Error = Box; - -// The full context passed to a command -type Context<'a> = poise::Context<'a, Data, Error>; - -// The structure making up the configuration -#[derive(Debug, Serialize, Deserialize, Default)] -struct Settings { - channels: Vec, -} - // Path at which our settings are stored (currently PWD) -const SETTINGS_PATH: &str = "settings.json"; - -async fn event_handler( - _ctx: &serenity::Context, - event: &serenity::FullEvent, - _framework: poise::FrameworkContext<'_, Data, Error>, - data: &Data, -) -> Result<(), Error> { - if let FullEvent::ChannelDelete { - channel, - messages: _, - } = event - { - info!("Handling event type: ChannelDelete({})", channel.id); - data.config_manager - .lock() - .await - .channels - .retain(|item| *item != u64::from(channel.id)); - } - Ok(()) -} +//const SETTINGS_PATH: &str = "settings.json"; // Main function for setup #[tokio::main] @@ -95,15 +62,6 @@ async fn main() { // Set up some non privileged intents let intents = serenity::GatewayIntents::non_privileged(); - // Configure persistent options - let config_manager: Arc>> = Arc::new(Mutex::new( - Manager::load(SETTINGS_PATH).unwrap_or(Manager::manage(SETTINGS_PATH, Settings::default())), - )); - match config_manager.lock().await.store() { - Ok(_) => info!("Stored config successfully"), - Err(e) => error!("Failed to store config: {}", e), - }; - // Set up framework let framework = poise::Framework::builder() .options(poise::FrameworkOptions { @@ -114,9 +72,6 @@ async fn main() { // Util age(), info(), - add_channel(), - remove_channel(), - list_channels(), invite(), dice(), // Dev @@ -141,7 +96,7 @@ async fn main() { Box::pin(async move { poise::builtins::register_globally(ctx, &framework.options().commands).await?; // Shared data has to go here!!! - Ok(Data { config_manager }) + Ok(Data {}) }) }) .build(); diff --git a/src/schema.rs b/src/schema.rs new file mode 100644 index 0000000..118691c --- /dev/null +++ b/src/schema.rs @@ -0,0 +1,19 @@ +use structstruck; +use poise::serenity_prelude::*; + +structstruck::strike! { + #[allow(dead_code)] + pub struct ReactionRole { + role: Role, + message: Message, + reaction: ReactionType, + variant: + #[allow(dead_code)] + enum ReactionRoleVariant { + Standard, + PermaAdd, + PermaRemove, + Reverse, + } + } +} \ No newline at end of file diff --git a/src/settings.rs b/src/settings.rs index a4dfb60..8408b19 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -10,6 +10,7 @@ pub struct Manager Deserialize<'a>> { path: String, } +#[allow(dead_code)] impl Deserialize<'a>> Manager { /// Instantiate new self if the path contains a valid serialization of /// the settings structure.