Initialize Twilight project, set up basic framework, initialize DB module

This commit is contained in:
2025-08-07 04:32:34 -03:00
parent 00d61545eb
commit 24d2344f37
29 changed files with 4095 additions and 0 deletions
+103
View File
@@ -0,0 +1,103 @@
use std::sync::Arc;
use async_trait::async_trait;
use twilight_model::channel::message::{
Component as TwilightComponent,
component::{ActionRow as TwilightActionRow, Button as TwilightButton, ButtonStyle},
};
use crate::framework::interactions::{InteractionError, context::InteractionContext};
pub struct ActionRow {
components: Vec<(Option<String>, Arc<dyn Component>)>,
}
impl ActionRow {
pub fn new(components: &[(Option<String>, Arc<dyn Component>)]) -> Self {
Self {
components: components.to_vec(),
}
}
pub fn add(&mut self, id: Option<String>, component: Arc<dyn Component>) {
self.components.push((id, component));
}
pub fn len(&self) -> usize {
self.components.len()
}
pub fn build(self) -> TwilightComponent {
TwilightComponent::ActionRow(TwilightActionRow {
components: self
.components
.into_iter()
.map(|(id, c)| c.build(id))
.collect(),
})
}
}
#[async_trait]
pub trait Component: Send + Sync {
fn custom_id(&self) -> Option<String> {
Some(String::from("component"))
}
fn build(&self, id: Option<String>) -> TwilightComponent;
async fn execute(&self, ctx: InteractionContext) -> Result<(), InteractionError>;
}
#[async_trait]
impl<T> Component for T
where
T: Button,
{
fn custom_id(&self) -> Option<String> {
Button::id(self)
}
fn build(&self, id: Option<String>) -> TwilightComponent {
TwilightComponent::Button(TwilightButton {
custom_id: id,
disabled: false,
emoji: None,
label: self.label().map(|i| i.to_string()),
style: if self.url().is_none() {
self.style()
} else {
ButtonStyle::Link
},
url: self.url().map(|i| i.to_string()),
sku_id: None,
})
}
async fn execute(&self, ctx: InteractionContext) -> Result<(), InteractionError> {
self.on_press(ctx).await
}
}
#[async_trait]
pub trait Button: Send + Sync {
fn id(&self) -> Option<String> {
if self.url().is_none() {
Some(String::from("Button"))
} else {
None
}
}
fn style(&self) -> ButtonStyle {
ButtonStyle::Secondary
}
fn label(&self) -> Option<&'static str> {
None
}
fn url(&self) -> Option<&'static str> {
None
}
async fn on_press(&self, ctx: InteractionContext) -> Result<(), InteractionError> {
ctx.defer().await
}
}