summaryrefslogtreecommitdiffstats
path: root/melib/src/email/parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'melib/src/email/parser.rs')
-rw-r--r--melib/src/email/parser.rs78
1 files changed, 77 insertions, 1 deletions
diff --git a/melib/src/email/parser.rs b/melib/src/email/parser.rs
index cba49644..4d2e376b 100644
--- a/melib/src/email/parser.rs
+++ b/melib/src/email/parser.rs
@@ -530,7 +530,7 @@ fn group(input: &[u8]) -> IResult<&[u8], Address> {
}
}
-named!(address<Address>, ws!(alt_complete!(mailbox | group)));
+named!(pub address<Address>, ws!(alt_complete!(mailbox | group)));
named!(pub rfc2822address_list<Vec<Address>>, ws!( separated_list!(is_a!(","), address)));
@@ -788,6 +788,82 @@ pub fn phrase(input: &[u8]) -> IResult<&[u8], Vec<u8>> {
IResult::Done(&input[ptr..], acc)
}
+named!(pub angle_bracket_delimeted_list<Vec<&[u8]>>, separated_nonempty_list!(complete!(is_a!(",")), ws!(complete!(message_id))));
+
+pub fn mailto(mut input: &[u8]) -> IResult<&[u8], Mailto> {
+ if !input.starts_with(b"mailto:") {
+ return IResult::Error(error_code!(ErrorKind::Custom(43)));
+ }
+
+ input = &input[b"mailto:".len()..];
+
+ let end = input.iter().position(|e| *e == b'?').unwrap_or(input.len());
+ let address: Address;
+
+ if let IResult::Done(rest, addr) = crate::email::parser::address(&input[..end]) {
+ address = addr;
+ input = if input[end..].is_empty() {
+ &input[end..]
+ } else {
+ &input[end + 1..]
+ };
+ } else {
+ return IResult::Error(error_code!(ErrorKind::Custom(43)));
+ }
+
+ let mut subject = None;
+ let mut cc = None;
+ let mut bcc = None;
+ let mut body = None;
+ while !input.is_empty() {
+ let tag = if let Some(tag_pos) = input.iter().position(|e| *e == b'=') {
+ let ret = &input[0..tag_pos];
+ input = &input[tag_pos + 1..];
+ ret
+ } else {
+ return IResult::Error(error_code!(ErrorKind::Custom(43)));
+ };
+
+ let value_end = input.iter().position(|e| *e == b'&').unwrap_or(input.len());
+
+ let value = String::from_utf8_lossy(&input[..value_end]).to_string();
+ match tag {
+ b"subject" if subject.is_none() => {
+ subject = Some(value);
+ }
+ b"cc" if cc.is_none() => {
+ cc = Some(value);
+ }
+ b"bcc" if bcc.is_none() => {
+ bcc = Some(value);
+ }
+ b"body" if body.is_none() => {
+ /* FIXME:
+ * Parse escaped characters properly.
+ */
+ body = Some(value.replace("%20", " ").replace("%0A", "\n"));
+ }
+ _ => {
+ return IResult::Error(error_code!(ErrorKind::Custom(43)));
+ }
+ }
+ if input[value_end..].is_empty() {
+ break;
+ }
+ input = &input[value_end + 1..];
+ }
+ IResult::Done(
+ input,
+ Mailto {
+ address,
+ subject,
+ cc,
+ bcc,
+ body,
+ },
+ )
+}
+
#[cfg(test)]
mod tests {