1use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct Update {
12 pub update_id: i64,
14
15 #[serde(skip_serializing_if = "Option::is_none")]
17 pub message: Option<Message>,
18
19 #[serde(skip_serializing_if = "Option::is_none")]
21 pub callback_query: Option<CallbackQuery>,
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct Message {
28 pub message_id: i64,
30
31 #[serde(skip_serializing_if = "Option::is_none")]
33 pub from: Option<User>,
34
35 pub chat: Chat,
37
38 pub date: i64,
40
41 #[serde(skip_serializing_if = "Option::is_none")]
43 pub text: Option<String>,
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize)]
49pub struct User {
50 pub id: i64,
52
53 pub is_bot: bool,
55
56 pub first_name: String,
58
59 #[serde(skip_serializing_if = "Option::is_none")]
61 pub last_name: Option<String>,
62
63 #[serde(skip_serializing_if = "Option::is_none")]
65 pub username: Option<String>,
66
67 #[serde(skip_serializing_if = "Option::is_none")]
69 pub language_code: Option<String>,
70}
71
72#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct Chat {
76 pub id: i64,
78
79 #[serde(rename = "type")]
81 pub chat_type: String,
82
83 #[serde(skip_serializing_if = "Option::is_none")]
85 pub title: Option<String>,
86
87 #[serde(skip_serializing_if = "Option::is_none")]
89 pub username: Option<String>,
90
91 #[serde(skip_serializing_if = "Option::is_none")]
93 pub first_name: Option<String>,
94}
95
96#[derive(Debug, Clone, Serialize, Deserialize)]
99pub struct CallbackQuery {
100 pub id: String,
102
103 pub from: User,
105
106 #[serde(skip_serializing_if = "Option::is_none")]
108 pub message: Option<Message>,
109
110 #[serde(skip_serializing_if = "Option::is_none")]
112 pub data: Option<String>,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize)]
117pub struct SendMessageRequest {
118 pub chat_id: i64,
120
121 pub text: String,
123
124 #[serde(skip_serializing_if = "Option::is_none")]
126 pub parse_mode: Option<String>,
127
128 #[serde(skip_serializing_if = "Option::is_none")]
130 pub reply_markup: Option<InlineKeyboard>,
131}
132
133#[derive(Debug, Clone, Serialize, Deserialize)]
136pub struct InlineKeyboard {
137 pub inline_keyboard: Vec<Vec<InlineKeyboardButton>>,
139}
140
141#[derive(Debug, Clone, Serialize, Deserialize)]
144pub struct InlineKeyboardButton {
145 pub text: String,
147
148 #[serde(skip_serializing_if = "Option::is_none")]
150 pub callback_data: Option<String>,
151
152 #[serde(skip_serializing_if = "Option::is_none")]
154 pub url: Option<String>,
155}
156
157#[derive(Debug, Clone, Serialize, Deserialize)]
159pub struct ApiResponse<T> {
160 pub ok: bool,
162
163 #[serde(skip_serializing_if = "Option::is_none")]
165 pub result: Option<T>,
166
167 #[serde(skip_serializing_if = "Option::is_none")]
169 pub description: Option<String>,
170}
171
172impl InlineKeyboard {
173 pub fn new(rows: Vec<Vec<InlineKeyboardButton>>) -> Self {
175 Self {
176 inline_keyboard: rows,
177 }
178 }
179
180 pub fn single_row(buttons: Vec<InlineKeyboardButton>) -> Self {
182 Self::new(vec![buttons])
183 }
184}
185
186impl InlineKeyboardButton {
187 pub fn callback(text: impl Into<String>, data: impl Into<String>) -> Self {
189 Self {
190 text: text.into(),
191 callback_data: Some(data.into()),
192 url: None,
193 }
194 }
195
196 pub fn url(text: impl Into<String>, url: impl Into<String>) -> Self {
198 Self {
199 text: text.into(),
200 callback_data: None,
201 url: Some(url.into()),
202 }
203 }
204}