mirror of
https://github.com/lsd-rs/lsd
synced 2024-12-14 06:02:36 +00:00
Create the Batch struct
This commit is contained in:
parent
e4f08321a5
commit
2d6627ce7f
4 changed files with 151 additions and 137 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -47,7 +47,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "lsd"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1-pre"
|
||||
dependencies = [
|
||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
124
src/batch.rs
Normal file
124
src/batch.rs
Normal file
|
@ -0,0 +1,124 @@
|
|||
use meta::FileType;
|
||||
use meta::Meta;
|
||||
use std::cmp::Ordering;
|
||||
use term_grid::{Cell, Direction, Filling, Grid, GridOptions};
|
||||
use terminal_size::terminal_size;
|
||||
|
||||
pub struct Batch(Vec<Meta>);
|
||||
|
||||
impl From<Vec<Meta>> for Batch {
|
||||
fn from(metas: Vec<Meta>) -> Self {
|
||||
Batch(metas)
|
||||
}
|
||||
}
|
||||
|
||||
impl Batch {
|
||||
pub fn sort(&mut self) {
|
||||
self.0.sort_unstable_by(sort_by_meta);
|
||||
}
|
||||
|
||||
pub fn print_short(&self) {
|
||||
let term_width = match terminal_size() {
|
||||
Some((w, _)) => w.0 as usize,
|
||||
None => panic!("failed to retrieve terminal size"),
|
||||
};
|
||||
|
||||
let mut grid = Grid::new(GridOptions {
|
||||
filling: Filling::Spaces(1),
|
||||
direction: Direction::LeftToRight,
|
||||
});
|
||||
|
||||
for meta in &self.0 {
|
||||
let mut content = String::from(" ");
|
||||
content += &meta.name.render();
|
||||
grid.add(Cell {
|
||||
width: content.len(),
|
||||
contents: content,
|
||||
});
|
||||
}
|
||||
|
||||
println!(
|
||||
"{}",
|
||||
grid.fit_into_width(term_width * 2)
|
||||
.expect("failed to print the grid")
|
||||
);
|
||||
}
|
||||
|
||||
pub fn print_long(&self) {
|
||||
let max_user_length = self.detect_user_lenght();
|
||||
let max_group_length = self.detect_group_lenght();
|
||||
let (max_size_value_length, max_size_unit_length) = self.detect_size_lenghts();
|
||||
|
||||
for meta in &self.0 {
|
||||
let mut link_str = String::new();
|
||||
if let Some(ref symlink) = meta.symlink {
|
||||
link_str = symlink.render();
|
||||
}
|
||||
|
||||
println!(
|
||||
"{}{} {} {} {} {}{}",
|
||||
meta.file_type.render(),
|
||||
meta.permissions.render(),
|
||||
meta.owner.render(max_user_length, max_group_length),
|
||||
meta.size
|
||||
.render(max_size_value_length, max_size_unit_length),
|
||||
meta.date.render(),
|
||||
meta.name.render(),
|
||||
link_str,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn detect_user_lenght(&self) -> usize {
|
||||
let mut max: usize = 0;
|
||||
|
||||
for meta in &self.0 {
|
||||
let user = meta.owner.render_user();
|
||||
if user.len() > max {
|
||||
max = user.len();
|
||||
}
|
||||
}
|
||||
|
||||
max
|
||||
}
|
||||
|
||||
fn detect_group_lenght(&self) -> usize {
|
||||
let mut max: usize = 0;
|
||||
|
||||
for meta in &self.0 {
|
||||
let group = meta.owner.render_group();
|
||||
if group.len() > max {
|
||||
max = group.len();
|
||||
}
|
||||
}
|
||||
|
||||
max
|
||||
}
|
||||
|
||||
fn detect_size_lenghts(&self) -> (usize, usize) {
|
||||
let mut max_value_length: usize = 0;
|
||||
let mut max_unit_size: usize = 0;
|
||||
|
||||
for meta in &self.0 {
|
||||
if meta.size.render_value().len() > max_value_length {
|
||||
max_value_length = meta.size.render_value().len();
|
||||
}
|
||||
|
||||
if meta.size.render_unit().len() > max_unit_size {
|
||||
max_unit_size = meta.size.render_unit().len();
|
||||
}
|
||||
}
|
||||
|
||||
(max_value_length, max_unit_size)
|
||||
}
|
||||
}
|
||||
|
||||
fn sort_by_meta(a: &Meta, b: &Meta) -> Ordering {
|
||||
if a.file_type == FileType::Directory && b.file_type != FileType::Directory {
|
||||
Ordering::Less
|
||||
} else if b.file_type == FileType::Directory && a.file_type != FileType::Directory {
|
||||
Ordering::Greater
|
||||
} else {
|
||||
a.name.cmp(&b.name)
|
||||
}
|
||||
}
|
159
src/core.rs
159
src/core.rs
|
@ -1,8 +1,6 @@
|
|||
use meta::{FileType, Meta};
|
||||
use std::cmp::Ordering;
|
||||
use batch::Batch;
|
||||
use meta::Meta;
|
||||
use std::path::Path;
|
||||
use term_grid::{Cell, Direction, Filling, Grid, GridOptions};
|
||||
use terminal_size::terminal_size;
|
||||
use Options;
|
||||
|
||||
pub struct Core<'a> {
|
||||
|
@ -15,8 +13,6 @@ impl<'a> Core<'a> {
|
|||
}
|
||||
|
||||
pub fn run(&self, inputs: Vec<&str>) {
|
||||
let print_folder_name: bool = inputs.len() > 1;
|
||||
|
||||
let mut dirs = Vec::new();
|
||||
let mut files = Vec::new();
|
||||
|
||||
|
@ -28,101 +24,46 @@ impl<'a> Core<'a> {
|
|||
} else if path.is_file() {
|
||||
files.push(Meta::from(path));
|
||||
} else {
|
||||
match path.metadata() {
|
||||
Ok(_) => panic!("shouldn't failed"),
|
||||
Err(err) => println!("cannot access '{}': {}", path.display(), err),
|
||||
};
|
||||
let err = path.metadata().unwrap_err();
|
||||
println!("cannot access '{}': {}", path.display(), err);
|
||||
}
|
||||
}
|
||||
|
||||
files.sort_unstable_by(sort_by_meta);
|
||||
let print_folder_name: bool = dirs.len() + files.len() > 1;
|
||||
|
||||
let mut file_batch = Batch::from(files);
|
||||
file_batch.sort();
|
||||
self.print(&file_batch);
|
||||
|
||||
dirs.sort_unstable();
|
||||
|
||||
if !files.is_empty() {
|
||||
self.print(&files);
|
||||
}
|
||||
|
||||
for dir in dirs {
|
||||
let folder_metas = self.list_folder_content(dir);
|
||||
if folder_metas.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(folder_batch) = self.list_folder_content(dir) {
|
||||
if print_folder_name {
|
||||
println!("\n{}:", dir.display())
|
||||
}
|
||||
self.print(&folder_metas);
|
||||
|
||||
self.print(&folder_batch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn print(&self, metas: &[Meta]) {
|
||||
pub fn print<'b>(&self, batch: &'b Batch) {
|
||||
if self.options.display_long {
|
||||
self.print_long(metas)
|
||||
batch.print_long();
|
||||
} else {
|
||||
self.print_short(metas)
|
||||
batch.print_short();
|
||||
}
|
||||
}
|
||||
|
||||
fn print_short(&self, metas: &[Meta]) {
|
||||
let term_width = match terminal_size() {
|
||||
Some((w, _)) => w.0 as usize,
|
||||
None => panic!("failed to retrieve terminal size"),
|
||||
};
|
||||
|
||||
let mut grid = Grid::new(GridOptions {
|
||||
filling: Filling::Spaces(1),
|
||||
direction: Direction::LeftToRight,
|
||||
});
|
||||
|
||||
for meta in metas {
|
||||
let mut content = String::from(" ");
|
||||
content += &meta.name.render();
|
||||
grid.add(Cell {
|
||||
width: content.len(),
|
||||
contents: content,
|
||||
});
|
||||
}
|
||||
|
||||
println!(
|
||||
"{}",
|
||||
grid.fit_into_width(term_width * 2)
|
||||
.expect("failed to print the grid")
|
||||
);
|
||||
}
|
||||
|
||||
fn print_long(&self, metas: &[Meta]) {
|
||||
let max_user_length = self.detect_user_lenght(&metas);
|
||||
let max_group_length = self.detect_group_lenght(&metas);
|
||||
let (max_size_value_length, max_size_unit_length) = self.detect_size_lenghts(&metas);
|
||||
|
||||
for meta in metas {
|
||||
let mut link_str = String::new();
|
||||
if let Some(ref symlink) = meta.symlink {
|
||||
link_str = symlink.render();
|
||||
}
|
||||
|
||||
println!(
|
||||
"{}{} {} {} {} {}{}",
|
||||
meta.file_type.render(),
|
||||
meta.permissions.render(),
|
||||
meta.owner.render(max_user_length, max_group_length),
|
||||
meta.size
|
||||
.render(max_size_value_length, max_size_unit_length),
|
||||
meta.date.render(),
|
||||
meta.name.render(),
|
||||
link_str,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn list_folder_content(&self, folder: &Path) -> Vec<Meta> {
|
||||
let mut content: Vec<Meta> = Vec::new();
|
||||
pub fn list_folder_content(&self, folder: &Path) -> Option<Batch> {
|
||||
let mut metas: Vec<Meta> = Vec::new();
|
||||
|
||||
let dir = match folder.read_dir() {
|
||||
Ok(dir) => dir,
|
||||
Err(err) => {
|
||||
println!("cannot open directory'{}': {}", folder.display(), err);
|
||||
return content;
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -130,66 +71,14 @@ impl<'a> Core<'a> {
|
|||
if let Ok(entry) = entry {
|
||||
let meta = Meta::from(entry.path().as_path());
|
||||
if !meta.name.is_hidden() || self.options.display_all {
|
||||
content.push(meta);
|
||||
metas.push(meta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
content.sort_unstable_by(sort_by_meta);
|
||||
let mut batch = Batch::from(metas);
|
||||
batch.sort();
|
||||
|
||||
content
|
||||
}
|
||||
|
||||
fn detect_user_lenght(&self, metas: &[Meta]) -> usize {
|
||||
let mut max: usize = 0;
|
||||
|
||||
for meta in metas {
|
||||
let user = meta.owner.render_user();
|
||||
if user.len() > max {
|
||||
max = user.len();
|
||||
}
|
||||
}
|
||||
|
||||
max
|
||||
}
|
||||
|
||||
fn detect_group_lenght(&self, metas: &[Meta]) -> usize {
|
||||
let mut max: usize = 0;
|
||||
|
||||
for meta in metas {
|
||||
let group = meta.owner.render_group();
|
||||
if group.len() > max {
|
||||
max = group.len();
|
||||
}
|
||||
}
|
||||
|
||||
max
|
||||
}
|
||||
|
||||
fn detect_size_lenghts(&self, metas: &[Meta]) -> (usize, usize) {
|
||||
let mut max_value_length: usize = 0;
|
||||
let mut max_unit_size: usize = 0;
|
||||
|
||||
for meta in metas {
|
||||
if meta.size.render_value().len() > max_value_length {
|
||||
max_value_length = meta.size.render_value().len();
|
||||
}
|
||||
|
||||
if meta.size.render_unit().len() > max_unit_size {
|
||||
max_unit_size = meta.size.render_unit().len();
|
||||
}
|
||||
}
|
||||
|
||||
(max_value_length, max_unit_size)
|
||||
}
|
||||
}
|
||||
|
||||
fn sort_by_meta(a: &Meta, b: &Meta) -> Ordering {
|
||||
if a.file_type == FileType::Directory && b.file_type != FileType::Directory {
|
||||
Ordering::Less
|
||||
} else if b.file_type == FileType::Directory && a.file_type != FileType::Directory {
|
||||
Ordering::Greater
|
||||
} else {
|
||||
a.name.cmp(&b.name)
|
||||
Some(batch)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ extern crate terminal_size;
|
|||
extern crate time;
|
||||
extern crate users;
|
||||
|
||||
mod batch;
|
||||
mod color;
|
||||
mod core;
|
||||
mod icon;
|
||||
|
|
Loading…
Reference in a new issue