Introduce composed_framework to compose multiple frameworks

This commit is contained in:
Natsu Kagami 2024-02-25 20:03:05 +01:00
parent 431f295b41
commit 0795a07a2c
Signed by: nki
GPG key ID: 55A032EB38B49ADB
2 changed files with 54 additions and 1 deletions

View file

@ -0,0 +1,48 @@
use std::{future::Future, pin::Pin};
use serenity::{client::FullEvent, framework::Framework, model::channel::Message};
use youmubot_prelude::*;
/// A Framework to compose other frameworks.
pub(crate) struct ComposedFramework {
frameworks: Box<[Box<dyn Framework>]>,
}
impl ComposedFramework {
/// Create a new composed framework.
pub fn new(frameworks: Vec<Box<dyn Framework>>) -> Self {
Self {
frameworks: frameworks.into_boxed_slice(),
}
}
}
#[async_trait]
impl Framework for ComposedFramework {
async fn dispatch(&self, ctx: Context, msg: FullEvent) -> () {
if !self.frameworks.is_empty() {
self.dispatch_loop(self.frameworks.len() - 1, ctx, msg)
.await
}
}
}
impl ComposedFramework {
/// Dispatch to all inner frameworks in a loop. Returns a `Pin<Box<Future>>` because rust.
fn dispatch_loop<'a>(
&'a self,
index: usize,
ctx: Context,
msg: FullEvent,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
if index == 0 {
self.frameworks[index].dispatch(ctx, msg).await
} else {
self.frameworks[index]
.dispatch(ctx.clone(), msg.clone())
.await;
self.dispatch_loop(index - 1, ctx, msg).await
}
})
}
}

View file

@ -1,3 +1,4 @@
use compose_framework::ComposedFramework;
use dotenv::var; use dotenv::var;
use serenity::{ use serenity::{
framework::standard::{ framework::standard::{
@ -11,6 +12,8 @@ use serenity::{
}; };
use youmubot_prelude::*; use youmubot_prelude::*;
mod compose_framework;
struct Handler { struct Handler {
hooks: Vec<RwLock<Box<dyn Hook>>>, hooks: Vec<RwLock<Box<dyn Hook>>>,
} }
@ -92,6 +95,8 @@ async fn main() {
// Set up base framework // Set up base framework
let fw = setup_framework(&token[..]).await; let fw = setup_framework(&token[..]).await;
let composed = ComposedFramework::new(vec![Box::new(fw)]);
// Sets up a client // Sets up a client
let mut client = { let mut client = {
// Attempt to connect and set up a framework // Attempt to connect and set up a framework
@ -105,7 +110,7 @@ async fn main() {
| GatewayIntents::DIRECT_MESSAGES | GatewayIntents::DIRECT_MESSAGES
| GatewayIntents::DIRECT_MESSAGE_REACTIONS; | GatewayIntents::DIRECT_MESSAGE_REACTIONS;
Client::builder(token, intents) Client::builder(token, intents)
.framework(fw) .framework(composed)
.event_handler(handler) .event_handler(handler)
.await .await
.unwrap() .unwrap()