melib: add display() method for Address

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
pull/314/head
Manos Pitsidianakis 2023-11-15 12:52:23 +02:00
parent 688e39a67e
commit ac2a5dcdd1
Signed by: Manos Pitsidianakis
GPG Key ID: 7729C7707F7E09D0
2 changed files with 56 additions and 3 deletions

View File

@ -405,14 +405,15 @@ pub struct EntryStrings {
}
#[macro_export]
/// Creates a comma separated list `String` out of an `Address` iterable.
/// Creates a comma separated list `String` out of an
/// [`Address`](melib::Address) iterable.
macro_rules! address_list {
(($name:expr) as comma_sep_list) => {{
let mut ret: String =
$name
.into_iter()
.fold(String::new(), |mut s: String, n: &Address| {
s.extend(n.to_string().chars());
s.extend(n.display().to_string().chars());
s.push_str(", ");
s
});

View File

@ -306,6 +306,30 @@ impl Address {
Self::Group(g) => g.display_name.display_bytes(&g.raw),
}
}
/// Returns a type that prints addresses suitably for UI display, e.g.
/// without quotes.
///
/// ## Example
///
/// ```rust
/// # use melib::email::Address;
/// let addr = Address::new(
/// Some("Jörg T. Doe".to_string()),
/// "joerg@example.com".to_string(),
/// );
/// assert_eq!(
/// addr.to_string().as_str(),
/// r#""Jörg T. Doe" <joerg@example.com>"#
/// );
/// assert_eq!(
/// addr.display().to_string().as_str(),
/// "Jörg T. Doe <joerg@example.com>"
/// );
/// ```
pub fn display(&self) -> UIAddress {
UIAddress(self)
}
}
impl Eq for Address {}
@ -349,6 +373,7 @@ impl std::fmt::Display for Address {
}
d => write!(f, "{} <{}>", d, m.address_spec.display(&m.raw)),
},
Self::Mailbox(m) => write!(f, "{}", m.address_spec.display(&m.raw)),
Self::Group(g) => {
let attachment_strings: Vec<String> =
g.mailbox_list.iter().map(|a| format!("{}", a)).collect();
@ -359,7 +384,6 @@ impl std::fmt::Display for Address {
attachment_strings.join(", ")
)
}
Self::Mailbox(m) => write!(f, "{}", m.address_spec.display(&m.raw)),
}
}
}
@ -393,6 +417,34 @@ impl TryFrom<&str> for Address {
}
}
#[derive(Debug, Copy, Clone)]
#[repr(transparent)]
pub struct UIAddress<'a>(&'a Address);
impl std::fmt::Display for UIAddress<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self.0 {
Address::Mailbox(m) if m.display_name.length > 0 => write!(
f,
"{} <{}>",
m.display_name.display(&m.raw),
m.address_spec.display(&m.raw)
),
Address::Mailbox(m) => write!(f, "{}", m.address_spec.display(&m.raw)),
Address::Group(g) => {
let attachment_strings: Vec<String> =
g.mailbox_list.iter().map(|a| format!("{}", a)).collect();
write!(
f,
"{}: {}",
g.display_name.display(&g.raw),
attachment_strings.join(", ")
)
}
}
}
}
/// Helper struct to return slices from a struct field on demand.
#[derive(Clone, Debug, Serialize, Deserialize, Default, PartialEq, Eq, Copy, Hash)]
pub struct StrBuilder {