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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
use serde::{Deserialize, Serialize};

use crate::{
    api::{Method, Payload},
    types::{InlineQueryResult, InlineQueryResultsButton, Integer, Location, User},
};

#[cfg(test)]
mod tests;

/// Represents an incoming inline query.
///
/// When the user sends an empty query, your bot could return some default or trending results.
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
pub struct InlineQuery {
    /// Sender of the query.
    pub from: User,
    /// Unique identifier of the query.
    pub id: String,
    /// Offset of the results to be returned, can be controlled by the bot.
    pub offset: String,
    /// Text of the query; up to 256 characters.
    pub query: String,
    /// Type of the chat, from which the inline query was sent.
    ///
    /// Can be either “sender” for a private chat with the inline query sender,
    /// “private”, “group”, “supergroup”, or “channel”.
    /// The chat type should be always known for requests sent from official
    /// clients and most third-party clients,
    /// unless the request was sent from a secret chat.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub chat_type: Option<InlineQueryChatType>,
    /// Sender location, only for bots that request user location.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub location: Option<Location>,
}

impl InlineQuery {
    /// Creates a new `InlineQuery`.
    ///
    /// # Arguments
    ///
    /// * `from` - Sender of the query.
    /// * `id` - Unique identifier of the query.
    /// * `offset` - Offset of the results.
    /// * `query` - Text of the query; up to 256 characters.
    pub fn new<A, B, C>(from: User, id: A, offset: B, query: C) -> Self
    where
        A: Into<String>,
        B: Into<String>,
        C: Into<String>,
    {
        Self {
            from,
            id: id.into(),
            offset: offset.into(),
            query: query.into(),
            chat_type: None,
            location: None,
        }
    }

    /// Sets a new chat type.
    ///
    /// # Arguments
    ///
    /// * `value` - Type of the chat, from which the inline query was sent.
    pub fn with_chat_type(mut self, value: InlineQueryChatType) -> Self {
        self.chat_type = Some(value);
        self
    }

    /// Sets a new location.
    ///
    /// # Arguments
    ///
    /// * `value` - Sender location.
    pub fn with_location(mut self, value: Location) -> Self {
        self.location = Some(value);
        self
    }
}

/// Represents a type of the chat, from which the inline query was sent.
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum InlineQueryChatType {
    /// A private chat with the sender of the inline query.
    Sender,
    /// A private chat.
    Private,
    /// A group chat.
    Group,
    /// A supergroup chat.
    Supergroup,
    /// A channel chat.
    Channel,
}

/// Sends an answer to an inline query.
///
/// No more than 50 results per query are allowed.
#[derive(Clone, Debug, Serialize)]
pub struct AnswerInlineQuery {
    inline_query_id: String,
    results: Vec<InlineQueryResult>,
    #[serde(skip_serializing_if = "Option::is_none")]
    button: Option<InlineQueryResultsButton>,
    #[serde(skip_serializing_if = "Option::is_none")]
    cache_time: Option<Integer>,
    #[serde(skip_serializing_if = "Option::is_none")]
    is_personal: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    next_offset: Option<String>,
}

impl AnswerInlineQuery {
    /// Creates a new `AnswerInlineQuery`.
    ///
    /// # Arguments
    ///
    /// * `inline_query_id` - Unique identifier of the answered query.
    /// * `results` - An array of results.
    pub fn new<A, B>(inline_query_id: A, results: B) -> Self
    where
        A: Into<String>,
        B: IntoIterator<Item = InlineQueryResult>,
    {
        Self {
            inline_query_id: inline_query_id.into(),
            results: results.into_iter().collect(),
            button: None,
            cache_time: None,
            is_personal: None,
            next_offset: None,
        }
    }

    /// Sets a new button.
    ///
    /// # Arguments
    ///
    /// * `value` - An object describing a button to be shown above inline query results.
    pub fn with_button(mut self, value: InlineQueryResultsButton) -> Self {
        self.button = Some(value);
        self
    }

    /// Sets a new cache time.
    ///
    /// # Arguments
    ///
    /// * `value` - Maximum amount of time in seconds that the result
    ///             of the inline query may be cached on the server;
    ///             default - 300.
    pub fn with_cache_time(mut self, value: Integer) -> Self {
        self.cache_time = Some(value);
        self
    }

    /// Sets a new value for an `is_personal` flag.
    ///
    /// # Arguments
    ///
    /// * `value` - Indicates whether the cache results on the server side
    ///             are only for the user that sent the query;
    ///             by default, results may be returned to any user who sends the same query.
    pub fn with_is_personal(mut self, value: bool) -> Self {
        self.is_personal = Some(value);
        self
    }

    /// Sets a new next offset.
    ///
    ///
    /// # Arguments
    ///
    /// * `value` - Offset that a client should send in the next query with
    ///             the same text to receive more results.
    ///
    /// Pass an empty string if there are no more results or if you don‘t support pagination.
    /// Offset length can’t exceed 64 bytes.
    pub fn with_next_offset<T>(mut self, value: T) -> Self
    where
        T: Into<String>,
    {
        self.next_offset = Some(value.into());
        self
    }
}

impl Method for AnswerInlineQuery {
    type Response = bool;

    fn into_payload(self) -> Payload {
        Payload::json("answerInlineQuery", self)
    }
}