1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
use crate::error::Result;
use serenity::builder::CreateMessage;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;

pub type MessageBuildOutput<'b> =
    Pin<Box<dyn Future<Output = Result<CreateMessage<'b>>> + Send + 'b>>;
pub type MessageBuilderFn<'b> = Arc<dyn Fn() -> MessageBuildOutput<'b> + Send + Sync>;

#[derive(Clone)]
/// A page that stores a builder function for message pages
/// or static pages
pub enum Page<'b> {
    Builder(MessageBuilderFn<'b>),
    Static(CreateMessage<'b>),
}

impl<'b> Page<'b> {
    /// Creates a new page with the given builder function that creates a page
    /// each time it is accessed
    pub fn new_builder<F: 'static>(builder_fn: F) -> Self
    where
        F: Fn() -> MessageBuildOutput<'b> + Send + Sync,
    {
        Self::Builder(Arc::new(builder_fn))
    }

    /// Creates a new page with a static message
    pub fn new_static(page: CreateMessage<'b>) -> Self {
        Self::Static(page)
    }

    /// Returns the CreateMessage of the page
    pub async fn get(&self) -> Result<CreateMessage<'b>> {
        match self {
            Page::Builder(b) => b().await,
            Page::Static(inner) => Ok(inner.clone()),
        }
    }
}