use serde::{Deserialize, Serialize};
pub struct Button<S: Send + Sync + 'static> {
pub(crate) name: String,
pub(crate) handler: ButtonHandlerVariant<S>,
}
impl<S: Send + Sync + 'static> Button<S> {
fn new(name: &str, handler: ButtonHandlerVariant<S>) -> Button<S> {
Button {
name: name.to_string(),
handler,
}
}
pub fn create_basic_button(
name: &str,
handler: Box<dyn Send + Sync + Fn() -> ButtonResponse>,
) -> Button<S> {
Button::new(name, ButtonHandlerVariant::Basic(handler))
}
pub fn create_button_with_state(
name: &str,
handler: Box<dyn Send + Sync + Fn(&S) -> ButtonResponse>,
) -> Button<S> {
Button::new(name, ButtonHandlerVariant::WithState(handler))
}
pub fn create_button_with_prompts(
name: &str,
handler: Box<dyn Send + Sync + Fn(Vec<ExtraResponse>) -> ButtonResponse>,
extra_prompts: Vec<String>,
) -> Button<S> {
Button::new(
name,
ButtonHandlerVariant::WithExtraPrompts(handler, extra_prompts),
)
}
pub fn create_button_with_state_and_prompts(
name: &str,
handler: Box<dyn Send + Sync + Fn(&S, Vec<ExtraResponse>) -> ButtonResponse>,
extra_prompts: Vec<String>,
) -> Button<S> {
Button::new(name, ButtonHandlerVariant::WithBoth(handler, extra_prompts))
}
}
pub(crate) enum ButtonHandlerVariant<S: Send + Sync + 'static> {
Basic(Box<dyn Send + Sync + Fn() -> ButtonResponse>),
WithState(Box<dyn Send + Sync + Fn(&S) -> ButtonResponse>),
WithExtraPrompts(
Box<dyn Send + Sync + Fn(Vec<ExtraResponse>) -> ButtonResponse>,
Vec<String>,
),
WithBoth(
Box<dyn Send + Sync + Fn(&S, Vec<ExtraResponse>) -> ButtonResponse>,
Vec<String>,
),
}
#[derive(Deserialize, Debug)]
pub(crate) struct ButtonInfo {
pub id: usize,
pub extra_responses: Vec<ExtraResponse>,
}
#[derive(Serialize)]
pub struct ButtonResponse {
pub message: String,
}
impl From<&str> for ButtonResponse {
fn from(message: &str) -> Self {
ButtonResponse {
message: message.to_string(),
}
}
}
impl From<String> for ButtonResponse {
fn from(message: String) -> Self {
ButtonResponse { message }
}
}
pub type ExtraResponse = Option<String>;