From 3bab5324c4273bf335b881b2e48ac4067bcb661e Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Sun, 2 Jun 2024 12:15:33 +0300 Subject: [PATCH] melib/email: Improve Debug impl for ContentType etc Improve Debug impl for ContentType, Text, ContentTransferEncoding which all include bytes in some of their variants. The derived Debug implementation did not show them as readable ascii strings, so a custom impl was necessary to make it readable. Signed-off-by: Manos Pitsidianakis --- melib/src/email/attachment_types.rs | 100 +++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 3 deletions(-) diff --git a/melib/src/email/attachment_types.rs b/melib/src/email/attachment_types.rs index 6bb963e1..1560283b 100644 --- a/melib/src/email/attachment_types.rs +++ b/melib/src/email/attachment_types.rs @@ -243,7 +243,7 @@ impl> From for MultipartType { } } -#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +#[derive(Clone, Deserialize, Eq, Hash, PartialEq, Serialize)] pub enum ContentType { Text { kind: Text, @@ -270,6 +270,66 @@ pub enum ContentType { }, } +impl std::fmt::Debug for ContentType { + fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + macro_rules! fmt_params { + ($p:expr) => { + &$p.iter() + .map(|(b1, b2)| (String::from_utf8_lossy(b1), String::from_utf8_lossy(b2))) + .collect::>() + }; + } + match self { + Self::Text { + kind, + parameters, + charset, + } => fmt + .debug_struct(stringify!(ContentType::Text)) + .field("kind", &kind) + .field("parameters", fmt_params! { parameters }) + .field("charset", &charset) + .finish(), + Self::Multipart { + boundary, + parameters, + kind, + parts, + } => fmt + .debug_struct(stringify!(ContentType::Multipart)) + .field("kind", &kind) + .field("boundary", &String::from_utf8_lossy(boundary)) + .field("parameters", fmt_params! { parameters }) + .field("parts", &parts) + .finish(), + Self::MessageRfc822 => fmt + .debug_struct(stringify!(ContentType::MessageRfc822)) + .finish(), + Self::PGPSignature => fmt + .debug_struct(stringify!(ContentType::PGPSignature)) + .finish(), + Self::CMSSignature => fmt + .debug_struct(stringify!(ContentType::CMSSignature)) + .finish(), + Self::Other { + tag, + name, + parameters, + } => fmt + .debug_struct(stringify!(ContentType::Other)) + .field("tag", &String::from_utf8_lossy(tag)) + .field("name", name) + .field("parameters", fmt_params! { parameters }) + .finish(), + Self::OctetStream { name, parameters } => fmt + .debug_struct(stringify!(ContentType::OctetStream)) + .field("name", name) + .field("parameters", fmt_params! { parameters }) + .finish(), + } + } +} + impl Default for ContentType { fn default() -> Self { Self::Text { @@ -439,7 +499,7 @@ impl ContentType { } } -#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +#[derive(Clone, Deserialize, Eq, Hash, PartialEq, Serialize)] pub enum Text { Plain, Html, @@ -464,7 +524,18 @@ impl std::fmt::Display for Text { } } -#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, PartialEq, Serialize)] +impl std::fmt::Debug for Text { + fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Self::Plain => write!(fmt, "plain"), + Self::Html => write!(fmt, "html"), + Self::Rfc822 => write!(fmt, "rfc822"), + Self::Other { tag } => write!(fmt, "{}", String::from_utf8_lossy(tag)), + } + } +} + +#[derive(Clone, Default, Deserialize, Eq, Hash, PartialEq, Serialize)] pub enum ContentTransferEncoding { #[default] _8Bit, @@ -476,6 +547,29 @@ pub enum ContentTransferEncoding { }, } +impl std::fmt::Debug for ContentTransferEncoding { + fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Self::_7Bit => fmt + .debug_struct(stringify!(ContentTransferEncoding::_7Bit)) + .finish(), + Self::_8Bit => fmt + .debug_struct(stringify!(ContentTransferEncoding::_8Bit)) + .finish(), + Self::Base64 => fmt + .debug_struct(stringify!(ContentTransferEncoding::Base64)) + .finish(), + Self::QuotedPrintable => fmt + .debug_struct(stringify!(ContentTransferEncoding::QuotedPrintable)) + .finish(), + Self::Other { tag } => fmt + .debug_struct(stringify!(ContentTransferEncoding::Other)) + .field("tag", &String::from_utf8_lossy(tag)) + .finish(), + } + } +} + impl std::fmt::Display for ContentTransferEncoding { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match *self {