From 626874bedf33a754089fc3ef04157d3e4ad3171e Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Tue, 13 Jun 2023 12:25:00 +0200 Subject: [PATCH] wip address --- src/address.rs | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + src/model.rs | 12 ++++++- 3 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 src/address.rs diff --git a/src/address.rs b/src/address.rs new file mode 100644 index 0000000..92352fd --- /dev/null +++ b/src/address.rs @@ -0,0 +1,88 @@ +use nom::{ + IResult, + branch::alt, + bytes::complete::tag, + combinator::{into, opt, map_res}, + multi::separated_list1, + sequence::tuple, +}; + +use crate::model::{GroupRef, AddressRef, MailboxRef}; +use crate::mailbox::{addr_spec, mailbox}; +use crate::misc_token::phrase; +use crate::whitespace::{cfws}; + +/// Address (section 3.4 of RFC5322) +/// +/// ```abnf +/// address = mailbox / group +/// ``` +pub fn address(input: &str) -> IResult<&str, AddressRef> { + alt((into(mailbox), into(group)))(input) +} + +/// Group +/// +/// ```abnf +/// group = display-name ":" [group-list] ";" [CFWS] +/// display-name = phrase +/// ``` +pub fn group(input: &str) -> IResult<&str, GroupRef> { + let (input, (grp_name, _, grp_list, _, _)) = + tuple((phrase, tag(":"), group_list, tag(";"), opt(cfws)))(input)?; + + Ok((input, GroupRef { + name: grp_name, + participants: grp_list, + })) +} + +/// Group list +/// +/// ```abnf +/// group-list = mailbox-list / CFWS / obs-group-list +/// ``` +pub fn group_list(input: &str) -> IResult<&str, Vec> { + alt((mailbox_list, mx_cfws))(input) +} + +fn mx_cfws(input: &str) -> IResult<&str, Vec> { + let (input, _) = cfws(input)?; + Ok((input, vec![])) +} + +/// Mailbox list +/// +/// ```abnf +/// mailbox-list = (mailbox *("," mailbox)) / obs-mbox-list +/// ``` +pub fn mailbox_list(input: &str) -> IResult<&str, Vec> { + separated_list1(tag(","), mailbox)(input) +} + +/// Address list +/// +/// ```abnf +/// address-list = (address *("," address)) / obs-addr-list +/// ``` +pub fn address_list(input: &str) -> IResult<&str, Vec> { + separated_list1(tag(","), address)(input) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_mailbox_list() { + match mailbox_list(r#"Pete(A nice \) chap) "#) { + Ok(("", _)) => (), + _ => panic!(), + }; + + match mailbox_list(r#"Mary Smith , jdoe@example.org, Who? , , "Giant; \"Big\" Box" "#) { + Ok(("", _)) => (), + _ => panic!(), + }; + } +} diff --git a/src/lib.rs b/src/lib.rs index f53bba6..80add56 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,3 +9,4 @@ mod misc_token; // Header specific mod mailbox; +mod address; diff --git a/src/model.rs b/src/model.rs index e2a9072..08cce62 100644 --- a/src/model.rs +++ b/src/model.rs @@ -38,7 +38,7 @@ impl From for MailboxRef { #[derive(Debug)] pub struct GroupRef { pub name: String, - pub mbx: Vec, + pub participants: Vec, } #[derive(Debug)] @@ -46,6 +46,16 @@ pub enum AddressRef { Single(MailboxRef), Many(GroupRef), } +impl From for AddressRef { + fn from(mx: MailboxRef) -> Self { + AddressRef::Single(mx) + } +} +impl From for AddressRef { + fn from(grp: GroupRef) -> Self { + AddressRef::Many(grp) + } +} /// Permissive Header Section ///