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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
use crate::types::{MessageEntity, PollType, User};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
/// This object contains information about a poll.
///
/// [The official docs](https://core.telegram.org/bots/api#poll).
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct Poll {
/// Unique poll identifier.
pub id: String,
/// Poll question, 1-255 characters.
pub question: String,
/// List of poll options.
pub options: Vec<PollOption>,
/// `true`, if the poll is closed.
pub is_closed: bool,
/// Total number of users that voted in the poll
pub total_voter_count: i32,
/// True, if the poll is anonymous
pub is_anonymous: bool,
/// Poll type, currently can be “regular” or “quiz”
#[serde(rename = "type")]
pub poll_type: PollType,
/// True, if the poll allows multiple answers
pub allows_multiple_answers: bool,
/// 0-based identifier of the correct answer option. Available only for
/// polls in the quiz mode, which are closed, or was sent (not
/// forwarded) by the bot or to the private chat with the bot.
pub correct_option_id: Option<u8>,
/// Text that is shown when a user chooses an incorrect answer or taps on
/// the lamp icon in a quiz-style poll, 0-200 characters.
pub explanation: Option<String>,
/// Special entities like usernames, URLs, bot commands, etc. that appear in
/// the explanation.
pub explanation_entities: Option<Vec<MessageEntity>>,
/// Amount of time in seconds the poll will be active after creation.
pub open_period: Option<u16>,
/// Point in time when the poll will be automatically closed.
#[serde(default, with = "crate::types::serde_opt_date_from_unix_timestamp")]
pub close_date: Option<DateTime<Utc>>,
}
/// This object contains information about one answer option in a poll.
///
/// [The official docs](https://core.telegram.org/bots/api#polloption).
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct PollOption {
/// Option text, 1-100 characters.
pub text: String,
/// Number of users that voted for this option.
pub voter_count: i32,
}
impl Poll {
/// Returns all users that are "contained" in this `Poll`
/// structure.
///
/// This might be useful to track information about users.
///
/// Note that this function can return duplicate users.
pub fn mentioned_users(&self) -> impl Iterator<Item = &User> {
use crate::util::{flatten, mentioned_users_from_entities};
flatten(self.explanation_entities.as_deref().map(mentioned_users_from_entities))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deserialize() {
let data = r#"
{
"allows_multiple_answers": false,
"id": "5377643193141559299",
"is_anonymous": true,
"is_closed": false,
"options": [
{
"text": "1",
"voter_count": 1
},
{
"text": "2",
"voter_count": 0
},
{
"text": "3",
"voter_count": 0
},
{
"text": "4",
"voter_count": 0
},
{
"text": "5",
"voter_count": 0
}
],
"question": "Rate me from 1 to 5.",
"total_voter_count": 1,
"type": "regular"
}
"#;
serde_json::from_str::<Poll>(data).unwrap();
}
}