1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-08-03 14:37:45 +00:00

fix: failing test cases & some refactoring

This commit is contained in:
snapdgn 2022-09-11 20:55:37 +05:30
parent 26301d05f6
commit 39e352e2af

View file

@ -9,7 +9,7 @@
extern crate uucore; extern crate uucore;
use clap::builder::ValueParser; use clap::builder::ValueParser;
use uucore::display::Quotable; use uucore::display::Quotable;
use uucore::error::{FromIo, UError, UResult, USimpleError}; use uucore::error::{FromIo, UResult, USimpleError};
use uucore::fs::display_permissions; use uucore::fs::display_permissions;
use uucore::fsext::{ use uucore::fsext::{
pretty_filetype, pretty_fstype, pretty_time, read_fs_list, statfs, BirthTime, FsMeta, pretty_filetype, pretty_fstype, pretty_time, read_fs_list, statfs, BirthTime, FsMeta,
@ -26,7 +26,7 @@ use std::os::unix::prelude::OsStrExt;
use std::path::Path; use std::path::Path;
use std::{cmp, fs, iter}; use std::{cmp, fs, iter};
fn check_bound(slice: &str, bound: usize, beg: usize, end: usize) -> Result<(), Box<dyn UError>> { fn check_bound(slice: &str, bound: usize, beg: usize, end: usize) -> UResult<()> {
if end >= bound { if end >= bound {
return Err(USimpleError::new( return Err(USimpleError::new(
1, 1,
@ -36,61 +36,53 @@ fn check_bound(slice: &str, bound: usize, beg: usize, end: usize) -> Result<(),
Ok(()) Ok(())
} }
fn fill_string(strs: &mut String, c: char, cnt: usize) { fn extend_digits(string: &str, min: usize) -> Cow<'_, str> {
iter::repeat(c) if min > string.len() {
.take(cnt)
.map(|c| strs.push(c))
.all(|_| true);
}
fn extend_digits(strs: &str, min: usize) -> Cow<'_, str> {
if min > strs.len() {
let mut pad = String::with_capacity(min); let mut pad = String::with_capacity(min);
fill_string(&mut pad, '0', min - strs.len()); iter::repeat('0')
pad.push_str(strs); .take(min - string.len())
return pad.into(); .map(|_| pad.push('0'))
.all(|_| true);
pad.push_str(string);
pad.into()
} else { } else {
return strs.into(); string.into()
} }
} }
fn pad_and_print<S: AsRef<str>>( enum Padding {
result: &mut String, Zero,
strs: S, Space,
}
fn pad_and_print(result: &str, left: bool, width: usize, padding: Padding) {
match (left, padding) {
(false, Padding::Zero) => print!("{result:0>width$}"),
(false, Padding::Space) => print!("{result:>width$}"),
(true, Padding::Zero) => print!("{result:0<width$}"),
(true, Padding::Space) => print!("{result:<width$}"),
};
}
fn print_adjusted(
s: &str,
left: bool, left: bool,
need_prefix: Option<bool>,
prefix: Option<&str>,
width: usize, width: usize,
padding: char, padding: Padding,
) { ) {
let strs_ref = strs.as_ref(); let mut field_width = cmp::max(width, s.len());
if strs_ref.len() < width { if let Some(p) = prefix {
if left { if let Some(needprefix) = need_prefix {
result.push_str(strs.as_ref()); if needprefix {
fill_string(result, padding, width - strs_ref.len()); field_width -= p.len();
} else { }
fill_string(result, padding, width - strs_ref.len());
result.push_str(strs.as_ref());
} }
pad_and_print(s, left, field_width, padding);
} else { } else {
result.push_str(strs.as_ref()); pad_and_print(s, left, field_width, padding);
} }
print!("{}", result);
}
macro_rules! print_adjusted {
($str: ident, $left: expr, $width: expr, $padding: expr) => {
let field_width = cmp::max($width, $str.len());
let mut result = String::with_capacity(field_width);
pad_and_print(&mut result, $str, $left, field_width, $padding);
};
($str: ident, $left: expr, $need_prefix: expr, $prefix: expr, $width: expr, $padding: expr) => {
let mut field_width = cmp::max($width, $str.len());
let mut result = String::with_capacity(field_width + $prefix.len());
if $need_prefix {
result.push_str($prefix);
field_width -= $prefix.len();
}
pad_and_print(&mut result, $str, $left, field_width, $padding);
};
} }
static ABOUT: &str = "Display file or file system status."; static ABOUT: &str = "Display file or file system status.";
@ -271,10 +263,10 @@ fn print_it(arg: &str, output_type: &OutputType, flag: u8, width: usize, precisi
} }
let left_align = has!(flag, F_LEFT); let left_align = has!(flag, F_LEFT);
let padding_char = if has!(flag, F_ZERO) && !left_align && precision == -1 { let padding_char: Padding = if has!(flag, F_ZERO) && !left_align && precision == -1 {
'0' Padding::Zero
} else { } else {
' ' Padding::Space
}; };
let has_sign = has!(flag, F_SIGN) || has!(flag, F_SPACE); let has_sign = has!(flag, F_SIGN) || has!(flag, F_SPACE);
@ -301,7 +293,7 @@ fn print_it(arg: &str, output_type: &OutputType, flag: u8, width: usize, precisi
} else { } else {
arg arg
}; };
print_adjusted!(s, left_align, width, ' '); print_adjusted(s, left_align, None, None, width, Padding::Space);
} }
OutputType::Integer => { OutputType::Integer => {
let arg = if has!(flag, F_GROUP) { let arg = if has!(flag, F_GROUP) {
@ -311,7 +303,14 @@ fn print_it(arg: &str, output_type: &OutputType, flag: u8, width: usize, precisi
}; };
let min_digits = cmp::max(precision, arg.len() as i32) as usize; let min_digits = cmp::max(precision, arg.len() as i32) as usize;
let extended: Cow<str> = extend_digits(arg.as_ref(), min_digits); let extended: Cow<str> = extend_digits(arg.as_ref(), min_digits);
print_adjusted!(extended, left_align, has_sign, prefix, width, padding_char); print_adjusted(
extended.as_ref(),
left_align,
Some(has_sign),
Some(prefix),
width,
padding_char,
);
} }
OutputType::Unsigned => { OutputType::Unsigned => {
let arg = if has!(flag, F_GROUP) { let arg = if has!(flag, F_GROUP) {
@ -321,30 +320,37 @@ fn print_it(arg: &str, output_type: &OutputType, flag: u8, width: usize, precisi
}; };
let min_digits = cmp::max(precision, arg.len() as i32) as usize; let min_digits = cmp::max(precision, arg.len() as i32) as usize;
let extended: Cow<str> = extend_digits(arg.as_ref(), min_digits); let extended: Cow<str> = extend_digits(arg.as_ref(), min_digits);
print_adjusted!(extended, left_align, width, padding_char); print_adjusted(
extended.as_ref(),
left_align,
None,
None,
width,
padding_char,
);
} }
OutputType::UnsignedOct => { OutputType::UnsignedOct => {
let min_digits = cmp::max(precision, arg.len() as i32) as usize; let min_digits = cmp::max(precision, arg.len() as i32) as usize;
let extended: Cow<str> = extend_digits(arg, min_digits); let extended: Cow<str> = extend_digits(arg, min_digits);
print_adjusted!( print_adjusted(
extended, extended.as_ref(),
left_align, left_align,
should_alter, Some(should_alter),
prefix, Some(prefix),
width, width,
padding_char padding_char,
); );
} }
OutputType::UnsignedHex => { OutputType::UnsignedHex => {
let min_digits = cmp::max(precision, arg.len() as i32) as usize; let min_digits = cmp::max(precision, arg.len() as i32) as usize;
let extended: Cow<str> = extend_digits(arg, min_digits); let extended: Cow<str> = extend_digits(arg, min_digits);
print_adjusted!( print_adjusted(
extended, extended.as_ref(),
left_align, left_align,
should_alter, Some(should_alter),
prefix, Some(prefix),
width, width,
padding_char padding_char,
); );
} }
_ => unreachable!(), _ => unreachable!(),