mirror of
https://github.com/lsd-rs/lsd
synced 2024-12-14 14:12:31 +00:00
refactored 'Size' to only contain bytes. The unit is calculated only when needed. Added a new --size option 'bytes' to display the filesize in bytes (without unit) this is the default of ls
This commit is contained in:
parent
cb1de67261
commit
3facd44840
4 changed files with 85 additions and 98 deletions
|
@ -118,6 +118,7 @@ pub fn build() -> App<'static, 'static> {
|
||||||
.long("size")
|
.long("size")
|
||||||
.possible_value("default")
|
.possible_value("default")
|
||||||
.possible_value("short")
|
.possible_value("short")
|
||||||
|
.possible_value("bytes")
|
||||||
.default_value("default")
|
.default_value("default")
|
||||||
.multiple(true)
|
.multiple(true)
|
||||||
.number_of_values(1)
|
.number_of_values(1)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::color::Colors;
|
use crate::color::Colors;
|
||||||
use crate::flags::{Block, Display, Flags, Layout};
|
use crate::flags::{Block, Display, Flags, Layout};
|
||||||
use crate::icon::Icons;
|
use crate::icon::Icons;
|
||||||
use crate::meta::{FileType, Meta};
|
use crate::meta::{FileType, Meta, Size};
|
||||||
use ansi_term::{ANSIString, ANSIStrings};
|
use ansi_term::{ANSIString, ANSIStrings};
|
||||||
use term_grid::{Cell, Direction, Filling, Grid, GridOptions};
|
use term_grid::{Cell, Direction, Filling, Grid, GridOptions};
|
||||||
use terminal_size::terminal_size;
|
use terminal_size::terminal_size;
|
||||||
|
@ -400,12 +400,16 @@ fn detect_size_lengths(metas: &[Meta], flags: &Flags) -> (usize, usize) {
|
||||||
let mut max_unit_size: usize = 0;
|
let mut max_unit_size: usize = 0;
|
||||||
|
|
||||||
for meta in metas {
|
for meta in metas {
|
||||||
if meta.size.render_value().len() > max_value_length {
|
let unit = meta.size.get_unit(flags);
|
||||||
max_value_length = meta.size.render_value().len();
|
let value_len = meta.size.render_value(&unit).len();
|
||||||
|
let unit_len = Size::render_unit(&unit, &flags).len();
|
||||||
|
|
||||||
|
if value_len > max_value_length {
|
||||||
|
max_value_length = value_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if meta.size.render_unit(&flags).len() > max_unit_size {
|
if unit_len > max_unit_size {
|
||||||
max_unit_size = meta.size.render_unit(&flags).len();
|
max_unit_size = unit_len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -195,6 +195,7 @@ pub enum Display {
|
||||||
pub enum SizeFlag {
|
pub enum SizeFlag {
|
||||||
Default,
|
Default,
|
||||||
Short,
|
Short,
|
||||||
|
Bytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a str> for SizeFlag {
|
impl<'a> From<&'a str> for SizeFlag {
|
||||||
|
@ -202,6 +203,7 @@ impl<'a> From<&'a str> for SizeFlag {
|
||||||
match size {
|
match size {
|
||||||
"default" => SizeFlag::Default,
|
"default" => SizeFlag::Default,
|
||||||
"short" => SizeFlag::Short,
|
"short" => SizeFlag::Short,
|
||||||
|
"bytes" => SizeFlag::Bytes,
|
||||||
_ => panic!("invalid \"size\" flag: {}", size),
|
_ => panic!("invalid \"size\" flag: {}", size),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
166
src/meta/size.rs
166
src/meta/size.rs
|
@ -14,15 +14,13 @@ pub enum Unit {
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct Size {
|
pub struct Size {
|
||||||
value: u64,
|
|
||||||
unit: Unit,
|
|
||||||
bytes: u64,
|
bytes: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a Metadata> for Size {
|
impl<'a> From<&'a Metadata> for Size {
|
||||||
fn from(meta: &Metadata) -> Self {
|
fn from(meta: &Metadata) -> Self {
|
||||||
let len = meta.len();
|
let len = meta.len();
|
||||||
Self::from_bytes(len)
|
Self { bytes: len }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,37 +28,19 @@ impl Size {
|
||||||
pub fn get_bytes(&self) -> u64 {
|
pub fn get_bytes(&self) -> u64 {
|
||||||
self.bytes
|
self.bytes
|
||||||
}
|
}
|
||||||
fn from_bytes(len: u64) -> Self {
|
|
||||||
if len < 1024 {
|
pub fn get_unit(&self, flags: &Flags) -> Unit
|
||||||
Self {
|
{
|
||||||
value: len * 1024,
|
if self.bytes < 1024 || flags.size == SizeFlag::Bytes {
|
||||||
unit: Unit::Byte,
|
Unit::Byte
|
||||||
bytes: len,
|
} else if self.bytes < 1024 * 1024 {
|
||||||
}
|
Unit::Kilo
|
||||||
} else if len < 1024 * 1024 {
|
} else if self.bytes < 1024 * 1024 * 1024 {
|
||||||
Self {
|
Unit::Mega
|
||||||
value: len,
|
} else if self.bytes < 1024 * 1024 * 1024 * 1024 {
|
||||||
unit: Unit::Kilo,
|
Unit::Giga
|
||||||
bytes: len,
|
|
||||||
}
|
|
||||||
} else if len < 1024 * 1024 * 1024 {
|
|
||||||
Self {
|
|
||||||
value: len / 1024,
|
|
||||||
unit: Unit::Mega,
|
|
||||||
bytes: len,
|
|
||||||
}
|
|
||||||
} else if len < 1024 * 1024 * 1024 * 1024 {
|
|
||||||
Self {
|
|
||||||
value: len / (1024 * 1024),
|
|
||||||
unit: Unit::Giga,
|
|
||||||
bytes: len,
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Self {
|
Unit::Tera
|
||||||
value: len / (1024 * 1024 * 1024),
|
|
||||||
unit: Unit::Tera,
|
|
||||||
bytes: len,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,64 +53,54 @@ impl Size {
|
||||||
) -> ColoredString {
|
) -> ColoredString {
|
||||||
let mut content = String::with_capacity(value_alignment + unit_alignment + 1);
|
let mut content = String::with_capacity(value_alignment + unit_alignment + 1);
|
||||||
|
|
||||||
let value = self.render_value();
|
let unit = self.get_unit(flags);
|
||||||
let unit = self.render_unit(&flags);
|
|
||||||
|
|
||||||
for _ in 0..(value_alignment - value.len()) {
|
let value_str = self.render_value(&unit);
|
||||||
|
let unit_str = Size::render_unit(&unit, &flags);
|
||||||
|
|
||||||
|
for _ in 0..(value_alignment - value_str.len()) {
|
||||||
content.push(' ');
|
content.push(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
content += &self.render_value();
|
content += &self.render_value(&unit);
|
||||||
if flags.size != SizeFlag::Short {
|
if flags.size == SizeFlag::Default {
|
||||||
content.push(' ');
|
content.push(' ');
|
||||||
}
|
}
|
||||||
content += &self.render_unit(&flags);
|
content += &Size::render_unit(&unit, &flags);
|
||||||
|
|
||||||
for _ in 0..(unit_alignment - unit.len()) {
|
for _ in 0..(unit_alignment - unit_str.len()) {
|
||||||
content.push(' ');
|
content.push(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
self.paint(colors, content)
|
self.paint(&unit, colors, content)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint(&self, colors: &Colors, content: String) -> ColoredString {
|
fn paint(&self, unit: &Unit, colors: &Colors, content: String) -> ColoredString {
|
||||||
if self.unit == Unit::None {
|
if unit == &Unit::None {
|
||||||
colors.colorize(content, &Elem::NonFile)
|
colors.colorize(content, &Elem::NonFile)
|
||||||
} else if self.unit == Unit::Byte || self.unit == Unit::Kilo {
|
} else if unit == &Unit::Byte || unit == &Unit::Kilo {
|
||||||
colors.colorize(content, &Elem::FileSmall)
|
colors.colorize(content, &Elem::FileSmall)
|
||||||
} else if self.unit == Unit::Mega {
|
} else if unit == &Unit::Mega {
|
||||||
colors.colorize(content, &Elem::FileMedium)
|
colors.colorize(content, &Elem::FileMedium)
|
||||||
} else {
|
} else {
|
||||||
colors.colorize(content, &Elem::FileLarge)
|
colors.colorize(content, &Elem::FileLarge)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_value(&self) -> String {
|
pub fn render_value(&self, unit: &Unit) -> String {
|
||||||
let size_str = match self.unit {
|
match unit {
|
||||||
Unit::None => "".to_string(),
|
Unit::None => "".to_string(),
|
||||||
_ => (self.value as f64 / 1024.0).to_string(),
|
Unit::Byte => self.bytes.to_string(),
|
||||||
};
|
Unit::Kilo => ((( self.bytes as f64 ) / 1024.0 * 10.0).round() / 10.0).to_string(),
|
||||||
|
Unit::Mega => ((( self.bytes as f64 ) / (1024.0 * 1024.0) * 10.0).round() / 10.0).to_string(),
|
||||||
// Check if there is a fraction.
|
Unit::Giga => ((( self.bytes as f64 ) / (1024.0 * 1024.0 * 1024.0) * 10.0).round() / 10.0).to_string(),
|
||||||
if let Some(fraction_idx) = size_str.find('.') {
|
Unit::Tera => ((( self.bytes as f64 ) / (1024.0 * 1024.0 * 1024.0 * 1024.0) * 10.0).round() / 10.0).to_string(),
|
||||||
// If the fraction start with 0 (like 32.01), the result is rounded
|
|
||||||
// by removing the fraction.
|
|
||||||
if size_str.chars().nth(fraction_idx + 1) == Some('0') {
|
|
||||||
let (res, _) = size_str.split_at(fraction_idx); // Split before the fraction
|
|
||||||
res.to_string()
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
let (res, _) = size_str.split_at(fraction_idx + 2); // Split after the '.' and the first fraction digit.
|
|
||||||
res.to_string()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
size_str
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_unit(&self, flags: &Flags) -> String {
|
pub fn render_unit(unit: &Unit, flags: &Flags) -> String {
|
||||||
match flags.size {
|
match flags.size {
|
||||||
SizeFlag::Default => match self.unit {
|
SizeFlag::Default => match unit {
|
||||||
Unit::None => String::from("-"),
|
Unit::None => String::from("-"),
|
||||||
Unit::Byte => String::from("B"),
|
Unit::Byte => String::from("B"),
|
||||||
Unit::Kilo => String::from("KB"),
|
Unit::Kilo => String::from("KB"),
|
||||||
|
@ -138,7 +108,7 @@ impl Size {
|
||||||
Unit::Giga => String::from("GB"),
|
Unit::Giga => String::from("GB"),
|
||||||
Unit::Tera => String::from("TB"),
|
Unit::Tera => String::from("TB"),
|
||||||
},
|
},
|
||||||
SizeFlag::Short => match self.unit {
|
SizeFlag::Short => match unit {
|
||||||
Unit::None => String::from("-"),
|
Unit::None => String::from("-"),
|
||||||
Unit::Byte => String::from("B"),
|
Unit::Byte => String::from("B"),
|
||||||
Unit::Kilo => String::from("K"),
|
Unit::Kilo => String::from("K"),
|
||||||
|
@ -146,6 +116,7 @@ impl Size {
|
||||||
Unit::Giga => String::from("G"),
|
Unit::Giga => String::from("G"),
|
||||||
Unit::Tera => String::from("T"),
|
Unit::Tera => String::from("T"),
|
||||||
},
|
},
|
||||||
|
SizeFlag::Bytes => String::from("")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,75 +128,84 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn render_byte() {
|
fn render_byte() {
|
||||||
let size = Size::from_bytes(42); // == 42 bytes
|
let size = Size { bytes: 42 }; // == 42 bytes
|
||||||
let mut flags = Flags::default();
|
let mut flags = Flags::default();
|
||||||
|
let unit = size.get_unit(&flags);
|
||||||
|
|
||||||
assert_eq!(size.render_value().as_str(), "42");
|
assert_eq!(size.render_value(&unit).as_str(), "42");
|
||||||
|
|
||||||
assert_eq!(size.render_unit(&flags).as_str(), "B");
|
assert_eq!(Size::render_unit(&unit, &flags).as_str(), "B");
|
||||||
flags.size = SizeFlag::Short;
|
flags.size = SizeFlag::Short;
|
||||||
assert_eq!(size.render_unit(&flags).as_str(), "B");
|
assert_eq!(Size::render_unit(&unit, &flags).as_str(), "B");
|
||||||
|
flags.size = SizeFlag::Bytes;
|
||||||
|
assert_eq!(Size::render_unit(&unit, &flags).as_str(), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn render_kilobyte() {
|
fn render_kilobyte() {
|
||||||
let size = Size::from_bytes(42 * 1024); // 42 kilobytes
|
let size = Size { bytes: 42 * 1024 }; // 42 kilobytes
|
||||||
let mut flags = Flags::default();
|
let mut flags = Flags::default();
|
||||||
|
let unit = size.get_unit(&flags);
|
||||||
|
|
||||||
assert_eq!(size.render_value().as_str(), "42");
|
assert_eq!(size.render_value(&unit).as_str(), "42");
|
||||||
assert_eq!(size.render_unit(&flags).as_str(), "KB");
|
assert_eq!(Size::render_unit(&unit, &flags).as_str(), "KB");
|
||||||
flags.size = SizeFlag::Short;
|
flags.size = SizeFlag::Short;
|
||||||
assert_eq!(size.render_unit(&flags).as_str(), "K");
|
assert_eq!(Size::render_unit(&unit, &flags).as_str(), "K");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn render_megabyte() {
|
fn render_megabyte() {
|
||||||
let size = Size::from_bytes(42 * 1024 * 1024); // 42 megabytes
|
let size = Size { bytes: 42 * 1024 * 1024 }; // 42 megabytes
|
||||||
let mut flags = Flags::default();
|
let mut flags = Flags::default();
|
||||||
|
let unit = size.get_unit(&flags);
|
||||||
|
|
||||||
assert_eq!(size.render_value().as_str(), "42");
|
assert_eq!(size.render_value(&unit).as_str(), "42");
|
||||||
assert_eq!(size.render_unit(&flags).as_str(), "MB");
|
assert_eq!(Size::render_unit(&unit, &flags).as_str(), "MB");
|
||||||
flags.size = SizeFlag::Short;
|
flags.size = SizeFlag::Short;
|
||||||
assert_eq!(size.render_unit(&flags).as_str(), "M");
|
assert_eq!(Size::render_unit(&unit, &flags).as_str(), "M");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn render_gigabyte() {
|
fn render_gigabyte() {
|
||||||
let size = Size::from_bytes(42 * 1024 * 1024 * 1024); // 42 gigabytes
|
let size = Size { bytes: 42 * 1024 * 1024 * 1024 }; // 42 gigabytes
|
||||||
let mut flags = Flags::default();
|
let mut flags = Flags::default();
|
||||||
|
let unit = size.get_unit(&flags);
|
||||||
|
|
||||||
assert_eq!(size.render_value().as_str(), "42");
|
assert_eq!(size.render_value(&unit).as_str(), "42");
|
||||||
assert_eq!(size.render_unit(&flags).as_str(), "GB");
|
assert_eq!(Size::render_unit(&unit, &flags).as_str(), "GB");
|
||||||
flags.size = SizeFlag::Short;
|
flags.size = SizeFlag::Short;
|
||||||
assert_eq!(size.render_unit(&flags).as_str(), "G");
|
assert_eq!(Size::render_unit(&unit, &flags).as_str(), "G");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn render_terabyte() {
|
fn render_terabyte() {
|
||||||
let size = Size::from_bytes(42 * 1024 * 1024 * 1024 * 1024); // 42 terabytes
|
let size = Size { bytes: 42 * 1024 * 1024 * 1024 * 1024 }; // 42 terabytes
|
||||||
let mut flags = Flags::default();
|
let mut flags = Flags::default();
|
||||||
|
let unit = size.get_unit(&flags);
|
||||||
|
|
||||||
assert_eq!(size.render_value().as_str(), "42");
|
assert_eq!(size.render_value(&unit).as_str(), "42");
|
||||||
assert_eq!(size.render_unit(&flags).as_str(), "TB");
|
assert_eq!(Size::render_unit(&unit, &flags).as_str(), "TB");
|
||||||
flags.size = SizeFlag::Short;
|
flags.size = SizeFlag::Short;
|
||||||
assert_eq!(size.render_unit(&flags).as_str(), "T");
|
assert_eq!(Size::render_unit(&unit, &flags).as_str(), "T");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn render_with_a_fraction() {
|
fn render_with_a_fraction() {
|
||||||
let size = Size::from_bytes(42 * 1024 + 103); // 42.1 kilobytes
|
let size = Size { bytes: 42 * 1024 + 103 }; // 42.1 kilobytes
|
||||||
let flags = Flags::default();
|
let flags = Flags::default();
|
||||||
|
let unit = size.get_unit(&flags);
|
||||||
|
|
||||||
assert_eq!(size.render_value().as_str(), "42.1");
|
assert_eq!(size.render_value(&unit).as_str(), "42.1");
|
||||||
assert_eq!(size.render_unit(&flags).as_str(), "KB");
|
assert_eq!(Size::render_unit(&unit, &flags).as_str(), "KB");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn render_with_a_truncated_fraction() {
|
fn render_with_a_truncated_fraction() {
|
||||||
let size = Size::from_bytes(42 * 1024 + 1); // 42.001 kilobytes == 42 kilobytes
|
let size = Size { bytes: 42 * 1024 + 1 }; // 42.001 kilobytes == 42 kilobytes
|
||||||
let flags = Flags::default();
|
let flags = Flags::default();
|
||||||
|
let unit = size.get_unit(&flags);
|
||||||
|
|
||||||
assert_eq!(size.render_value().as_str(), "42");
|
assert_eq!(size.render_value(&unit).as_str(), "42");
|
||||||
assert_eq!(size.render_unit(&flags).as_str(), "KB");
|
assert_eq!(Size::render_unit(&unit, &flags).as_str(), "KB");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue