mirror of
https://github.com/lsd-rs/lsd
synced 2024-12-14 14:12:31 +00:00
Add the --recursive option
This commit is contained in:
parent
823b04a258
commit
8989ca44fe
4 changed files with 44 additions and 16 deletions
11
src/batch.rs
11
src/batch.rs
|
@ -2,6 +2,8 @@ use ansi_term::{ANSIString, ANSIStrings};
|
||||||
use meta::FileType;
|
use meta::FileType;
|
||||||
use meta::Meta;
|
use meta::Meta;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
use std::iter::IntoIterator;
|
||||||
|
use std::vec::IntoIter;
|
||||||
|
|
||||||
pub struct Batch(Vec<Meta>);
|
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 {
|
impl Batch {
|
||||||
pub fn sort(&mut self) {
|
pub fn sort(&mut self) {
|
||||||
self.0.sort_unstable_by(sort_by_meta);
|
self.0.sort_unstable_by(sort_by_meta);
|
||||||
|
|
34
src/core.rs
34
src/core.rs
|
@ -1,7 +1,7 @@
|
||||||
use batch::Batch;
|
use batch::Batch;
|
||||||
use display::Display;
|
use display::Display;
|
||||||
use meta::Meta;
|
use meta::{FileType, Meta};
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
use Options;
|
use Options;
|
||||||
|
|
||||||
pub struct Core<'a> {
|
pub struct Core<'a> {
|
||||||
|
@ -13,23 +13,19 @@ impl<'a> Core<'a> {
|
||||||
Core { options }
|
Core { options }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&self, inputs: Vec<&str>) {
|
pub fn run(&self, paths: Vec<PathBuf>) {
|
||||||
let display = Display::new(self.options);
|
let display = Display::new(self.options);
|
||||||
|
|
||||||
let mut dirs = Vec::new();
|
let mut dirs = Vec::new();
|
||||||
let mut files = Vec::new();
|
let mut files = Vec::new();
|
||||||
|
|
||||||
for input in inputs {
|
for path in paths {
|
||||||
let path = Path::new(input);
|
|
||||||
|
|
||||||
if path.is_dir() {
|
if path.is_dir() {
|
||||||
dirs.push(path);
|
dirs.push(path);
|
||||||
} else {
|
} else if let Some(meta) = Meta::from_path(&path) {
|
||||||
if let Some(meta) = Meta::from_path(path) {
|
|
||||||
files.push(meta);
|
files.push(meta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let print_folder_name: bool = dirs.len() + files.len() > 1;
|
let print_folder_name: bool = dirs.len() + files.len() > 1;
|
||||||
|
|
||||||
|
@ -42,12 +38,26 @@ impl<'a> Core<'a> {
|
||||||
dirs.sort_unstable();
|
dirs.sort_unstable();
|
||||||
|
|
||||||
for dir in dirs {
|
for dir in dirs {
|
||||||
if let Some(folder_batch) = self.list_folder_content(dir) {
|
if let Some(folder_batch) = self.list_folder_content(dir.as_path()) {
|
||||||
if print_folder_name {
|
if print_folder_name || self.options.recursive {
|
||||||
println!("\n{}:", dir.display())
|
println!("\n{}:", dir.display())
|
||||||
}
|
}
|
||||||
|
|
||||||
display.print_outputs(self.get_batch_outputs(&folder_batch));
|
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 {
|
for entry in dir {
|
||||||
if let Ok(entry) = entry {
|
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 {
|
if !meta.name.is_hidden() || self.options.display_all {
|
||||||
metas.push(meta);
|
metas.push(meta);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,13 @@ mod meta;
|
||||||
|
|
||||||
use clap::{App, Arg};
|
use clap::{App, Arg};
|
||||||
use core::Core;
|
use core::Core;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
pub display_all: bool,
|
pub display_all: bool,
|
||||||
pub display_long: bool,
|
pub display_long: bool,
|
||||||
pub display_online: bool,
|
pub display_online: bool,
|
||||||
|
pub recursive: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -31,17 +33,20 @@ fn main() {
|
||||||
.arg(Arg::with_name("all").short("a").long("all"))
|
.arg(Arg::with_name("all").short("a").long("all"))
|
||||||
.arg(Arg::with_name("long").short("l").long("long"))
|
.arg(Arg::with_name("long").short("l").long("long"))
|
||||||
.arg(Arg::with_name("oneline").short("1").long("oneline"))
|
.arg(Arg::with_name("oneline").short("1").long("oneline"))
|
||||||
|
.arg(Arg::with_name("recursive").short("R").long("recursive"))
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
let options = Options {
|
let options = Options {
|
||||||
display_all: matches.is_present("all"),
|
display_all: matches.is_present("all"),
|
||||||
display_long: matches.is_present("long"),
|
display_long: matches.is_present("long"),
|
||||||
display_online: matches.is_present("oneline"),
|
display_online: matches.is_present("oneline"),
|
||||||
|
recursive: matches.is_present("recursive"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let inputs: Vec<&str> = matches
|
let inputs = matches
|
||||||
.values_of("FILE")
|
.values_of("FILE")
|
||||||
.expect("failed to retrieve cli value")
|
.expect("failed to retrieve cli value")
|
||||||
|
.map(PathBuf::from)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let core = Core::new(&options);
|
let core = Core::new(&options);
|
||||||
|
|
|
@ -15,11 +15,12 @@ pub use self::size::Size;
|
||||||
pub use self::symlink::SymLink;
|
pub use self::symlink::SymLink;
|
||||||
|
|
||||||
use std::fs::read_link;
|
use std::fs::read_link;
|
||||||
use std::path::Path;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Meta {
|
pub struct Meta {
|
||||||
pub name: Name,
|
pub name: Name,
|
||||||
|
pub path: PathBuf,
|
||||||
pub permissions: Permissions,
|
pub permissions: Permissions,
|
||||||
pub date: Date,
|
pub date: Date,
|
||||||
pub owner: Owner,
|
pub owner: Owner,
|
||||||
|
@ -29,7 +30,7 @@ pub struct Meta {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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() {
|
let mut metadata = match path.metadata() {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -51,6 +52,7 @@ impl Meta {
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(Meta {
|
Some(Meta {
|
||||||
|
path: path.to_path_buf(),
|
||||||
symlink: SymLink::from_path(&path),
|
symlink: SymLink::from_path(&path),
|
||||||
size: Size::from(&metadata),
|
size: Size::from(&metadata),
|
||||||
permissions: Permissions::from(&metadata),
|
permissions: Permissions::from(&metadata),
|
||||||
|
|
Loading…
Reference in a new issue