diff --git a/melib/src/imap/protocol_parser.rs b/melib/src/imap/protocol_parser.rs index 26b36e65..45416358 100644 --- a/melib/src/imap/protocol_parser.rs +++ b/melib/src/imap/protocol_parser.rs @@ -26,6 +26,7 @@ use std::{convert::TryFrom, str::FromStr}; pub mod id_ext; #[cfg(test)] mod tests; +pub mod utils; use nom::{ branch::{alt, permutation}, @@ -1270,15 +1271,12 @@ pub fn envelope_addresses<'a>( // ("Terry Gray" NIL "gray" "cac.washington.edu") pub fn envelope_address(input: &[u8]) -> IResult<&[u8], Address> { const WS: &[u8] = b"\r\n\t "; - let (input, name) = alt((quoted, map(tag("NIL"), |_| Vec::new())))(input)?; + let (input, name) = utils::nil_to_default(quoted)(input)?; let (input, _) = is_a(WS)(input)?; - let (input, _) = alt((quoted, map(tag("NIL"), |_| Vec::new())))(input)?; + let (input, _) = utils::nil_to_default(quoted)(input)?; let (input, _) = is_a(WS)(input)?; - let (input, mailbox_name) = alt((quoted, map(tag("NIL"), |_| Vec::new())))(input)?; - let (input, host_name) = opt(preceded( - is_a(WS), - alt((quoted, map(tag("NIL"), |_| Vec::new()))), - ))(input)?; + let (input, mailbox_name) = utils::nil_to_default(quoted)(input)?; + let (input, host_name) = opt(preceded(is_a(WS), utils::nil_to_default(quoted)))(input)?; Ok(( input, Address::Mailbox(MailboxAddress { @@ -1368,8 +1366,9 @@ pub fn quoted(input: &[u8]) -> IResult<&[u8], Vec> { )) } +#[inline] pub fn quoted_or_nil(input: &[u8]) -> IResult<&[u8], Option>> { - alt((map(tag("NIL"), |_| None), map(quoted, Some)))(input.ltrim()) + utils::nil_to_none(quoted)(input.ltrim()) } pub fn uid_fetch_envelopes_response<'a>( diff --git a/melib/src/imap/protocol_parser/utils.rs b/melib/src/imap/protocol_parser/utils.rs new file mode 100644 index 00000000..842a5e9a --- /dev/null +++ b/melib/src/imap/protocol_parser/utils.rs @@ -0,0 +1,41 @@ +// +// meli +// +// Copyright 2024 Emmanouil 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 . +// +// SPDX-License-Identifier: EUPL-1.2 OR GPL-3.0-or-later + +//! # IMAP Parsing utility functions + +use nom::{branch::alt, bytes::complete::tag, combinator::map}; + +use crate::email::parser::IResult; + +#[inline] +pub fn nil_to_none<'i, T>( + parser: fn(&'i [u8]) -> IResult<&'i [u8], T>, +) -> impl FnMut(&'i [u8]) -> IResult<&'i [u8], Option> { + alt((map(tag("NIL"), |_| None), map(parser, Some))) +} + +#[inline] +pub fn nil_to_default<'i, T: Default>( + parser: fn(&'i [u8]) -> IResult<&'i [u8], T>, +) -> impl FnMut(&'i [u8]) -> IResult<&'i [u8], T> { + alt((map(tag("NIL"), |_| T::default()), parser)) +}