From 0795a07a2c83fadc5c8206f7cd078c910ad0e8a9 Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Sun, 25 Feb 2024 20:03:05 +0100 Subject: [PATCH] Introduce composed_framework to compose multiple frameworks --- youmubot/src/compose_framework.rs | 48 +++++++++++++++++++++++++++++++ youmubot/src/main.rs | 7 ++++- 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 youmubot/src/compose_framework.rs diff --git a/youmubot/src/compose_framework.rs b/youmubot/src/compose_framework.rs new file mode 100644 index 0000000..ec338d4 --- /dev/null +++ b/youmubot/src/compose_framework.rs @@ -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]>, +} + +impl ComposedFramework { + /// Create a new composed framework. + pub fn new(frameworks: Vec>) -> 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>` because rust. + fn dispatch_loop<'a>( + &'a self, + index: usize, + ctx: Context, + msg: FullEvent, + ) -> Pin + 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 + } + }) + } +} diff --git a/youmubot/src/main.rs b/youmubot/src/main.rs index 1a18019..5e28d41 100644 --- a/youmubot/src/main.rs +++ b/youmubot/src/main.rs @@ -1,3 +1,4 @@ +use compose_framework::ComposedFramework; use dotenv::var; use serenity::{ framework::standard::{ @@ -11,6 +12,8 @@ use serenity::{ }; use youmubot_prelude::*; +mod compose_framework; + struct Handler { hooks: Vec>>, } @@ -92,6 +95,8 @@ async fn main() { // Set up base framework let fw = setup_framework(&token[..]).await; + let composed = ComposedFramework::new(vec![Box::new(fw)]); + // Sets up a client let mut client = { // Attempt to connect and set up a framework @@ -105,7 +110,7 @@ async fn main() { | GatewayIntents::DIRECT_MESSAGES | GatewayIntents::DIRECT_MESSAGE_REACTIONS; Client::builder(token, intents) - .framework(fw) + .framework(composed) .event_handler(handler) .await .unwrap()