tgbot/types/location/mod.rs
1use serde::{Deserialize, Serialize};
2
3use crate::{
4 api::{Method, Payload},
5 types::{ChatId, Float, Integer, Message, ReplyMarkup, ReplyParameters},
6};
7
8#[cfg(test)]
9mod tests;
10
11/// Represents a point on a map.
12#[serde_with::skip_serializing_none]
13#[derive(Clone, Copy, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
14pub struct Location {
15 /// Latitude as defined by sender.
16 pub latitude: Float,
17 /// Longitude as defined by sender.
18 pub longitude: Float,
19 /// The direction in which user is moving; in degrees; 1-360.
20 ///
21 /// For active live locations only.
22 pub heading: Option<Integer>,
23 /// The radius of uncertainty for the location, measured in meters; 0-1500.
24 pub horizontal_accuracy: Option<Float>,
25 /// Time relative to the message sending date,
26 /// during which the location can be updated, in seconds.
27 ///
28 /// For active live locations only.
29 pub live_period: Option<Integer>,
30 /// Maximum distance for proximity alerts about
31 /// approaching another chat member; in meters.
32 ///
33 /// For sent live locations only.
34 pub proximity_alert_radius: Option<Integer>,
35}
36
37impl Location {
38 /// Creates a new `Location`.
39 ///
40 /// # Arguments
41 ///
42 /// * `latitude` - Latitude.
43 /// * `longitude` - Longitude.
44 pub fn new(latitude: Float, longitude: Float) -> Self {
45 Self {
46 latitude,
47 longitude,
48 heading: None,
49 horizontal_accuracy: None,
50 live_period: None,
51 proximity_alert_radius: None,
52 }
53 }
54
55 /// Sets a new heading.
56 ///
57 /// # Arguments
58 ///
59 /// * `value` - A direction in which the user is moving; in degrees; 1-360.
60 pub fn with_heading(mut self, value: Integer) -> Self {
61 self.heading = Some(value);
62 self
63 }
64
65 /// Sets a new horizontal accuracy.
66 ///
67 /// # Arguments
68 ///
69 /// * `value` - A radius of uncertainty for the location; in meters; 0-1500.
70 pub fn with_horizontal_accuracy(mut self, value: Float) -> Self {
71 self.horizontal_accuracy = Some(value);
72 self
73 }
74
75 /// Sets a new live period.
76 ///
77 /// # Arguments
78 ///
79 /// * `value` - Period in seconds for which the location can be updated; 60-86400.
80 pub fn with_live_period(mut self, value: Integer) -> Self {
81 self.live_period = Some(value);
82 self
83 }
84
85 /// Sets a new proximity alert radius.
86 ///
87 /// # Arguments
88 ///
89 /// * `value` - A maximum distance for proximity alerts
90 /// about approaching another chat member; in meters; 1-100000.
91 pub fn with_proximity_alert_radius(mut self, value: Integer) -> Self {
92 self.proximity_alert_radius = Some(value);
93 self
94 }
95}
96
97/// Describes the physical address of a location.
98#[serde_with::skip_serializing_none]
99#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
100pub struct LocationAddress {
101 /// The two-letter ISO 3166-1 alpha-2 country code of the country where the location is located.
102 pub country_code: String,
103 /// State of the location.
104 pub state: Option<String>,
105 /// City of the location.
106 pub city: Option<String>,
107 /// Street address of the location.
108 pub street: Option<String>,
109}
110
111impl LocationAddress {
112 /// Creates a new `LocationAddress`.
113 ///
114 /// # Arguments
115 ///
116 /// * `country_code` - The two-letter ISO 3166-1 alpha-2 country code of the country where the location is located.
117 pub fn new<T>(country_code: T) -> Self
118 where
119 T: Into<String>,
120 {
121 Self {
122 country_code: country_code.into(),
123 state: None,
124 city: None,
125 street: None,
126 }
127 }
128
129 /// Sets a new state.
130 ///
131 /// # Arguments
132 ///
133 /// * `value` - State of the location.
134 pub fn with_state<T>(mut self, value: T) -> Self
135 where
136 T: Into<String>,
137 {
138 self.state = Some(value.into());
139 self
140 }
141
142 /// Sets a new city.
143 ///
144 /// # Arguments
145 ///
146 /// * `value` - City of the location.
147 pub fn with_city<T>(mut self, value: T) -> Self
148 where
149 T: Into<String>,
150 {
151 self.city = Some(value.into());
152 self
153 }
154
155 /// Sets a new street.
156 ///
157 /// # Arguments
158 ///
159 /// * `value` - Street address of the location.
160 pub fn with_street<T>(mut self, value: T) -> Self
161 where
162 T: Into<String>,
163 {
164 self.street = Some(value.into());
165 self
166 }
167}
168
169/// Sends a point on a map.
170#[serde_with::skip_serializing_none]
171#[derive(Clone, Debug, Serialize)]
172pub struct SendLocation {
173 chat_id: ChatId,
174 latitude: Float,
175 longitude: Float,
176 allow_paid_broadcast: Option<bool>,
177 business_connection_id: Option<String>,
178 disable_notification: Option<bool>,
179 heading: Option<Integer>,
180 horizontal_accuracy: Option<Float>,
181 live_period: Option<Integer>,
182 message_effect_id: Option<String>,
183 message_thread_id: Option<Integer>,
184 protect_content: Option<bool>,
185 proximity_alert_radius: Option<Integer>,
186 reply_markup: Option<ReplyMarkup>,
187 reply_parameters: Option<ReplyParameters>,
188}
189
190impl SendLocation {
191 /// Creates a new `SendLocation`.
192 ///
193 /// # Arguments
194 ///
195 /// * `chat_id` - Unique identifier of the target chat.
196 /// * `latitude` - Latitude.
197 /// * `longitude` - Longitude.
198 pub fn new<T>(chat_id: T, latitude: Float, longitude: Float) -> Self
199 where
200 T: Into<ChatId>,
201 {
202 Self {
203 chat_id: chat_id.into(),
204 latitude,
205 longitude,
206 allow_paid_broadcast: None,
207 business_connection_id: None,
208 disable_notification: None,
209 heading: None,
210 horizontal_accuracy: None,
211 live_period: None,
212 message_effect_id: None,
213 message_thread_id: None,
214 protect_content: None,
215 proximity_alert_radius: None,
216 reply_markup: None,
217 reply_parameters: None,
218 }
219 }
220
221 /// Sets a new value for the `allow_paid_broadcast` flag.
222 ///
223 /// # Arguments
224 ///
225 /// * `value` - Whether to allow up to 1000 messages per second, ignoring broadcasting limits
226 /// for a fee of 0.1 Telegram Stars per message.
227 /// The relevant Stars will be withdrawn from the bot's balance.
228 pub fn with_allow_paid_broadcast(mut self, value: bool) -> Self {
229 self.allow_paid_broadcast = Some(value);
230 self
231 }
232
233 /// Sets a new business connection ID.
234 ///
235 /// # Arguments
236 ///
237 /// * `value` - Unique identifier of the business connection.
238 pub fn with_business_connection_id<T>(mut self, value: T) -> Self
239 where
240 T: Into<String>,
241 {
242 self.business_connection_id = Some(value.into());
243 self
244 }
245
246 /// Sets a new value for the `disable_notification` flag.
247 ///
248 /// # Arguments
249 ///
250 /// * `value` - Indicates whether to send the message silently or not;
251 /// a user will receive a notification without sound.
252 pub fn with_disable_notification(mut self, value: bool) -> Self {
253 self.disable_notification = Some(value);
254 self
255 }
256
257 /// Sets a new heading.
258 ///
259 /// # Arguments
260 ///
261 /// * `value` - A direction in which the user is moving; in degrees; 1-360.
262 pub fn with_heading(mut self, value: Integer) -> Self {
263 self.heading = Some(value);
264 self
265 }
266
267 /// Sets a new horizontal accuracy.
268 ///
269 /// # Arguments
270 ///
271 /// * `value` - A radius of uncertainty for the location; in meters; 0-1500.
272 pub fn with_horizontal_accuracy(mut self, value: Float) -> Self {
273 self.horizontal_accuracy = Some(value);
274 self
275 }
276
277 /// Sets a new live period.
278 ///
279 /// # Arguments
280 ///
281 /// * `value` - Period in seconds during which the location will be updated.
282 ///
283 /// See [Live Locations][1], should be between 60 and 86400,
284 /// or 0x7FFFFFFF for live locations that can be edited indefinitely.
285 ///
286 /// [1]: https://telegram.org/blog/live-locations
287 pub fn with_live_period(mut self, value: Integer) -> Self {
288 self.live_period = Some(value);
289 self
290 }
291
292 /// Sets a new message effect ID.
293 ///
294 /// # Arguments
295 ///
296 /// * `value` - Unique identifier of the message effect to be added to the message; for private chats only.
297 pub fn with_message_effect_id<T>(mut self, value: T) -> Self
298 where
299 T: Into<String>,
300 {
301 self.message_effect_id = Some(value.into());
302 self
303 }
304
305 /// Sets a new message thread ID.
306 ///
307 /// # Arguments
308 ///
309 /// * `value` - Unique identifier of the target message thread;
310 /// supergroups only.
311 pub fn with_message_thread_id(mut self, value: Integer) -> Self {
312 self.message_thread_id = Some(value);
313 self
314 }
315
316 /// Sets a new proximity alert radius.
317 ///
318 /// # Arguments
319 ///
320 /// * `value` - A maximum distance for proximity alerts
321 /// about approaching another chat member; in meters; 1-100000.
322 pub fn with_proximity_alert_radius(mut self, value: Integer) -> Self {
323 self.proximity_alert_radius = Some(value);
324 self
325 }
326
327 /// Sets a new value for the `protect_content` flag.
328 ///
329 /// # Arguments
330 ///
331 /// * `value` - Indicates whether to protect the contents
332 /// of the sent message from forwarding and saving.
333 pub fn with_protect_content(mut self, value: bool) -> Self {
334 self.protect_content = Some(value);
335 self
336 }
337
338 /// Sets a new reply markup.
339 ///
340 /// # Arguments
341 ///
342 /// * `value` - Reply markup.
343 pub fn with_reply_markup<T>(mut self, value: T) -> Self
344 where
345 T: Into<ReplyMarkup>,
346 {
347 self.reply_markup = Some(value.into());
348 self
349 }
350
351 /// Sets new reply parameters.
352 ///
353 /// # Arguments
354 ///
355 /// * `value` - Description of the message to reply to.
356 pub fn with_reply_parameters(mut self, value: ReplyParameters) -> Self {
357 self.reply_parameters = Some(value);
358 self
359 }
360}
361
362impl Method for SendLocation {
363 type Response = Message;
364
365 fn into_payload(self) -> Payload {
366 Payload::json("sendLocation", self)
367 }
368}