Add the --recursive option

This commit is contained in:
Peltoche 2018-12-04 13:29:54 +01:00
parent 823b04a258
commit 8989ca44fe
No known key found for this signature in database
GPG key ID: CED68D0487156952
4 changed files with 44 additions and 16 deletions

View file

@ -2,6 +2,8 @@ use ansi_term::{ANSIString, ANSIStrings};
use meta::FileType;
use meta::Meta;
use std::cmp::Ordering;
use std::iter::IntoIterator;
use std::vec::IntoIter;
pub struct Batch(Vec<Meta>);
@ -11,6 +13,15 @@ impl From<Vec<Meta>> for Batch {
}
}
impl IntoIterator for Batch {
type Item = Meta;
type IntoIter = IntoIter<Meta>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl Batch {
pub fn sort(&mut self) {
self.0.sort_unstable_by(sort_by_meta);

View file

@ -1,7 +1,7 @@
use batch::Batch;
use display::Display;
use meta::Meta;
use std::path::Path;
use meta::{FileType, Meta};
use std::path::{Path, PathBuf};
use Options;
pub struct Core<'a> {
@ -13,21 +13,17 @@ impl<'a> Core<'a> {
Core { options }
}
pub fn run(&self, inputs: Vec<&str>) {
pub fn run(&self, paths: Vec<PathBuf>) {
let display = Display::new(self.options);
let mut dirs = Vec::new();
let mut files = Vec::new();
for input in inputs {
let path = Path::new(input);
for path in paths {
if path.is_dir() {
dirs.push(path);
} else {
if let Some(meta) = Meta::from_path(path) {
files.push(meta);
}
} else if let Some(meta) = Meta::from_path(&path) {
files.push(meta);
}
}
@ -42,12 +38,26 @@ impl<'a> Core<'a> {
dirs.sort_unstable();
for dir in dirs {
if let Some(folder_batch) = self.list_folder_content(dir) {
if print_folder_name {
if let Some(folder_batch) = self.list_folder_content(dir.as_path()) {
if print_folder_name || self.options.recursive {
println!("\n{}:", dir.display())
}
display.print_outputs(self.get_batch_outputs(&folder_batch));
if self.options.recursive {
let folder_dirs = folder_batch
.into_iter()
.filter_map(|x| {
if x.file_type == FileType::Directory {
Some(x.path)
} else {
None
}
}).collect();
self.run(folder_dirs);
}
}
}
}
@ -73,7 +83,7 @@ impl<'a> Core<'a> {
for entry in dir {
if let Ok(entry) = entry {
if let Some(meta) = Meta::from_path(entry.path().as_path()) {
if let Some(meta) = Meta::from_path(&entry.path()) {
if !meta.name.is_hidden() || self.options.display_all {
metas.push(meta);
}

View file

@ -17,11 +17,13 @@ mod meta;
use clap::{App, Arg};
use core::Core;
use std::path::PathBuf;
pub struct Options {
pub display_all: bool,
pub display_long: bool,
pub display_online: bool,
pub recursive: bool,
}
fn main() {
@ -31,17 +33,20 @@ fn main() {
.arg(Arg::with_name("all").short("a").long("all"))
.arg(Arg::with_name("long").short("l").long("long"))
.arg(Arg::with_name("oneline").short("1").long("oneline"))
.arg(Arg::with_name("recursive").short("R").long("recursive"))
.get_matches();
let options = Options {
display_all: matches.is_present("all"),
display_long: matches.is_present("long"),
display_online: matches.is_present("oneline"),
recursive: matches.is_present("recursive"),
};
let inputs: Vec<&str> = matches
let inputs = matches
.values_of("FILE")
.expect("failed to retrieve cli value")
.map(PathBuf::from)
.collect();
let core = Core::new(&options);

View file

@ -15,11 +15,12 @@ pub use self::size::Size;
pub use self::symlink::SymLink;
use std::fs::read_link;
use std::path::Path;
use std::path::PathBuf;
#[derive(Debug)]
pub struct Meta {
pub name: Name,
pub path: PathBuf,
pub permissions: Permissions,
pub date: Date,
pub owner: Owner,
@ -29,7 +30,7 @@ pub struct Meta {
}
impl Meta {
pub fn from_path(path: &Path) -> Option<Self> {
pub fn from_path(path: &PathBuf) -> Option<Self> {
let mut metadata = match path.metadata() {
Ok(res) => res,
Err(err) => {
@ -51,6 +52,7 @@ impl Meta {
}
Some(Meta {
path: path.to_path_buf(),
symlink: SymLink::from_path(&path),
size: Size::from(&metadata),
permissions: Permissions::from(&metadata),