melib: add ShellExpandTrait

Add trait to expand "~" and environment variables in paths.
embed
Manos Pitsidianakis 2019-09-26 18:27:13 +03:00
parent 0ece51612f
commit 9d69a06807
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
4 changed files with 54 additions and 6 deletions

View File

@ -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("/")),
) {

View File

@ -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 {

View File

@ -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(),

View File

@ -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
}
}
}