Add option to include content-type params in fingerprint

This commit is contained in:
Bill Thiede 2023-12-02 12:47:46 -08:00
parent 199669d302
commit 34293e03d2
3 changed files with 23 additions and 11 deletions

View File

@ -32,6 +32,10 @@ struct Args {
#[arg(short, long, default_value_t = 10)]
top_n: usize,
/// Include subpart params in fingerprint
#[arg(short, long)]
include_params: bool,
/// List of input directories to recursively search
input_dir: String,
}
@ -68,7 +72,7 @@ fn main() -> anyhow::Result<()> {
if should_skip(&arg) {
return None;
}
match parse(&arg, youngest) {
match parse(&arg, youngest, args.include_params) {
Ok(Some(h)) => Some((h, arg)),
// Skip old emails
Ok(None) => return None,
@ -116,7 +120,11 @@ fn main() -> anyhow::Result<()> {
}
// If the date in the email is before youngest Ok(None) will be returned.
fn parse<P: AsRef<Path>>(path: P, youngest: i64) -> Result<Option<String>, EmailError> {
fn parse<P: AsRef<Path>>(
path: P,
youngest: i64,
include_params: bool,
) -> Result<Option<String>, EmailError> {
let file = File::open(&path)?;
let mmap = unsafe { MmapOptions::new().map(&file)? };
let m = parse_mail(&mmap)?;
@ -131,5 +139,5 @@ fn parse<P: AsRef<Path>>(path: P, youngest: i64) -> Result<Option<String>, Email
return Ok(None);
}
//println!("{}: {:#?}", path.as_ref().display(), m.ctype);
Ok(Some(fingerprint(&m).join("\n")))
Ok(Some(fingerprint(&m, include_params).join("\n")))
}

View File

@ -23,7 +23,7 @@ fn main() -> anyhow::Result<()> {
.headers
.get_first_value("subject")
.unwrap_or("(NO SUBJECT)".to_owned());
println!("{subject}: {path}\n{}", fingerprint(&m).join("\n"));
println!("{subject}: {path}\n{}", fingerprint(&m, false).join("\n"));
}
Ok(())
}

View File

@ -65,15 +65,19 @@ pub fn should_skip(path: &str) -> bool {
SKIP_FILES.contains(&filename)
}
pub fn fingerprint(pm: &ParsedMail<'_>) -> Vec<String> {
fingerprint_rec(pm, 0)
pub fn fingerprint(pm: &ParsedMail<'_>, include_params: bool) -> Vec<String> {
fingerprint_rec(pm, include_params, 0)
}
fn fingerprint_rec(pm: &ParsedMail<'_>, depth: usize) -> Vec<String> {
let mut v = vec![format!("{}{}", " ".repeat(depth * 2), pm.ctype.mimetype)];
for c in &pm.subparts {
v.extend(fingerprint_rec(&c, depth + 1));
fn fingerprint_rec(pm: &ParsedMail<'_>, include_params: bool, depth: usize) -> Vec<String> {
let indent = " ".repeat(depth * 2);
let mut parts = vec![format!("{}{}", indent, pm.ctype.mimetype)];
for (k, v) in &pm.ctype.params {
parts.push(format!("{indent} {k}: {v}"));
}
v
for c in &pm.subparts {
parts.extend(fingerprint_rec(&c, include_params, depth + 1));
}
parts
}
#[cfg(test)]