checkbox_list/
checkbox_list.rs1use derive_more::Display;
5use serde::{Deserialize, Serialize};
6use teloxide::{dispatching::dialogue::InMemStorage, prelude::*, types::InlineKeyboardMarkup};
7use teloxide_inline_widgets::prelude::*;
8
9type Bot = teloxide::Bot;
10type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
11type HandlerResult = Result<(), Error>;
12type UpdateHandler = teloxide::dispatching::UpdateHandler<Error>;
13type Storage = InMemStorage<State>;
14type Dialogue = teloxide::dispatching::dialogue::Dialogue<State, Storage>;
15
16type OptionsCheckboxList = CheckboxList<Options, OptionsCLS>;
17
18#[derive(Debug, Default, Clone, Deserialize, Serialize)]
19enum State {
20 #[default]
21 Idle,
22 EditingWidget(Widget),
23}
24
25#[derive(Debug, Clone, Deserialize, Serialize)]
26struct Widget {
27 pub options: OptionsCheckboxList,
28}
29
30#[derive(Debug, Display, Clone, Deserialize, Serialize)]
31enum Options {
32 A,
33 B,
34 C,
35}
36
37#[derive(Debug, Clone, Copy, Deserialize, Serialize)]
38pub struct OptionsCLS;
39
40impl CheckboxListSettings for OptionsCLS {
41 fn prefix() -> &'static str {
42 "o_"
43 }
44
45 fn size() -> (u8, u8) {
46 (3, 1)
48 }
49}
50
51impl UserDefinedWidget for Widget {
52 type Err = Error;
53 type Bot = Bot;
54 type Dialogue = Dialogue;
55
56 fn schema() -> UpdateHandler {
57 dptree::entry().branch(OptionsCheckboxList::schema::<Self>())
58 }
59
60 fn inline_keyboard_markup(&self) -> InlineKeyboardMarkup {
61 InlineKeyboardMarkup::new(self.options.keyboard())
62 }
63
64 async fn update_state(self, dialogue: &Self::Dialogue) -> Result<(), Self::Err> {
65 dialogue.update(State::EditingWidget(self)).await?;
66
67 Ok(())
68 }
69}
70
71impl WidgetContainer<OptionsCheckboxList> for Widget {
72 fn get_widget(&mut self) -> &mut OptionsCheckboxList {
73 &mut self.options
74 }
75}
76
77#[tokio::main]
78async fn main() {
79 pretty_env_logger::init();
80
81 log::info!("Example \"checkbox_list\" started..");
82
83 let state_storage = InMemStorage::<State>::new();
84
85 Dispatcher::builder(Bot::from_env(), schema())
86 .dependencies(dptree::deps![state_storage])
87 .build()
88 .dispatch()
89 .await;
90}
91
92fn schema() -> UpdateHandler {
93 dptree::entry()
94 .branch(
95 Update::filter_message()
96 .enter_dialogue::<Message, Storage, State>()
97 .endpoint(send_widget),
98 )
99 .branch(
100 Update::filter_callback_query()
101 .enter_dialogue::<CallbackQuery, Storage, State>()
102 .branch(dptree::case![State::EditingWidget(_w)].branch(Widget::schema())),
103 )
104}
105
106async fn send_widget(bot: Bot, dialogue: Dialogue, message: Message) -> HandlerResult {
107 let options = CheckboxList::new([Options::A, Options::B, Options::C]);
108
109 let widget = Widget { options };
110
111 bot.send_message(message.chat.id, "Choose options:")
112 .reply_markup(widget.inline_keyboard_markup())
113 .await?;
114
115 dialogue.update(State::EditingWidget(widget)).await?;
116
117 Ok(())
118}