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}