use std::collections::VecDeque;
use super::*;
use crate::utils::parsec::{is_not, map_res, match_literal_anycase, prefix, Parser};
pub fn parse_mutt_contact<'a>() -> impl Parser<'a, Card> {
move |input| {
map_res(
prefix(match_literal_anycase("alias "), is_not(b"\r\n")),
|l| {
let mut tokens = l.split_whitespace().collect::<VecDeque<&str>>();
let mut ret = Card::new();
let title = tokens.pop_front().ok_or(l)?.to_string();
let mut email = tokens.pop_back().ok_or(l)?.to_string();
if email.starts_with('<') && email.ends_with('>') {
email.pop();
email.remove(0);
}
let mut name = tokens.into_iter().fold(String::new(), |mut acc, el| {
acc.push_str(el);
acc.push(' ');
acc
});
name.pop();
if name.trim().is_empty() {
name.clone_from(&title);
}
ret.set_title(title).set_email(email).set_name(name);
Ok::<Card, &'a str>(ret)
},
)
.parse(input)
}
}
#[test]
fn test_mutt_contacts() {
let a = "alias mumon My dear pupil Mumon foobar@example.com";
let b = "alias mumon foobar@example.com";
let c = "alias <nickname> <long name> <address>";
let (other, a_card) = parse_mutt_contact().parse(a).unwrap();
assert!(other.is_empty());
assert_eq!(a_card.name(), "My dear pupil Mumon");
assert_eq!(a_card.title(), "mumon");
assert_eq!(a_card.email(), "foobar@example.com");
let (other, b_card) = parse_mutt_contact().parse(b).unwrap();
assert!(other.is_empty());
assert_eq!(b_card.name(), "mumon");
assert_eq!(b_card.title(), "mumon");
assert_eq!(b_card.email(), "foobar@example.com");
let (other, c_card) = parse_mutt_contact().parse(c).unwrap();
assert!(other.is_empty());
assert_eq!(c_card.name(), "<long name>");
assert_eq!(c_card.title(), "<nickname>");
assert_eq!(c_card.email(), "address");
}