1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use abnf_core::streaming::SP;
use nom::{
bytes::streaming::tag,
sequence::{delimited, tuple},
IResult,
};
use crate::{
parse::core::nstring,
types::{address::Address, core::nstr},
};
pub(crate) fn address(input: &[u8]) -> IResult<&[u8], Address> {
let mut parser = delimited(
tag(b"("),
tuple((addr_name, SP, addr_adl, SP, addr_mailbox, SP, addr_host)),
tag(b")"),
);
let (remaining, (name, _, adl, _, mailbox, _, host)) = parser(input)?;
Ok((
remaining,
Address::new(
name.to_owned(),
adl.to_owned(),
mailbox.to_owned(),
host.to_owned(),
),
))
}
#[inline]
fn addr_name(input: &[u8]) -> IResult<&[u8], nstr> {
nstring(input)
}
#[inline]
fn addr_adl(input: &[u8]) -> IResult<&[u8], nstr> {
nstring(input)
}
#[inline]
fn addr_mailbox(input: &[u8]) -> IResult<&[u8], nstr> {
nstring(input)
}
#[inline]
fn addr_host(input: &[u8]) -> IResult<&[u8], nstr> {
nstring(input)
}
#[cfg(test)]
mod test {
use std::convert::{TryFrom, TryInto};
use super::*;
use crate::types::core::{IString, NString, NonZeroBytes};
#[test]
fn test_address() {
let (rem, val) = address(b"(nil {3}\r\nxxx \"xxx\" nil)").unwrap();
assert_eq!(
val,
Address::new(
NString(None),
NString(Some(IString::Literal(
NonZeroBytes::try_from(b"xxx".as_ref()).unwrap()
))),
NString(Some(IString::Quoted("xxx".try_into().unwrap()))),
NString(None),
)
);
assert_eq!(rem, b"");
}
}