tgbot/types/definitions/
location.rs

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