diff options
Diffstat (limited to 'src/cmd/folders.rs')
-rw-r--r-- | src/cmd/folders.rs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/cmd/folders.rs b/src/cmd/folders.rs new file mode 100644 index 0000000..7bf93f1 --- /dev/null +++ b/src/cmd/folders.rs @@ -0,0 +1,48 @@ +use std::collections::BTreeSet; +use std::ffi::{OsStr, OsString}; +use std::path::Path; + +use lazy_static::lazy_static; +use maildir::Maildir; + +use crate::error::Result; + +lazy_static! { + static ref REQUIRED_MAILDIR_DIRS: BTreeSet<OsString> = [ + OsString::from("cur"), + "new".into(), + "tmp".into(), + "maildirfolder".into(), + ] + .into(); +} + +fn is_mailsubdir(p: &Path) -> bool { + p.is_dir() + && p.file_name() + .map_or(false, |fname| fname.to_string_lossy().starts_with('.')) + && p.read_dir() + .map(|dir| { + dir.filter_map(|child| { + child + .ok() + .and_then(|dir_entry| dir_entry.path().file_name().map(OsStr::to_owned)) + }) + .collect::<BTreeSet<_>>() + .is_superset(&REQUIRED_MAILDIR_DIRS) + }) + .unwrap_or_default() +} + +pub fn folders(md: &Maildir) -> Result<Vec<String>> { + let root_path = md.path(); + + let subdirs = root_path + .read_dir()? + .filter_map(|d| d.ok()) + .filter(|d| is_mailsubdir(&d.path())) + .filter_map(|d| Some(d.path().file_name()?.to_string_lossy()[1..].to_owned())) + .collect(); + + Ok(subdirs) +} |