2018-12-02 14:05:27 +00:00
|
|
|
use batch::Batch;
|
2018-12-02 16:22:51 +00:00
|
|
|
use display::Display;
|
2018-12-04 12:29:54 +00:00
|
|
|
use meta::{FileType, Meta};
|
|
|
|
use std::path::{Path, PathBuf};
|
2018-11-16 13:19:07 +00:00
|
|
|
use Options;
|
|
|
|
|
|
|
|
pub struct Core<'a> {
|
|
|
|
options: &'a Options,
|
2018-12-04 13:54:56 +00:00
|
|
|
display: Display<'a>,
|
2018-11-16 13:19:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Core<'a> {
|
|
|
|
pub fn new(options: &'a Options) -> Core<'a> {
|
2018-12-04 13:54:56 +00:00
|
|
|
Core {
|
|
|
|
options,
|
|
|
|
display: Display::new(options),
|
|
|
|
}
|
2018-11-16 13:19:07 +00:00
|
|
|
}
|
|
|
|
|
2018-12-04 13:54:56 +00:00
|
|
|
pub fn run(self, paths: Vec<PathBuf>) {
|
|
|
|
self.run_inner(paths, 0);
|
|
|
|
}
|
2018-12-02 16:22:51 +00:00
|
|
|
|
2018-12-04 13:54:56 +00:00
|
|
|
fn run_inner(&self, paths: Vec<PathBuf>, depth: usize) {
|
2018-11-16 13:19:07 +00:00
|
|
|
let mut dirs = Vec::new();
|
|
|
|
let mut files = Vec::new();
|
|
|
|
|
2018-12-04 12:29:54 +00:00
|
|
|
for path in paths {
|
2018-11-16 13:19:07 +00:00
|
|
|
if path.is_dir() {
|
|
|
|
dirs.push(path);
|
2018-12-04 12:29:54 +00:00
|
|
|
} else if let Some(meta) = Meta::from_path(&path) {
|
|
|
|
files.push(meta);
|
2018-11-16 13:19:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-02 14:05:27 +00:00
|
|
|
let print_folder_name: bool = dirs.len() + files.len() > 1;
|
2018-11-16 13:19:07 +00:00
|
|
|
|
2018-12-04 13:54:56 +00:00
|
|
|
if !files.is_empty() && !self.options.display_tree {
|
2018-12-02 16:22:51 +00:00
|
|
|
let mut file_batch = Batch::from(files);
|
|
|
|
file_batch.sort();
|
2018-12-04 13:54:56 +00:00
|
|
|
self.display
|
|
|
|
.print_outputs(self.get_batch_outputs(&file_batch));
|
2018-12-02 16:22:51 +00:00
|
|
|
}
|
2018-12-02 14:05:27 +00:00
|
|
|
|
|
|
|
dirs.sort_unstable();
|
2018-11-16 13:19:07 +00:00
|
|
|
|
|
|
|
for dir in dirs {
|
2018-12-04 12:29:54 +00:00
|
|
|
if let Some(folder_batch) = self.list_folder_content(dir.as_path()) {
|
2018-12-04 13:54:56 +00:00
|
|
|
if (print_folder_name || self.options.recursive) && !self.options.display_tree {
|
2018-12-02 14:05:27 +00:00
|
|
|
println!("\n{}:", dir.display())
|
|
|
|
}
|
2018-11-24 11:02:39 +00:00
|
|
|
|
2018-12-04 13:54:56 +00:00
|
|
|
if self.options.display_tree {
|
|
|
|
self.display_as_tree(folder_batch, depth);
|
|
|
|
} else if self.options.recursive {
|
|
|
|
self.display
|
|
|
|
.print_outputs(self.get_batch_outputs(&folder_batch));
|
2018-12-04 12:29:54 +00:00
|
|
|
|
|
|
|
let folder_dirs = folder_batch
|
|
|
|
.into_iter()
|
|
|
|
.filter_map(|x| {
|
|
|
|
if x.file_type == FileType::Directory {
|
|
|
|
Some(x.path)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}).collect();
|
|
|
|
|
2018-12-04 13:54:56 +00:00
|
|
|
self.run_inner(folder_dirs, depth);
|
|
|
|
} else {
|
|
|
|
self.display
|
|
|
|
.print_outputs(self.get_batch_outputs(&folder_batch));
|
2018-12-04 12:29:54 +00:00
|
|
|
}
|
2018-11-16 13:19:07 +00:00
|
|
|
}
|
2018-11-24 16:42:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-04 13:54:56 +00:00
|
|
|
pub fn display_as_tree(&self, batch: Batch, depth: usize) {
|
|
|
|
let last_idx = batch.len();
|
|
|
|
|
|
|
|
for (idx, elem) in batch.into_iter().enumerate() {
|
|
|
|
let last = !(idx + 1 == last_idx);
|
|
|
|
|
|
|
|
if elem.file_type == FileType::Directory {
|
|
|
|
self.display
|
|
|
|
.print_tree_row(elem.name.render().to_string(), depth, last);
|
|
|
|
self.run_inner(vec![elem.path], depth + 1);
|
|
|
|
} else {
|
|
|
|
self.display
|
|
|
|
.print_tree_row(elem.name.render().to_string(), depth, last);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-02 16:22:51 +00:00
|
|
|
pub fn get_batch_outputs<'b>(&self, batch: &'b Batch) -> Vec<String> {
|
2018-11-24 16:42:39 +00:00
|
|
|
if self.options.display_long {
|
2018-12-02 16:22:51 +00:00
|
|
|
batch.get_long_output()
|
2018-11-24 16:42:39 +00:00
|
|
|
} else {
|
2018-12-02 16:22:51 +00:00
|
|
|
batch.get_short_output()
|
2018-11-24 16:42:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-02 14:05:27 +00:00
|
|
|
pub fn list_folder_content(&self, folder: &Path) -> Option<Batch> {
|
|
|
|
let mut metas: Vec<Meta> = Vec::new();
|
2018-11-16 13:19:07 +00:00
|
|
|
|
2018-11-24 11:02:39 +00:00
|
|
|
let dir = match folder.read_dir() {
|
|
|
|
Ok(dir) => dir,
|
|
|
|
Err(err) => {
|
|
|
|
println!("cannot open directory'{}': {}", folder.display(), err);
|
2018-12-02 14:05:27 +00:00
|
|
|
return None;
|
2018-11-24 11:02:39 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
for entry in dir {
|
2018-11-16 13:19:07 +00:00
|
|
|
if let Ok(entry) = entry {
|
2018-12-04 12:29:54 +00:00
|
|
|
if let Some(meta) = Meta::from_path(&entry.path()) {
|
2018-12-04 10:15:05 +00:00
|
|
|
if !meta.name.is_hidden() || self.options.display_all {
|
|
|
|
metas.push(meta);
|
|
|
|
}
|
2018-11-16 13:19:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-02 14:05:27 +00:00
|
|
|
let mut batch = Batch::from(metas);
|
|
|
|
batch.sort();
|
2018-11-16 13:19:07 +00:00
|
|
|
|
2018-12-02 14:05:27 +00:00
|
|
|
Some(batch)
|
2018-11-16 13:19:07 +00:00
|
|
|
}
|
|
|
|
}
|