1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-08-05 15:37:47 +00:00

refactor: declarative macros to rust

This commit is contained in:
snapdgn 2022-09-11 15:36:18 +05:30
parent e40f175bb6
commit 26301d05f6
2 changed files with 57 additions and 53 deletions

2
Cargo.lock generated
View file

@ -2624,7 +2624,7 @@ dependencies = [
"itertools", "itertools",
"quick-error", "quick-error",
"regex", "regex",
"time 0.3.14", "time",
"uucore", "uucore",
] ]

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, UResult, USimpleError}; use uucore::error::{FromIo, UError, 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,57 +26,61 @@ use std::os::unix::prelude::OsStrExt;
use std::path::Path; use std::path::Path;
use std::{cmp, fs, iter}; use std::{cmp, fs, iter};
macro_rules! check_bound { fn check_bound(slice: &str, bound: usize, beg: usize, end: usize) -> Result<(), Box<dyn UError>> {
($str: ident, $bound:expr, $beg: expr, $end: expr) => { if end >= bound {
if $end >= $bound { return Err(USimpleError::new(
return Err(USimpleError::new( 1,
1, format!("{}: invalid directive", slice[beg..end].quote()),
format!("{}: invalid directive", $str[$beg..$end].quote()), ));
)); }
} Ok(())
};
} }
macro_rules! fill_string {
($str: ident, $c: expr, $cnt: expr) => { fn fill_string(strs: &mut String, c: char, cnt: usize) {
iter::repeat($c) iter::repeat(c)
.take($cnt) .take(cnt)
.map(|c| $str.push(c)) .map(|c| strs.push(c))
.all(|_| true) .all(|_| true);
};
} }
macro_rules! extend_digits {
($str: expr, $min: expr) => { fn extend_digits(strs: &str, min: usize) -> Cow<'_, str> {
if $min > $str.len() { if min > strs.len() {
let mut pad = String::with_capacity($min); let mut pad = String::with_capacity(min);
fill_string!(pad, '0', $min - $str.len()); fill_string(&mut pad, '0', min - strs.len());
pad.push_str($str); pad.push_str(strs);
pad.into() return pad.into();
} else {
return strs.into();
}
}
fn pad_and_print<S: AsRef<str>>(
result: &mut String,
strs: S,
left: bool,
width: usize,
padding: char,
) {
let strs_ref = strs.as_ref();
if strs_ref.len() < width {
if left {
result.push_str(strs.as_ref());
fill_string(result, padding, width - strs_ref.len());
} else { } else {
$str.into() fill_string(result, padding, width - strs_ref.len());
result.push_str(strs.as_ref());
} }
}; } else {
} result.push_str(strs.as_ref());
macro_rules! pad_and_print { }
($result: ident, $str: ident, $left: expr, $width: expr, $padding: expr) => { print!("{}", result);
if $str.len() < $width {
if $left {
$result.push_str($str.as_ref());
fill_string!($result, $padding, $width - $str.len());
} else {
fill_string!($result, $padding, $width - $str.len());
$result.push_str($str.as_ref());
}
} else {
$result.push_str($str.as_ref());
}
print!("{}", $result);
};
} }
macro_rules! print_adjusted { macro_rules! print_adjusted {
($str: ident, $left: expr, $width: expr, $padding: expr) => { ($str: ident, $left: expr, $width: expr, $padding: expr) => {
let field_width = cmp::max($width, $str.len()); let field_width = cmp::max($width, $str.len());
let mut result = String::with_capacity(field_width); let mut result = String::with_capacity(field_width);
pad_and_print!(result, $str, $left, field_width, $padding); pad_and_print(&mut result, $str, $left, field_width, $padding);
}; };
($str: ident, $left: expr, $need_prefix: expr, $prefix: expr, $width: expr, $padding: expr) => { ($str: ident, $left: expr, $need_prefix: expr, $prefix: expr, $width: expr, $padding: expr) => {
let mut field_width = cmp::max($width, $str.len()); let mut field_width = cmp::max($width, $str.len());
@ -85,7 +89,7 @@ macro_rules! print_adjusted {
result.push_str($prefix); result.push_str($prefix);
field_width -= $prefix.len(); field_width -= $prefix.len();
} }
pad_and_print!(result, $str, $left, field_width, $padding); pad_and_print(&mut result, $str, $left, field_width, $padding);
}; };
} }
@ -306,7 +310,7 @@ fn print_it(arg: &str, output_type: &OutputType, flag: u8, width: usize, precisi
Cow::Borrowed(arg) Cow::Borrowed(arg)
}; };
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, left_align, has_sign, prefix, width, padding_char);
} }
OutputType::Unsigned => { OutputType::Unsigned => {
@ -316,12 +320,12 @@ fn print_it(arg: &str, output_type: &OutputType, flag: u8, width: usize, precisi
Cow::Borrowed(arg) Cow::Borrowed(arg)
}; };
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, left_align, 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,
left_align, left_align,
@ -333,7 +337,7 @@ fn print_it(arg: &str, output_type: &OutputType, flag: u8, width: usize, precisi
} }
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,
left_align, left_align,
@ -384,7 +388,7 @@ impl Stater {
} }
i += 1; i += 1;
} }
check_bound!(format_str, bound, old, i); check_bound(format_str, bound, old, i)?;
let mut width = 0_usize; let mut width = 0_usize;
let mut precision = -1_i32; let mut precision = -1_i32;
@ -394,11 +398,11 @@ impl Stater {
width = field_width; width = field_width;
j += offset; j += offset;
} }
check_bound!(format_str, bound, old, j); check_bound(format_str, bound, old, j)?;
if chars[j] == '.' { if chars[j] == '.' {
j += 1; j += 1;
check_bound!(format_str, bound, old, j); check_bound(format_str, bound, old, j)?;
match format_str[j..].scan_num::<i32>() { match format_str[j..].scan_num::<i32>() {
Some((value, offset)) => { Some((value, offset)) => {
@ -409,7 +413,7 @@ impl Stater {
} }
None => precision = 0, None => precision = 0,
} }
check_bound!(format_str, bound, old, j); check_bound(format_str, bound, old, j)?;
} }
i = j; i = j;