summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2019-09-26 18:27:13 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2019-09-26 18:27:13 +0300
commit9d69a068073e89bd965b49acf314556eeab2fe54 (patch)
tree2af289cb0772803b9eb9871920999f5f5013d8f8
parent0ece51612f68db228f6ff75e05a465ea103ceede (diff)
melib: add ShellExpandTrait
Add trait to expand "~" and environment variables in paths.
-rw-r--r--melib/src/backends/maildir.rs2
-rw-r--r--melib/src/backends/maildir/backend.rs5
-rw-r--r--melib/src/backends/mbox.rs9
-rw-r--r--melib/src/lib.rs44
4 files changed, 54 insertions, 6 deletions
diff --git a/melib/src/backends/maildir.rs b/melib/src/backends/maildir.rs
index e346bd90..6fbb8d10 100644
--- a/melib/src/backends/maildir.rs
+++ b/melib/src/backends/maildir.rs
@@ -27,6 +27,7 @@ use crate::backends::*;
use crate::email::parser;
use crate::email::{Envelope, Flag};
use crate::error::{MeliError, Result};
+use crate::shellexpand::ShellExpandTrait;
use memmap::{Mmap, Protection};
use std::collections::hash_map::DefaultHasher;
@@ -208,6 +209,7 @@ impl MaildirFolder {
* mailboxes in user configuration */
let fname = if let Ok(fname) = pathbuf.strip_prefix(
PathBuf::from(&settings.root_folder)
+ .expand()
.parent()
.unwrap_or_else(|| &Path::new("/")),
) {
diff --git a/melib/src/backends/maildir/backend.rs b/melib/src/backends/maildir/backend.rs
index e51eec32..ae6984f9 100644
--- a/melib/src/backends/maildir/backend.rs
+++ b/melib/src/backends/maildir/backend.rs
@@ -28,6 +28,7 @@ use crate::async_workers::*;
use crate::conf::AccountSettings;
use crate::email::{Envelope, EnvelopeHash, Flag};
use crate::error::{MeliError, Result};
+use crate::shellexpand::ShellExpandTrait;
extern crate notify;
use self::notify::{watcher, DebouncedEvent, RecursiveMode, Watcher};
@@ -583,7 +584,7 @@ impl MaildirType {
}
children
};
- let root_path = PathBuf::from(settings.root_folder());
+ let root_path = PathBuf::from(settings.root_folder()).expand();
if !root_path.exists() {
eprintln!(
"Configuration error ({}): root_path `{}` is not a valid directory.",
@@ -651,7 +652,7 @@ impl MaildirType {
name: settings.name().to_string(),
folders,
hash_indexes,
- path: PathBuf::from(settings.root_folder()),
+ path: root_path,
}
}
fn owned_folder_idx(&self, folder: &Folder) -> FolderHash {
diff --git a/melib/src/backends/mbox.rs b/melib/src/backends/mbox.rs
index 16368f5d..132db42a 100644
--- a/melib/src/backends/mbox.rs
+++ b/melib/src/backends/mbox.rs
@@ -33,6 +33,7 @@ use crate::conf::AccountSettings;
use crate::email::parser::BytesExt;
use crate::email::*;
use crate::error::{MeliError, Result};
+use crate::shellexpand::ShellExpandTrait;
use fnv::FnvHashMap;
use libc;
use memmap::{Mmap, Protection};
@@ -548,7 +549,7 @@ impl MailBackend for MboxType {
impl MboxType {
pub fn new(s: &AccountSettings, _is_subscribed: Box<dyn Fn(&str) -> bool>) -> Self {
- let path = Path::new(s.root_folder.as_str());
+ let path = Path::new(s.root_folder.as_str()).expand();
if !path.exists() {
panic!(
"\"root_folder\" {} for account {} is not a valid path.",
@@ -557,7 +558,7 @@ impl MboxType {
);
}
let ret = MboxType {
- path: PathBuf::from(path),
+ path,
..Default::default()
};
let name: String = ret
@@ -565,12 +566,12 @@ impl MboxType {
.file_name()
.map(|f| f.to_string_lossy().into())
.unwrap_or(String::new());
- let hash = get_path_hash!(path);
+ let hash = get_path_hash!(&ret.path);
ret.folders.lock().unwrap().insert(
hash,
MboxFolder {
hash,
- path: PathBuf::from(path),
+ path: ret.path.clone(),
name,
content: Vec::new(),
children: Vec::new(),
diff --git a/melib/src/lib.rs b/melib/src/lib.rs
index 1a459469..38ebfce2 100644
--- a/melib/src/lib.rs
+++ b/melib/src/lib.rs
@@ -128,3 +128,47 @@ pub use crate::email::{Envelope, Flag};
pub use crate::error::{MeliError, Result};
pub use crate::addressbook::*;
+
+pub use shellexpand::ShellExpandTrait;
+pub mod shellexpand {
+
+ use std::path::*;
+
+ pub trait ShellExpandTrait {
+ fn expand(&self) -> PathBuf;
+ }
+
+ impl ShellExpandTrait for Path {
+ fn expand(&self) -> PathBuf {
+ let mut ret = PathBuf::new();
+ for c in self.components() {
+ let c_to_str = c.as_os_str().to_str();
+ match c_to_str {
+ Some("~") => {
+ if let Some(home_dir) = std::env::var("HOME").ok() {
+ ret.push(home_dir)
+ } else {
+ return PathBuf::new();
+ }
+ }
+ Some(var) if var.starts_with("$") => {
+ let env_name = var.split_at(1).1;
+ if env_name.chars().all(char::is_uppercase) {
+ ret.push(std::env::var(env_name).unwrap_or(String::new()));
+ } else {
+ ret.push(c);
+ }
+ }
+ Some(_) => {
+ ret.push(c);
+ }
+ None => {
+ /* path is invalid */
+ return PathBuf::new();
+ }
+ }
+ }
+ ret
+ }
+ }
+}