1use quick_xml::{events::Event, Reader, XmlVersion};
4use thiserror::Error;
5
6use crate::messages::MessageEntry;
7
8#[derive(Debug, Error)]
10pub enum MessageListingError {
11 #[error("XML error: {0}")]
13 Parse(#[from] quick_xml::Error),
14 #[error("attribute error: {0}")]
16 Attr(#[from] quick_xml::events::attributes::AttrError),
17 #[error("invalid integer attribute: {0}")]
19 InvalidInt(#[from] std::num::ParseIntError),
20}
21
22pub fn parse_message_listing(xml: &[u8]) -> Result<Vec<MessageEntry>, MessageListingError> {
32 let mut reader = Reader::from_reader(xml);
33 reader.config_mut().trim_text(true);
34 let mut messages = Vec::new();
35 let mut buf = Vec::new();
36 loop {
37 match reader.read_event_into(&mut buf)? {
38 Event::Empty(e) | Event::Start(e) if e.name().as_ref() == b"msg" => {
39 let mut handle = String::new();
40 let mut subject = String::new();
41 let mut datetime = String::new();
42 let mut sender_name = String::new();
43 let mut sender_addressing = String::new();
44 let mut recipient_name = String::new();
45 let mut recipient_addressing = String::new();
46 let mut msg_type = String::new();
47 let mut size = 0u32;
48 let mut read = false;
49 let mut sent = false;
50 for attr in e.attributes() {
51 let a = attr?;
52 let val = a.normalized_value(XmlVersion::Implicit1_0)?.into_owned();
53 match a.key.as_ref() {
54 b"handle" => handle = val,
55 b"subject" => subject = val,
56 b"datetime" => datetime = val,
57 b"sender_name" => sender_name = val,
58 b"sender_addressing" => sender_addressing = val,
59 b"recipient_name" => recipient_name = val,
60 b"recipient_addressing" => recipient_addressing = val,
61 b"type" => msg_type = val,
62 b"size" => size = val.parse()?,
63 b"read" => read = val == "yes",
64 b"sent" => sent = val == "yes",
65 _ => {}
66 }
67 }
68 messages.push(MessageEntry {
69 handle,
70 subject,
71 datetime,
72 sender_name,
73 sender_addressing,
74 recipient_name,
75 recipient_addressing,
76 msg_type,
77 size,
78 read,
79 sent,
80 });
81 }
82 Event::Eof => break,
83 _ => {}
84 }
85 buf.clear();
86 }
87 Ok(messages)
88}