mirror of
https://github.com/mailscope/kumomta.git
synced 2026-10-28 09:16:15 +00:00
mailparsing: refactor: Mailbox::name to Option<BString>
This commit is contained in:
@@ -554,7 +554,7 @@ impl<'a> Compiled<'a> {
|
||||
|
||||
if need_to {
|
||||
builder.set_to(Address::Mailbox(Mailbox {
|
||||
name: recip.name.clone(),
|
||||
name: recip.name.clone().map(Into::into),
|
||||
address: AddrSpec::parse(&recip.email)?,
|
||||
}))?;
|
||||
}
|
||||
@@ -586,7 +586,7 @@ impl InjectV1Request {
|
||||
} => {
|
||||
if let Some(from) = from {
|
||||
let mailbox = Address::Mailbox(Mailbox {
|
||||
name: from.name.clone(),
|
||||
name: from.name.clone().map(Into::into),
|
||||
address: AddrSpec::parse(&from.email)
|
||||
.context("failed parsing content.from")?,
|
||||
});
|
||||
@@ -595,7 +595,7 @@ impl InjectV1Request {
|
||||
}
|
||||
if let Some(reply_to) = reply_to {
|
||||
let mailbox = Address::Mailbox(Mailbox {
|
||||
name: reply_to.name.clone(),
|
||||
name: reply_to.name.clone().map(Into::into),
|
||||
address: AddrSpec::parse(&reply_to.email)
|
||||
.context("failed parsing content.reply_to")?,
|
||||
});
|
||||
|
||||
@@ -577,7 +577,7 @@ Ok(
|
||||
fn assign_mailbox() {
|
||||
let mut sender = Header::with_name_value("Sender", "");
|
||||
sender.assign(Mailbox {
|
||||
name: Some("John Smith".to_string()),
|
||||
name: Some("John Smith".into()),
|
||||
address: AddrSpec::new("john.smith", "example.com"),
|
||||
});
|
||||
assert_eq!(
|
||||
@@ -586,7 +586,7 @@ Ok(
|
||||
);
|
||||
|
||||
sender.assign(Mailbox {
|
||||
name: Some("John \"the smith\" Smith".to_string()),
|
||||
name: Some("John \"the smith\" Smith".into()),
|
||||
address: AddrSpec::new("john.smith", "example.com"),
|
||||
});
|
||||
assert_eq!(
|
||||
@@ -600,7 +600,7 @@ Ok(
|
||||
let sender = Header::new(
|
||||
"Sender",
|
||||
Mailbox {
|
||||
name: Some("John".to_string()),
|
||||
name: Some("John".into()),
|
||||
address: AddrSpec::new("john.smith", "example.com"),
|
||||
},
|
||||
);
|
||||
@@ -612,7 +612,7 @@ Ok(
|
||||
let sender = Header::new(
|
||||
"Sender",
|
||||
Mailbox {
|
||||
name: Some("John".to_string()),
|
||||
name: Some("John".into()),
|
||||
address: AddrSpec::new("john smith", "example.com"),
|
||||
},
|
||||
);
|
||||
@@ -627,7 +627,7 @@ Ok(
|
||||
let sender = Header::new(
|
||||
"Sender",
|
||||
Mailbox {
|
||||
name: Some("André Pirard".to_string()),
|
||||
name: Some("André Pirard".into()),
|
||||
address: AddrSpec::new("andre", "example.com"),
|
||||
},
|
||||
);
|
||||
|
||||
@@ -313,7 +313,7 @@ fn name_addr(input: Span) -> IResult<Span, Mailbox> {
|
||||
context(
|
||||
"name_addr",
|
||||
map((opt(display_name), angle_addr), |(name, address)| Mailbox {
|
||||
name,
|
||||
name: name.map(Into::into),
|
||||
address,
|
||||
}),
|
||||
)
|
||||
@@ -1705,7 +1705,7 @@ impl MailboxList {
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Mailbox {
|
||||
pub name: Option<String>,
|
||||
pub name: Option<BString>,
|
||||
pub address: AddrSpec,
|
||||
}
|
||||
|
||||
@@ -2170,20 +2170,21 @@ fn test_qp_encode() {
|
||||
/// Quote input string `s`, using a backslash escape, if any
|
||||
/// of the characters is NOT atext. When quoting, the input
|
||||
/// string is enclosed in quotes.
|
||||
fn quote_string(s: &str) -> String {
|
||||
fn quote_string(s: impl AsRef<[u8]>) -> BString {
|
||||
let s = s.as_ref();
|
||||
if s.chars().any(|c| !is_atext(c)) {
|
||||
let mut result = String::with_capacity(s.len() + 4);
|
||||
result.push('"');
|
||||
for c in s.chars() {
|
||||
let mut result = Vec::<u8>::with_capacity(s.len() + 4);
|
||||
result.push(b'"');
|
||||
for (start, end, c) in s.char_indices() {
|
||||
if !c.is_ascii_whitespace() && !is_qtext(c) && !is_atext(c) {
|
||||
result.push('\\');
|
||||
result.push(b'\\');
|
||||
}
|
||||
result.push(c);
|
||||
result.push_str(&s[start..end]);
|
||||
}
|
||||
result.push('"');
|
||||
result
|
||||
result.push(b'"');
|
||||
result.into()
|
||||
} else {
|
||||
s.to_string()
|
||||
s.into()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2209,12 +2210,11 @@ impl EncodeHeaderValue for Mailbox {
|
||||
fn encode_value(&self) -> SharedString<'static> {
|
||||
match &self.name {
|
||||
Some(name) => {
|
||||
let mut value = if name.is_ascii() {
|
||||
quote_string(name)
|
||||
let mut value: Vec<u8> = if name.is_ascii() {
|
||||
quote_string(name).into()
|
||||
} else {
|
||||
qp_encode(name.as_bytes())
|
||||
}
|
||||
.into_bytes();
|
||||
qp_encode(name.as_bytes()).into_bytes()
|
||||
};
|
||||
|
||||
value.push_str(" <");
|
||||
value.push_str(self.address.encode_value().as_bytes());
|
||||
@@ -2282,7 +2282,7 @@ mod test {
|
||||
#[test]
|
||||
fn mailbox_encodes_at() {
|
||||
let mbox = Mailbox {
|
||||
name: Some("foo@bar.com".to_string()),
|
||||
name: Some("foo@bar.com".into()),
|
||||
address: AddrSpec {
|
||||
local_part: "foo".into(),
|
||||
domain: "bar.com".into(),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use bstr::{BStr, BString, ByteSlice};
|
||||
use config::any_err;
|
||||
use dns_resolver::DomainClassification;
|
||||
use mailparsing::{Address, AddressList, EncodeHeaderValue, Mailbox};
|
||||
@@ -164,9 +165,9 @@ impl HeaderAddressList {
|
||||
|
||||
/// If the address list is comprised of a single entry,
|
||||
/// returns just the display name portion, if any
|
||||
pub fn name(&self) -> anyhow::Result<Option<&str>> {
|
||||
pub fn name(&self) -> anyhow::Result<Option<&BStr>> {
|
||||
let addr = self.single_address()?;
|
||||
Ok(addr.name.as_deref())
|
||||
Ok(addr.name.as_ref().map(|b| b.as_bstr()))
|
||||
}
|
||||
|
||||
pub fn email(&self) -> anyhow::Result<Option<&str>> {
|
||||
@@ -285,7 +286,7 @@ impl From<&Address> for HeaderAddressEntry {
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct HeaderAddress {
|
||||
pub name: Option<String>,
|
||||
pub name: Option<BString>,
|
||||
pub address: Option<String>,
|
||||
}
|
||||
|
||||
@@ -310,8 +311,8 @@ impl HeaderAddress {
|
||||
pub fn email(&self) -> Option<&str> {
|
||||
self.address.as_deref()
|
||||
}
|
||||
pub fn name(&self) -> Option<&str> {
|
||||
self.name.as_deref()
|
||||
pub fn name(&self) -> Option<&BStr> {
|
||||
self.name.as_ref().map(|b| b.as_bstr())
|
||||
}
|
||||
|
||||
pub fn crack_address(&self) -> anyhow::Result<(&str, &str)> {
|
||||
|
||||
Reference in New Issue
Block a user