huawei_dongle_api/models/
sms.rs1use super::enums::{SmsBoxType, SmsPriority, SmsSortType, SmsStatus, SmsType};
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
25#[serde(rename = "response")]
26pub struct SmsCount {
27 #[serde(rename = "LocalUnread")]
28 pub local_unread: String,
29
30 #[serde(rename = "LocalInbox")]
31 pub local_inbox: String,
32
33 #[serde(rename = "LocalOutbox")]
34 pub local_outbox: String,
35
36 #[serde(rename = "LocalDraft")]
37 pub local_draft: String,
38
39 #[serde(rename = "SimUnread")]
40 pub sim_unread: String,
41
42 #[serde(rename = "SimInbox")]
43 pub sim_inbox: String,
44
45 #[serde(rename = "SimOutbox")]
46 pub sim_outbox: String,
47
48 #[serde(rename = "SimDraft")]
49 pub sim_draft: String,
50
51 #[serde(rename = "NewMsg")]
52 pub new_msg: String,
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
57#[serde(rename = "request")]
58pub struct SmsListRequest {
59 #[serde(rename = "PageIndex")]
60 pub page_index: String,
61
62 #[serde(rename = "ReadCount")]
63 pub read_count: String,
64
65 #[serde(rename = "BoxType")]
66 pub box_type: String,
67
68 #[serde(rename = "SortType")]
69 pub sort_type: String,
70
71 #[serde(rename = "Ascending")]
72 pub ascending: String,
73
74 #[serde(rename = "UnreadPreferred")]
75 pub unread_preferred: String,
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize)]
80#[serde(rename = "Message")]
81pub struct SmsMessage {
82 #[serde(rename = "Smstat")]
83 pub status: SmsStatus,
84
85 #[serde(rename = "Index")]
86 pub index: String,
87
88 #[serde(rename = "Phone")]
89 pub phone: String,
90
91 #[serde(rename = "Content")]
92 pub content: String,
93
94 #[serde(rename = "Date")]
95 pub date: String,
96
97 #[serde(rename = "Sca")]
98 pub sca: Option<String>,
99
100 #[serde(rename = "SaveType")]
101 pub save_type: String,
102
103 #[serde(rename = "Priority")]
104 pub priority: SmsPriority,
105
106 #[serde(rename = "SmsType")]
107 pub sms_type: SmsType,
108}
109
110#[derive(Debug, Clone, Serialize, Deserialize)]
112pub struct SmsMessages {
113 #[serde(rename = "$value", default)]
114 pub messages: Vec<SmsMessage>,
115}
116
117#[derive(Debug, Clone, Serialize, Deserialize)]
119#[serde(rename = "response")]
120pub struct SmsListResponse {
121 #[serde(rename = "Count", default)]
122 pub count: Option<String>,
123
124 #[serde(rename = "Messages")]
125 pub messages: SmsMessages,
126}
127
128impl SmsListResponse {
129 pub fn message_count(&self) -> usize {
131 if let Some(count_str) = &self.count {
132 count_str.parse().unwrap_or(self.messages.messages.len())
133 } else {
134 self.messages.messages.len()
135 }
136 }
137}
138
139#[derive(Debug, Clone, Serialize, Deserialize)]
141#[serde(rename = "request")]
142pub struct SmsDeleteRequest {
143 #[serde(rename = "Index")]
144 pub index: String,
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize)]
149#[serde(rename = "request")]
150pub struct SmsSetReadRequest {
151 #[serde(rename = "Index")]
152 pub index: String,
153}
154
155impl SmsCount {
156 pub fn total_unread(&self) -> Result<u32, std::num::ParseIntError> {
158 let local: u32 = self.local_unread.parse()?;
159 let sim: u32 = self.sim_unread.parse()?;
160 Ok(local + sim)
161 }
162
163 pub fn total_inbox(&self) -> Result<u32, std::num::ParseIntError> {
165 let local: u32 = self.local_inbox.parse()?;
166 let sim: u32 = self.sim_inbox.parse()?;
167 Ok(local + sim)
168 }
169
170 pub fn has_new_messages(&self) -> bool {
172 self.new_msg.parse::<u32>().unwrap_or(0) > 0
173 }
174}
175
176impl SmsListRequest {
177 pub fn new(
179 page_index: u32,
180 read_count: u32,
181 box_type: SmsBoxType,
182 sort_type: SmsSortType,
183 ascending: bool,
184 unread_preferred: bool,
185 ) -> Self {
186 Self {
187 page_index: page_index.to_string(),
188 read_count: read_count.to_string(),
189 box_type: box_type.to_string(),
190 sort_type: sort_type.to_string(),
191 ascending: if ascending { "1" } else { "0" }.to_string(),
192 unread_preferred: if unread_preferred { "1" } else { "0" }.to_string(),
193 }
194 }
195}
196
197impl SmsMessage {
198 pub fn is_unread(&self) -> bool {
200 self.status.is_unread()
201 }
202
203 pub fn is_read(&self) -> bool {
205 self.status.is_read()
206 }
207
208 pub fn id(&self) -> &str {
210 &self.index
211 }
212
213 pub fn phone_number(&self) -> &str {
215 &self.phone
216 }
217
218 pub fn text(&self) -> &str {
220 &self.content
221 }
222
223 pub fn date_str(&self) -> &str {
225 &self.date
226 }
227}
228
229impl SmsDeleteRequest {
230 pub fn new(message_id: &str) -> Self {
232 Self {
233 index: message_id.to_string(),
234 }
235 }
236}
237
238impl SmsSetReadRequest {
239 pub fn new(message_id: &str) -> Self {
241 Self {
242 index: message_id.to_string(),
243 }
244 }
245}
246
247#[cfg(test)]
248mod tests {
249 use super::*;
250
251 #[test]
252 fn test_sms_count_totals() {
253 let count = SmsCount {
254 local_unread: "3".to_string(),
255 local_inbox: "10".to_string(),
256 local_outbox: "5".to_string(),
257 local_draft: "1".to_string(),
258 sim_unread: "2".to_string(),
259 sim_inbox: "8".to_string(),
260 sim_outbox: "3".to_string(),
261 sim_draft: "0".to_string(),
262 new_msg: "1".to_string(),
263 };
264
265 assert_eq!(count.total_unread().unwrap(), 5);
266 assert_eq!(count.total_inbox().unwrap(), 18);
267 assert!(count.has_new_messages());
268 }
269
270 #[test]
271 fn test_sms_message_status() {
272 let unread = SmsMessage {
273 status: SmsStatus::Unread,
274 index: "1".to_string(),
275 phone: "+1234567890".to_string(),
276 content: "Test message".to_string(),
277 date: "2024-01-01 12:00:00".to_string(),
278 sca: None,
279 save_type: "3".to_string(),
280 priority: SmsPriority::Normal,
281 sms_type: SmsType::Single,
282 };
283
284 assert!(unread.is_unread());
285 assert!(!unread.is_read());
286 assert_eq!(unread.id(), "1");
287 assert_eq!(unread.text(), "Test message");
288 }
289
290 #[test]
291 fn test_sms_list_request_creation() {
292 let request = SmsListRequest::new(
293 1,
294 20,
295 SmsBoxType::LocalInbox,
296 SmsSortType::ByTime,
297 false,
298 true,
299 );
300
301 assert_eq!(request.page_index, "1");
302 assert_eq!(request.read_count, "20");
303 assert_eq!(request.box_type, "1"); assert_eq!(request.sort_type, "0"); assert_eq!(request.ascending, "0");
306 assert_eq!(request.unread_preferred, "1"); }
308
309 #[test]
310 fn test_sms_list_response_missing_count() {
311 let xml_without_count = r#"<response>
312 <Messages>
313 <Message>
314 <Smstat>0</Smstat>
315 <Index>1</Index>
316 <Phone>+123456789</Phone>
317 <Content>Test message</Content>
318 <Date>2023-01-01 12:00:00</Date>
319 <Sca></Sca>
320 <SaveType>0</SaveType>
321 <Priority>0</Priority>
322 <SmsType>1</SmsType>
323 </Message>
324 </Messages>
325</response>"#;
326
327 let response: SmsListResponse = serde_xml_rs::from_str(xml_without_count).unwrap();
328 assert!(response.count.is_none());
329 assert_eq!(response.message_count(), 1);
330 assert_eq!(response.messages.messages.len(), 1);
331 }
332
333 #[test]
334 fn test_sms_list_response_with_count() {
335 let xml_with_count = r#"<response>
336 <Count>1</Count>
337 <Messages>
338 <Message>
339 <Smstat>0</Smstat>
340 <Index>1</Index>
341 <Phone>+123456789</Phone>
342 <Content>Test message</Content>
343 <Date>2023-01-01 12:00:00</Date>
344 <Sca></Sca>
345 <SaveType>0</SaveType>
346 <Priority>0</Priority>
347 <SmsType>1</SmsType>
348 </Message>
349 </Messages>
350</response>"#;
351
352 let response: SmsListResponse = serde_xml_rs::from_str(xml_with_count).unwrap();
353 assert_eq!(response.count, Some("1".to_string()));
354 assert_eq!(response.message_count(), 1);
355 assert_eq!(response.messages.messages.len(), 1);
356 }
357
358 #[test]
359 fn test_sms_list_response_multiple_messages() {
360 let xml_multiple_messages = r#"<response>
361 <Count>2</Count>
362 <Messages>
363 <Message>
364 <Smstat>0</Smstat>
365 <Index>40003</Index>
366 <Phone>+48616673870</Phone>
367 <Content>Test message 1</Content>
368 <Date>2025-06-09 17:08:58</Date>
369 <Sca></Sca>
370 <SaveType>0</SaveType>
371 <Priority>0</Priority>
372 <SmsType>1</SmsType>
373 </Message>
374 <Message>
375 <Smstat>1</Smstat>
376 <Index>40002</Index>
377 <Phone>3350</Phone>
378 <Content>Test message 2</Content>
379 <Date>2024-11-22 12:32:12</Date>
380 <Sca></Sca>
381 <SaveType>0</SaveType>
382 <Priority>0</Priority>
383 <SmsType>5</SmsType>
384 </Message>
385 </Messages>
386</response>"#;
387
388 let response: SmsListResponse = serde_xml_rs::from_str(xml_multiple_messages).unwrap();
389 assert_eq!(response.count, Some("2".to_string()));
390 assert_eq!(response.message_count(), 2);
391 assert_eq!(response.messages.messages.len(), 2);
392
393 assert_eq!(response.messages.messages[0].index, "40003");
394 assert_eq!(response.messages.messages[0].phone, "+48616673870");
395 assert!(response.messages.messages[0].is_unread());
396
397 assert_eq!(response.messages.messages[1].index, "40002");
398 assert_eq!(response.messages.messages[1].phone, "3350");
399 assert!(response.messages.messages[1].is_read());
400 }
401}