diff --git a/src/backends/maildir/maildir_backend.rs b/src/backends/maildir/maildir_backend.rs index 9038d8a..a52dd13 100644 --- a/src/backends/maildir/maildir_backend.rs +++ b/src/backends/maildir/maildir_backend.rs @@ -5,7 +5,7 @@ use anyhow::{anyhow, Context, Result}; use log::{debug, info, trace}; -use std::{convert::TryInto, fs, path::PathBuf}; +use std::{convert::TryInto, env, fs, path::PathBuf}; use crate::{ backends::{Backend, IdMapper, MaildirEnvelopes, MaildirFlags, MaildirMboxes}, @@ -41,33 +41,32 @@ impl<'a> MaildirBackend<'a> { /// Creates a maildir instance from a string slice. pub fn get_mdir_from_dir(&self, dir: &str) -> Result { + let dir = self.account_config.get_mbox_alias(dir)?; + // If the dir points to the inbox folder, creates a maildir // instance from the root folder. - if dir.to_lowercase() == "inbox" { - self.validate_mdir_path(self.mdir.path().to_owned()) - .map(maildir::Maildir::from) - } else { - // If the dir is a valid maildir path, creates a maildir - // instance from it. Checks for absolute path first, - self.validate_mdir_path(dir.into()) - // then for relative path, - .or_else(|_| self.validate_mdir_path(self.mdir.path().join(dir))) - .or_else(|_| { - // otherwise creates a maildir instance from a - // maildir subdirectory by adding a "." in front - // of the name as described in the spec: - // https://cr.yp.to/proto/maildir.html. - let dir = self - .account_config - .mailboxes - .get(dir) - .map(|s| s.as_str()) - .unwrap_or(dir); - let path = self.mdir.path().join(format!(".{}", dir)); - self.validate_mdir_path(path) - }) - .map(maildir::Maildir::from) + if &dir == "inbox" { + return self + .validate_mdir_path(self.mdir.path().to_owned()) + .map(maildir::Maildir::from); } + + // If the dir is a valid maildir path, creates a maildir + // instance from it. First checks for absolute path, + self.validate_mdir_path((&dir).into()) + // then for relative path to `maildir-dir`, + .or_else(|_| self.validate_mdir_path(self.mdir.path().join(&dir))) + // and finally for relative path to the current directory. + .or_else(|_| self.validate_mdir_path(env::current_dir()?.join(&dir))) + .or_else(|_| { + // Otherwise creates a maildir instance from a maildir + // subdirectory by adding a "." in front of the name + // as described in the [spec]. + // + // [spec]: http://www.courier-mta.org/imap/README.maildirquota.html + self.validate_mdir_path(self.mdir.path().join(format!(".{}", dir))) + }) + .map(maildir::Maildir::from) } } diff --git a/src/config/account_config.rs b/src/config/account_config.rs index d821d0c..9a73e8f 100644 --- a/src/config/account_config.rs +++ b/src/config/account_config.rs @@ -317,6 +317,19 @@ impl<'a> AccountConfig { run_cmd(&cmd).context("cannot run notify cmd")?; Ok(()) } + + /// Gets the mailbox alias if exists, otherwise returns the + /// mailbox. Also tries to expand shell variables. + pub fn get_mbox_alias(&self, mbox: &str) -> Result { + let mbox = self + .mailboxes + .get(&mbox.trim().to_lowercase()) + .map(|s| s.as_str()) + .unwrap_or(mbox); + shellexpand::full(mbox) + .map(String::from) + .with_context(|| format!("cannot expand mailbox path {:?}", mbox)) + } } /// Represents all existing kind of account (backend).