diff options
Diffstat (limited to 'melib/src/addressbook/mutt.rs')
-rw-r--r-- | melib/src/addressbook/mutt.rs | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/melib/src/addressbook/mutt.rs b/melib/src/addressbook/mutt.rs new file mode 100644 index 00000000..805c3546 --- /dev/null +++ b/melib/src/addressbook/mutt.rs @@ -0,0 +1,106 @@ +/* + * meli - addressbook module + * + * Copyright 2019 Manos Pitsidianakis + * + * This file is part of meli. + * + * meli is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * meli is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with meli. If not, see <http://www.gnu.org/licenses/>. + */ + +//! # Mutt contact formats +//! + +use super::*; +use crate::parsec::{is_not, map_res, match_literal_anycase, prefix, Parser}; +use std::collections::VecDeque; + +//alias <nickname> [ <long name> ] <address> +// From mutt doc: +// +// ```text +// Since the name can consist of several whitespace-separated words, the +// last word is considered the address, and it can be optionally enclosed +// between angle brackets. +// For example: alias mumon My dear pupil Mumon foobar@example.com +// will be parsed in this way: +// +// alias mumon My dear pupil Mumon foobar@example.com +// ^ ^ ^ +// nickname long name email address +// The nickname (or alias) will be used to select a corresponding long name +// and email address when specifying the To field of an outgoing message, +// e.g. when using the function in the browser or index context. +// The long name is optional, so you can specify an alias command in this +// way: +// +// alias mumon foobar@example.com +// ^ ^ +// nickname email address +// ``` +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 = title.clone(); + } + 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"); +} |