android_sms_gateway/types/
options.rs1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4use super::inbox::IncomingMessageType;
5
6#[derive(Debug, Clone, Default)]
8pub struct SendOptions {
9 pub skip_phone_validation: Option<bool>,
11 pub device_active_within: Option<u32>,
13}
14
15impl SendOptions {
16 pub fn new() -> Self {
17 Self::default()
18 }
19
20 pub fn with_skip_phone_validation(mut self, val: bool) -> Self {
21 self.skip_phone_validation = Some(val);
22 self
23 }
24
25 pub fn with_device_active_within(mut self, hours: u32) -> Self {
26 self.device_active_within = Some(hours);
27 self
28 }
29}
30
31impl ToQueryParams for SendOptions {
32 fn to_query_params(&self) -> Vec<(String, String)> {
33 let mut params = Vec::new();
34 if let Some(val) = self.skip_phone_validation {
35 params.push(("skipPhoneValidation".to_string(), val.to_string()));
36 }
37 if let Some(hours) = self.device_active_within {
38 params.push(("deviceActiveWithin".to_string(), hours.to_string()));
39 }
40 params
41 }
42}
43
44#[derive(Debug, Clone, Default)]
46pub struct ListInboxOptions {
47 pub message_type: Option<IncomingMessageType>,
49 pub limit: Option<i32>,
51 pub offset: Option<i32>,
53 pub from: Option<DateTime<Utc>>,
55 pub to: Option<DateTime<Utc>>,
57 pub device_id: Option<String>,
59 pub include_attachments: Option<bool>,
61}
62
63impl ListInboxOptions {
64 pub fn new() -> Self {
65 Self::default()
66 }
67
68 pub fn validate(&self) -> Result<(), crate::Error> {
69 if let (Some(ref from), Some(ref to)) = (self.from, self.to) {
70 if from > to {
71 return Err(crate::Error::Validation(
72 "`from` date must be before `to` date".to_string(),
73 ));
74 }
75 }
76 if let Some(limit) = self.limit {
77 if !(1..=100).contains(&limit) {
78 return Err(crate::Error::Validation(
79 "`limit` must be between 1 and 100".to_string(),
80 ));
81 }
82 }
83 if let Some(offset) = self.offset {
84 if offset < 0 {
85 return Err(crate::Error::Validation(
86 "`offset` must be non-negative".to_string(),
87 ));
88 }
89 }
90 Ok(())
91 }
92
93 pub fn with_message_type(mut self, val: IncomingMessageType) -> Self {
94 self.message_type = Some(val);
95 self
96 }
97
98 pub fn with_limit(mut self, val: i32) -> Self {
99 self.limit = Some(val);
100 self
101 }
102
103 pub fn with_offset(mut self, val: i32) -> Self {
104 self.offset = Some(val);
105 self
106 }
107
108 pub fn with_from(mut self, val: DateTime<Utc>) -> Self {
109 self.from = Some(val);
110 self
111 }
112
113 pub fn with_to(mut self, val: DateTime<Utc>) -> Self {
114 self.to = Some(val);
115 self
116 }
117
118 pub fn with_device_id(mut self, val: impl Into<String>) -> Self {
119 self.device_id = Some(val.into());
120 self
121 }
122
123 pub fn with_include_attachments(mut self, val: bool) -> Self {
124 self.include_attachments = Some(val);
125 self
126 }
127}
128
129impl ToQueryParams for ListInboxOptions {
130 fn to_query_params(&self) -> Vec<(String, String)> {
131 let mut params = Vec::new();
132 if let Some(ref val) = self.message_type {
133 let s = serde_json::to_string(val)
134 .map(|s| s.trim_matches('"').to_string())
135 .unwrap_or_else(|_| panic!("failed to serialize IncomingMessageType"));
136 params.push(("type".to_string(), s));
137 }
138 if let Some(val) = self.limit {
139 params.push(("limit".to_string(), val.to_string()));
140 }
141 if let Some(val) = self.offset {
142 params.push(("offset".to_string(), val.to_string()));
143 }
144 if let Some(ref val) = self.from {
145 params.push(("from".to_string(), val.to_rfc3339()));
146 }
147 if let Some(ref val) = self.to {
148 params.push(("to".to_string(), val.to_rfc3339()));
149 }
150 if let Some(ref val) = self.device_id {
151 params.push(("deviceId".to_string(), val.clone()));
152 }
153 if let Some(val) = self.include_attachments {
154 params.push(("includeAttachments".to_string(), val.to_string()));
155 }
156 params
157 }
158}
159
160#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
162pub enum MessagesSortOrder {
163 #[serde(rename = "created_at")]
164 CreatedAtAscending,
165 #[serde(rename = "-created_at")]
166 CreatedAtDescending,
167}
168
169#[derive(Debug, Clone, Default)]
171pub struct ListMessagesOptions {
172 pub from: Option<DateTime<Utc>>,
174 pub to: Option<DateTime<Utc>>,
176 pub state: Option<String>,
178 pub device_id: Option<String>,
180 pub limit: Option<i32>,
182 pub offset: Option<i32>,
184 pub include_content: Option<bool>,
186 pub sort: Option<MessagesSortOrder>,
188}
189
190impl ListMessagesOptions {
191 pub fn new() -> Self {
192 Self::default()
193 }
194
195 pub fn with_from(mut self, val: DateTime<Utc>) -> Self {
196 self.from = Some(val);
197 self
198 }
199
200 pub fn with_to(mut self, val: DateTime<Utc>) -> Self {
201 self.to = Some(val);
202 self
203 }
204
205 pub fn with_state(mut self, val: impl Into<String>) -> Self {
206 self.state = Some(val.into());
207 self
208 }
209
210 pub fn with_device_id(mut self, val: impl Into<String>) -> Self {
211 self.device_id = Some(val.into());
212 self
213 }
214
215 pub fn with_limit(mut self, val: i32) -> Self {
216 self.limit = Some(val);
217 self
218 }
219
220 pub fn with_offset(mut self, val: i32) -> Self {
221 self.offset = Some(val);
222 self
223 }
224
225 pub fn with_include_content(mut self, val: bool) -> Self {
226 self.include_content = Some(val);
227 self
228 }
229
230 pub fn with_sort(mut self, val: MessagesSortOrder) -> Self {
231 self.sort = Some(val);
232 self
233 }
234
235 pub fn validate(&self) -> Result<(), crate::Error> {
236 if let (Some(ref from), Some(ref to)) = (self.from, self.to) {
237 if from > to {
238 return Err(crate::Error::Validation(
239 "`from` date must be before `to` date".to_string(),
240 ));
241 }
242 }
243 if let Some(limit) = self.limit {
244 if !(1..=100).contains(&limit) {
245 return Err(crate::Error::Validation(
246 "`limit` must be between 1 and 100".to_string(),
247 ));
248 }
249 }
250 if let Some(offset) = self.offset {
251 if offset < 0 {
252 return Err(crate::Error::Validation(
253 "`offset` must be non-negative".to_string(),
254 ));
255 }
256 }
257 Ok(())
258 }
259}
260
261impl ToQueryParams for ListMessagesOptions {
262 fn to_query_params(&self) -> Vec<(String, String)> {
263 let mut params = Vec::new();
264 if let Some(ref val) = self.from {
265 params.push(("from".to_string(), val.to_rfc3339()));
266 }
267 if let Some(ref val) = self.to {
268 params.push(("to".to_string(), val.to_rfc3339()));
269 }
270 if let Some(ref val) = self.state {
271 params.push(("state".to_string(), val.clone()));
272 }
273 if let Some(ref val) = self.device_id {
274 params.push(("deviceId".to_string(), val.clone()));
275 }
276 if let Some(val) = self.limit {
277 params.push(("limit".to_string(), val.to_string()));
278 }
279 if let Some(val) = self.offset {
280 params.push(("offset".to_string(), val.to_string()));
281 }
282 if let Some(val) = self.include_content {
283 params.push(("includeContent".to_string(), val.to_string()));
284 }
285 if let Some(ref val) = self.sort {
286 let s = serde_json::to_value(val)
287 .ok()
288 .and_then(|v| v.as_str().map(String::from))
289 .unwrap_or_default();
290 params.push(("sort".to_string(), s));
291 }
292 params
293 }
294}
295
296pub trait ToQueryParams {
298 fn to_query_params(&self) -> Vec<(String, String)>;
300
301 fn to_url_query(&self) -> String {
303 let pairs = self.to_query_params();
304 if pairs.is_empty() {
305 return String::new();
306 }
307 let mut serializer = url::form_urlencoded::Serializer::new(String::new());
308 for (key, value) in &pairs {
309 serializer.append_pair(key, value);
310 }
311 serializer.finish()
312 }
313}