Add get_text_body()

This commit is contained in:
Andrey Golovizin 2021-07-17 18:16:49 +02:00
parent 868a9d238d
commit ed7be8e731
2 changed files with 98 additions and 3 deletions

View file

@ -1,7 +1,11 @@
mod parsing;
use parsing::ParsedMailEx;
use anyhow::anyhow; use anyhow::anyhow;
use clap::Clap; use clap::Clap;
use mailparse::MailHeaderMap; use mailparse::MailHeaderMap;
use std::io::Read; use std::io::Read;
/// MIME mail viewer. /// MIME mail viewer.
@ -38,9 +42,10 @@ fn main() -> Result<(), anyhow::Error> {
dbg!(&date_str); dbg!(&date_str);
let date = chrono::DateTime::parse_from_rfc2822(&date_str)?; let date = chrono::DateTime::parse_from_rfc2822(&date_str)?;
println!("Date: {}", date); println!("Date: {}", date);
// dbg!(&message); dbg!(&message.ctype);
dbg!(&message.get_content_disposition());
// //
let body = message.get_body()?; let body = message.get_body_text()?.unwrap_or_default();
println!("---"); println!("---");
print!("{}", body); print!("{}", body);
Ok(()) Ok(())

90
src/parsing.rs Normal file
View file

@ -0,0 +1,90 @@
use mailparse::{DispositionType, MailParseError, ParsedMail};
pub trait ParsedMailEx {
fn is_attachment(&self) -> bool;
fn get_body_text(&self) -> Result<Option<String>, MailParseError>;
}
impl<'a> ParsedMailEx for ParsedMail<'a> {
fn is_attachment(&self) -> bool {
self.get_content_disposition().disposition == DispositionType::Attachment
}
fn get_body_text(&self) -> Result<Option<String>, MailParseError> {
if self.is_attachment() {
return Ok(None);
}
if self.ctype.mimetype == "text/plain" {
return Ok(Some(self.get_body()?));
}
for subpart in &self.subparts {
if let Some(body) = subpart.get_body_text()? {
return Ok(Some(body));
}
}
Ok(None)
}
}
#[cfg(test)]
mod test {
use super::*;
const TEXT_PLAIN: &str = r#"From: Andrey Golovizin <ag@sologoc.com>
To: ag@sologoc.com
Subject: Plain text body
Date: Sat, 17 Jul 2021 18:04:10 +0200
Message-ID: <2148453.iZASKD2KPV@sakuragaoka>
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="iso-8859-1"
Prost=FD text.
"#;
const MULTIPART_ALTERNATIVE: &str = r#"From: Andrey Golovizin <ag@sologoc.com>
Subject: Plain text with html
Date: Sat, 17 Jul 2021 18:13:26 +0200
Message-ID: <3609140.kQq0lBPeGt@sakuragaoka>
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="nextPart3377186.iIbC2pHGDl"
Content-Transfer-Encoding: 7Bit
This is a multi-part message in MIME format.
--nextPart3377186.iIbC2pHGDl
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="iso-8859-1"
Prost=FD text.
--nextPart3377186.iIbC2pHGDl
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="UTF-8"
<html>
<head>
<meta http-equiv=3D"content-type" content=3D"text/html; charset=3DUTF-8">
</head>
<body><p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0=
;"><strong>N=C4=9Bjaky HTML text.</strong></p>
</body>
</html>
--nextPart3377186.iIbC2pHGDl--
"#;
#[test]
fn test_plain_text_body() -> Result<(), anyhow::Error> {
let message = mailparse::parse_mail(TEXT_PLAIN.as_bytes())?;
assert_eq!(message.get_body_text()?.unwrap_or_default(), "Prostý text.");
Ok(())
}
#[test]
fn test_multipart_alternative_text_body() -> Result<(), anyhow::Error> {
let message = mailparse::parse_mail(MULTIPART_ALTERNATIVE.as_bytes())?;
assert_eq!(message.get_body_text()?.unwrap_or_default(), "Prostý text.");
Ok(())
}
}