borrow parsers (when it's possible)
This commit is contained in:
parent
2b7b5664c1
commit
8e67af6c2c
11 changed files with 58 additions and 60 deletions
|
@ -14,40 +14,40 @@ use crate::fragments::misc_token::phrase;
|
||||||
use crate::fragments::whitespace::{cfws};
|
use crate::fragments::whitespace::{cfws};
|
||||||
use crate::error::IMFError;
|
use crate::error::IMFError;
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a lazy::Mailbox<'a>> for MailboxRef {
|
impl<'a> TryFrom<lazy::Mailbox<'a>> for MailboxRef {
|
||||||
type Error = IMFError<'a>;
|
type Error = IMFError<'a>;
|
||||||
|
|
||||||
fn try_from(mx: &'a lazy::Mailbox<'a>) -> Result<Self, Self::Error> {
|
fn try_from(mx: lazy::Mailbox<'a>) -> Result<Self, Self::Error> {
|
||||||
mailbox(mx.0)
|
mailbox(mx.0)
|
||||||
.map(|(_, m)| m)
|
.map(|(_, m)| m)
|
||||||
.map_err(|e| IMFError::Mailbox(e))
|
.map_err(|e| IMFError::Mailbox(e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a lazy::MailboxList<'a>> for MailboxList {
|
impl<'a> TryFrom<lazy::MailboxList<'a>> for MailboxList {
|
||||||
type Error = IMFError<'a>;
|
type Error = IMFError<'a>;
|
||||||
|
|
||||||
fn try_from(ml: &'a lazy::MailboxList<'a>) -> Result<Self, Self::Error> {
|
fn try_from(ml: lazy::MailboxList<'a>) -> Result<Self, Self::Error> {
|
||||||
mailbox_list(ml.0)
|
mailbox_list(ml.0)
|
||||||
.map(|(_, m)| m)
|
.map(|(_, m)| m)
|
||||||
.map_err(|e| IMFError::MailboxList(e))
|
.map_err(|e| IMFError::MailboxList(e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a lazy::AddressList<'a>> for AddressList {
|
impl<'a> TryFrom<lazy::AddressList<'a>> for AddressList {
|
||||||
type Error = IMFError<'a>;
|
type Error = IMFError<'a>;
|
||||||
|
|
||||||
fn try_from(al: &'a lazy::AddressList<'a>) -> Result<Self, Self::Error> {
|
fn try_from(al: lazy::AddressList<'a>) -> Result<Self, Self::Error> {
|
||||||
address_list(al.0)
|
address_list(al.0)
|
||||||
.map(|(_, a)| a)
|
.map(|(_, a)| a)
|
||||||
.map_err(|e| IMFError::AddressList(e))
|
.map_err(|e| IMFError::AddressList(e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a lazy::NullableAddressList<'a>> for AddressList {
|
impl<'a> TryFrom<lazy::NullableAddressList<'a>> for AddressList {
|
||||||
type Error = IMFError<'a>;
|
type Error = IMFError<'a>;
|
||||||
|
|
||||||
fn try_from(nal: &'a lazy::NullableAddressList<'a>) -> Result<Self, Self::Error> {
|
fn try_from(nal: lazy::NullableAddressList<'a>) -> Result<Self, Self::Error> {
|
||||||
opt(alt((address_list, address_list_cfws)))(nal.0)
|
opt(alt((address_list, address_list_cfws)))(nal.0)
|
||||||
.map(|(_, a)| a.unwrap_or(vec![]))
|
.map(|(_, a)| a.unwrap_or(vec![]))
|
||||||
.map_err(|e| IMFError::NullableAddressList(e))
|
.map_err(|e| IMFError::NullableAddressList(e))
|
||||||
|
|
|
@ -18,10 +18,10 @@ use crate::error::IMFError;
|
||||||
const MIN: i32 = 60;
|
const MIN: i32 = 60;
|
||||||
const HOUR: i32 = 60 * MIN;
|
const HOUR: i32 = 60 * MIN;
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a lazy::DateTime<'a>> for DateTime<FixedOffset> {
|
impl<'a> TryFrom<lazy::DateTime<'a>> for DateTime<FixedOffset> {
|
||||||
type Error = IMFError<'a>;
|
type Error = IMFError<'a>;
|
||||||
|
|
||||||
fn try_from(value: &'a lazy::DateTime<'a>) -> Result<Self, Self::Error> {
|
fn try_from(value: lazy::DateTime<'a>) -> Result<Self, Self::Error> {
|
||||||
match section(value.0) {
|
match section(value.0) {
|
||||||
Ok((_, Some(dt))) => Ok(dt),
|
Ok((_, Some(dt))) => Ok(dt),
|
||||||
Err(e) => Err(IMFError::DateTimeParse(e)),
|
Err(e) => Err(IMFError::DateTimeParse(e)),
|
||||||
|
|
|
@ -45,10 +45,10 @@ pub enum Field<'a> {
|
||||||
}
|
}
|
||||||
use Field::*;
|
use Field::*;
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a Lazy<'a>> for Field<'a> {
|
impl<'a> TryFrom<Lazy<'a>> for Field<'a> {
|
||||||
type Error = IMFError<'a>;
|
type Error = IMFError<'a>;
|
||||||
|
|
||||||
fn try_from(l: &'a Lazy<'a>) -> Result<Self, Self::Error> {
|
fn try_from(l: Lazy<'a>) -> Result<Self, Self::Error> {
|
||||||
match l {
|
match l {
|
||||||
Lazy::Date(v) => v.try_into().map(|v| Date(v)),
|
Lazy::Date(v) => v.try_into().map(|v| Date(v)),
|
||||||
Lazy::From(v) => v.try_into().map(|v| From(v)),
|
Lazy::From(v) => v.try_into().map(|v| From(v)),
|
||||||
|
@ -66,7 +66,7 @@ impl<'a> TryFrom<&'a Lazy<'a>> for Field<'a> {
|
||||||
Lazy::Received(v) => v.try_into().map(|v| Received(v)),
|
Lazy::Received(v) => v.try_into().map(|v| Received(v)),
|
||||||
Lazy::ReturnPath(v) => v.try_into().map(|v| ReturnPath(v)),
|
Lazy::ReturnPath(v) => v.try_into().map(|v| ReturnPath(v)),
|
||||||
Lazy::Optional(k, v) => v.try_into().map(|v| Optional(k, v)),
|
Lazy::Optional(k, v) => v.try_into().map(|v| Optional(k, v)),
|
||||||
Lazy::Rescue(v) => Ok(Rescue(*v)),
|
Lazy::Rescue(v) => Ok(Rescue(v)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,20 +15,20 @@ use crate::fragments::mailbox::is_dtext;
|
||||||
use crate::fragments::model::{MessageId, MessageIdList};
|
use crate::fragments::model::{MessageId, MessageIdList};
|
||||||
use crate::error::IMFError;
|
use crate::error::IMFError;
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a lazy::Identifier<'a>> for MessageId<'a> {
|
impl<'a> TryFrom<lazy::Identifier<'a>> for MessageId<'a> {
|
||||||
type Error = IMFError<'a>;
|
type Error = IMFError<'a>;
|
||||||
|
|
||||||
fn try_from(id: &'a lazy::Identifier<'a>) -> Result<Self, Self::Error> {
|
fn try_from(id: lazy::Identifier<'a>) -> Result<Self, Self::Error> {
|
||||||
msg_id(id.0)
|
msg_id(id.0)
|
||||||
.map(|(_, i)| i)
|
.map(|(_, i)| i)
|
||||||
.map_err(|e| IMFError::MessageID(e))
|
.map_err(|e| IMFError::MessageID(e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a lazy::IdentifierList<'a>> for MessageIdList<'a> {
|
impl<'a> TryFrom<lazy::IdentifierList<'a>> for MessageIdList<'a> {
|
||||||
type Error = IMFError<'a>;
|
type Error = IMFError<'a>;
|
||||||
|
|
||||||
fn try_from(id: &'a lazy::IdentifierList<'a>) -> Result<Self, Self::Error> {
|
fn try_from(id: lazy::IdentifierList<'a>) -> Result<Self, Self::Error> {
|
||||||
many1(msg_id)(id.0)
|
many1(msg_id)(id.0)
|
||||||
.map(|(_, i)| i)
|
.map(|(_, i)| i)
|
||||||
.map_err(|e| IMFError::MessageIDList(e))
|
.map_err(|e| IMFError::MessageIDList(e))
|
||||||
|
|
|
@ -21,20 +21,20 @@ pub struct Unstructured(pub String);
|
||||||
#[derive(Debug, PartialEq, Default)]
|
#[derive(Debug, PartialEq, Default)]
|
||||||
pub struct PhraseList(pub Vec<String>);
|
pub struct PhraseList(pub Vec<String>);
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a lazy::Unstructured<'a>> for Unstructured {
|
impl<'a> TryFrom<lazy::Unstructured<'a>> for Unstructured {
|
||||||
type Error = IMFError<'a>;
|
type Error = IMFError<'a>;
|
||||||
|
|
||||||
fn try_from(input: &'a lazy::Unstructured<'a>) -> Result<Self, Self::Error> {
|
fn try_from(input: lazy::Unstructured<'a>) -> Result<Self, Self::Error> {
|
||||||
unstructured(input.0)
|
unstructured(input.0)
|
||||||
.map(|(_, v)| Unstructured(v))
|
.map(|(_, v)| Unstructured(v))
|
||||||
.map_err(|e| IMFError::Unstructured(e))
|
.map_err(|e| IMFError::Unstructured(e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a lazy::PhraseList<'a>> for PhraseList {
|
impl<'a> TryFrom<lazy::PhraseList<'a>> for PhraseList {
|
||||||
type Error = IMFError<'a>;
|
type Error = IMFError<'a>;
|
||||||
|
|
||||||
fn try_from(p: &'a lazy::PhraseList<'a>) -> Result<Self, Self::Error> {
|
fn try_from(p: lazy::PhraseList<'a>) -> Result<Self, Self::Error> {
|
||||||
separated_list1(tag(","), phrase)(p.0)
|
separated_list1(tag(","), phrase)(p.0)
|
||||||
.map(|(_, q)| PhraseList(q))
|
.map(|(_, q)| PhraseList(q))
|
||||||
.map_err(|e| IMFError::PhraseList(e))
|
.map_err(|e| IMFError::PhraseList(e))
|
||||||
|
|
|
@ -49,33 +49,31 @@ pub struct Section<'a> {
|
||||||
|
|
||||||
//@FIXME min and max limits are not enforced,
|
//@FIXME min and max limits are not enforced,
|
||||||
// it may result in missing data or silently overriden data.
|
// it may result in missing data or silently overriden data.
|
||||||
impl<'a> From<Vec<Field<'a>>> for Section<'a> {
|
impl<'a> FromIterator<Field<'a>> for Section<'a> {
|
||||||
fn from(field_list: Vec<Field<'a>>) -> Self {
|
fn from_iter<I: IntoIterator<Item=Field<'a>>>(iter: I) -> Self {
|
||||||
field_list.into_iter().fold(
|
let mut section = Section::default();
|
||||||
Section::default(),
|
for field in iter {
|
||||||
|mut section, field| {
|
match field {
|
||||||
match field {
|
Field::Date(v) => section.date = Some(v),
|
||||||
Field::Date(v) => section.date = Some(v),
|
Field::From(v) => section.from.extend(v),
|
||||||
Field::From(v) => section.from.extend(v),
|
Field::Sender(v) => section.sender = Some(v),
|
||||||
Field::Sender(v) => section.sender = Some(v),
|
Field::ReplyTo(v) => section.reply_to.extend(v),
|
||||||
Field::ReplyTo(v) => section.reply_to.extend(v),
|
Field::To(v) => section.to.extend(v),
|
||||||
Field::To(v) => section.to.extend(v),
|
Field::Cc(v) => section.cc.extend(v),
|
||||||
Field::Cc(v) => section.cc.extend(v),
|
Field::Bcc(v) => section.bcc.extend(v),
|
||||||
Field::Bcc(v) => section.bcc.extend(v),
|
Field::MessageID(v) => section.msg_id = Some(v),
|
||||||
Field::MessageID(v) => section.msg_id = Some(v),
|
Field::InReplyTo(v) => section.in_reply_to.extend(v),
|
||||||
Field::InReplyTo(v) => section.in_reply_to.extend(v),
|
Field::References(v) => section.references.extend(v),
|
||||||
Field::References(v) => section.references.extend(v),
|
Field::Subject(v) => section.subject = Some(v),
|
||||||
Field::Subject(v) => section.subject = Some(v),
|
Field::Comments(v) => section.comments.push(v),
|
||||||
Field::Comments(v) => section.comments.push(v),
|
Field::Keywords(v) => section.keywords.push(v),
|
||||||
Field::Keywords(v) => section.keywords.push(v),
|
Field::ReturnPath(v) => section.return_path.push(v),
|
||||||
Field::ReturnPath(v) => section.return_path.push(v),
|
Field::Received(v) => section.received.push(v),
|
||||||
Field::Received(v) => section.received.push(v),
|
Field::Optional(k, v) => { section.optional.insert(k, v); },
|
||||||
Field::Optional(k, v) => { section.optional.insert(k, v); },
|
Field::Rescue(v) => section.unparsed.push(v),
|
||||||
Field::Rescue(v) => section.unparsed.push(v),
|
|
||||||
};
|
|
||||||
section
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
section
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,10 @@ use crate::error::IMFError;
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct ReceivedLog<'a>(pub &'a str);
|
pub struct ReceivedLog<'a>(pub &'a str);
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a lazy::ReceivedLog<'a>> for ReceivedLog<'a> {
|
impl<'a> TryFrom<lazy::ReceivedLog<'a>> for ReceivedLog<'a> {
|
||||||
type Error = IMFError<'a>;
|
type Error = IMFError<'a>;
|
||||||
|
|
||||||
fn try_from(input: &'a lazy::ReceivedLog<'a>) -> Result<Self, Self::Error> {
|
fn try_from(input: lazy::ReceivedLog<'a>) -> Result<Self, Self::Error> {
|
||||||
received_body(input.0)
|
received_body(input.0)
|
||||||
.map_err(|e| IMFError::ReceivedLog(e))
|
.map_err(|e| IMFError::ReceivedLog(e))
|
||||||
.map(|(_, v)| ReceivedLog(v))
|
.map(|(_, v)| ReceivedLog(v))
|
||||||
|
|
|
@ -7,10 +7,10 @@ pub struct Parsed<'a> {
|
||||||
pub body: &'a [u8],
|
pub body: &'a [u8],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From <&'a field_lazy::Parsed<'a>> for Parsed<'a> {
|
impl<'a> From <field_lazy::Parsed<'a>> for Parsed<'a> {
|
||||||
fn from(p: &'a field_lazy::Parsed<'a>) -> Self {
|
fn from(p: field_lazy::Parsed<'a>) -> Self {
|
||||||
Parsed {
|
Parsed {
|
||||||
fields: p.fields.iter().filter_map(|entry| entry.try_into().ok()).collect(),
|
fields: p.fields.into_iter().filter_map(|entry| entry.try_into().ok()).collect(),
|
||||||
body: p.body,
|
body: p.body,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_field_body() {
|
fn test_field_body() {
|
||||||
assert_eq!(Parsed::from(&field_lazy::Parsed {
|
assert_eq!(Parsed::from(field_lazy::Parsed {
|
||||||
fields: vec![
|
fields: vec![
|
||||||
lazy::Field::From(lazy::MailboxList("hello@world.com,\r\n\talice@wonderlands.com\r\n")),
|
lazy::Field::From(lazy::MailboxList("hello@world.com,\r\n\talice@wonderlands.com\r\n")),
|
||||||
lazy::Field::Date(lazy::DateTime("12 Mar 1997 07:33:25 Z\r\n")),
|
lazy::Field::Date(lazy::DateTime("12 Mar 1997 07:33:25 Z\r\n")),
|
||||||
|
|
|
@ -7,8 +7,8 @@ pub struct Parsed<'a> {
|
||||||
pub body: &'a [u8],
|
pub body: &'a [u8],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From <&'a ExtractFields<'a>> for Parsed<'a> {
|
impl<'a> From <ExtractFields<'a>> for Parsed<'a> {
|
||||||
fn from(ef: &'a ExtractFields<'a>) -> Self {
|
fn from(ef: ExtractFields<'a>) -> Self {
|
||||||
Parsed {
|
Parsed {
|
||||||
fields: ef.fields.iter().map(|e| (*e).into()).collect(),
|
fields: ef.fields.iter().map(|e| (*e).into()).collect(),
|
||||||
body: ef.body,
|
body: ef.body,
|
||||||
|
@ -22,7 +22,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_field_name() {
|
fn test_field_name() {
|
||||||
assert_eq!(Parsed::from(&ExtractFields {
|
assert_eq!(Parsed::from(ExtractFields {
|
||||||
fields: vec![
|
fields: vec![
|
||||||
"From: hello@world.com,\r\n\talice@wonderlands.com\r\n",
|
"From: hello@world.com,\r\n\talice@wonderlands.com\r\n",
|
||||||
"Date: 12 Mar 1997 07:33:25 Z\r\n",
|
"Date: 12 Mar 1997 07:33:25 Z\r\n",
|
||||||
|
|
|
@ -16,8 +16,8 @@ const IS_LAST_BUFFER: bool = true;
|
||||||
const ALLOW_UTF8: bool = true;
|
const ALLOW_UTF8: bool = true;
|
||||||
const NO_TLD: Option<&[u8]> = None;
|
const NO_TLD: Option<&[u8]> = None;
|
||||||
|
|
||||||
impl<'a> From<&'a Segment<'a>> for GuessCharset<'a> {
|
impl<'a> From<Segment<'a>> for GuessCharset<'a> {
|
||||||
fn from(seg: &'a Segment<'a>) -> Self {
|
fn from(seg: Segment<'a>) -> Self {
|
||||||
// Create detector
|
// Create detector
|
||||||
let mut detector = EncodingDetector::new();
|
let mut detector = EncodingDetector::new();
|
||||||
detector.feed(&seg.header, IS_LAST_BUFFER);
|
detector.feed(&seg.header, IS_LAST_BUFFER);
|
||||||
|
@ -37,7 +37,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_charset() {
|
fn test_charset() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
GuessCharset::from(&Segment {
|
GuessCharset::from(Segment {
|
||||||
body: b"Hello world!",
|
body: b"Hello world!",
|
||||||
header: b"From: hello@world.com\r\nDate: 12 Mar 1997 07:33:25 Z\r\n",
|
header: b"From: hello@world.com\r\nDate: 12 Mar 1997 07:33:25 Z\r\n",
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub struct Parsed<'a> {
|
||||||
impl<'a> From<field_eager::Parsed<'a>> for Parsed<'a> {
|
impl<'a> From<field_eager::Parsed<'a>> for Parsed<'a> {
|
||||||
fn from(p: field_eager::Parsed<'a>) -> Self {
|
fn from(p: field_eager::Parsed<'a>) -> Self {
|
||||||
Parsed {
|
Parsed {
|
||||||
fields: p.fields.into(),
|
fields: Section::from_iter(p.fields.into_iter()),
|
||||||
body: p.body,
|
body: p.body,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue