mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-08-03 14:37:45 +00:00
fmt: extract determining options to separate function
This commit is contained in:
parent
01c32a5220
commit
d78923e4cc
1 changed files with 95 additions and 99 deletions
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
// spell-checker:ignore (ToDO) PSKIP linebreak ostream parasplit tabwidth xanti xprefix
|
// spell-checker:ignore (ToDO) PSKIP linebreak ostream parasplit tabwidth xanti xprefix
|
||||||
|
|
||||||
use clap::{crate_version, Arg, ArgAction, Command};
|
use clap::{crate_version, Arg, ArgAction, ArgMatches, Command};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{stdin, stdout, Write};
|
use std::io::{stdin, stdout, Write};
|
||||||
|
@ -40,6 +40,9 @@ static OPT_TAB_WIDTH: &str = "tab-width";
|
||||||
|
|
||||||
static ARG_FILES: &str = "files";
|
static ARG_FILES: &str = "files";
|
||||||
|
|
||||||
|
// by default, goal is 93% of width
|
||||||
|
const DEFAULT_GOAL_TO_WIDTH_RATIO: usize = 93;
|
||||||
|
|
||||||
pub type FileOrStdReader = BufReader<Box<dyn Read + 'static>>;
|
pub type FileOrStdReader = BufReader<Box<dyn Read + 'static>>;
|
||||||
pub struct FmtOptions {
|
pub struct FmtOptions {
|
||||||
crown: bool,
|
crown: bool,
|
||||||
|
@ -59,25 +62,97 @@ pub struct FmtOptions {
|
||||||
tabwidth: usize,
|
tabwidth: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for FmtOptions {
|
impl FmtOptions {
|
||||||
fn default() -> Self {
|
fn from_matches(matches: &ArgMatches) -> UResult<Self> {
|
||||||
Self {
|
let mut tagged = matches.get_flag(OPT_TAGGED_PARAGRAPH);
|
||||||
crown: false,
|
let mut crown = matches.get_flag(OPT_CROWN_MARGIN);
|
||||||
tagged: false,
|
|
||||||
mail: false,
|
let mail = matches.get_flag(OPT_PRESERVE_HEADERS);
|
||||||
uniform: false,
|
let uniform = matches.get_flag(OPT_UNIFORM_SPACING);
|
||||||
quick: false,
|
let quick = matches.get_flag(OPT_QUICK);
|
||||||
split_only: false,
|
let split_only = matches.get_flag(OPT_SPLIT_ONLY);
|
||||||
use_prefix: false,
|
|
||||||
prefix: String::new(),
|
if crown {
|
||||||
xprefix: false,
|
tagged = false;
|
||||||
use_anti_prefix: false,
|
|
||||||
anti_prefix: String::new(),
|
|
||||||
xanti_prefix: false,
|
|
||||||
width: 75,
|
|
||||||
goal: 70,
|
|
||||||
tabwidth: 8,
|
|
||||||
}
|
}
|
||||||
|
if split_only {
|
||||||
|
crown = false;
|
||||||
|
tagged = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let xprefix = matches.contains_id(OPT_EXACT_PREFIX);
|
||||||
|
let xanti_prefix = matches.contains_id(OPT_SKIP_PREFIX);
|
||||||
|
|
||||||
|
let mut prefix = String::new();
|
||||||
|
let mut use_prefix = false;
|
||||||
|
if let Some(s) = matches.get_one::<String>(OPT_PREFIX).map(String::from) {
|
||||||
|
prefix = s;
|
||||||
|
use_prefix = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut anti_prefix = String::new();
|
||||||
|
let mut use_anti_prefix = false;
|
||||||
|
if let Some(s) = matches.get_one::<String>(OPT_SKIP_PREFIX).map(String::from) {
|
||||||
|
anti_prefix = s;
|
||||||
|
use_anti_prefix = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut width = 75;
|
||||||
|
let mut goal = 70;
|
||||||
|
if let Some(w) = matches.get_one::<usize>(OPT_WIDTH) {
|
||||||
|
width = *w;
|
||||||
|
if width > MAX_WIDTH {
|
||||||
|
return Err(USimpleError::new(
|
||||||
|
1,
|
||||||
|
format!("invalid width: '{}': Numerical result out of range", width),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
goal = cmp::min(width * DEFAULT_GOAL_TO_WIDTH_RATIO / 100, width - 3);
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(g) = matches.get_one::<usize>(OPT_GOAL) {
|
||||||
|
goal = *g;
|
||||||
|
if !matches.contains_id(OPT_WIDTH) {
|
||||||
|
width = cmp::max(goal * 100 / DEFAULT_GOAL_TO_WIDTH_RATIO, goal + 3);
|
||||||
|
} else if goal > width {
|
||||||
|
return Err(USimpleError::new(1, "GOAL cannot be greater than WIDTH."));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut tabwidth = 8;
|
||||||
|
if let Some(s) = matches.get_one::<String>(OPT_TAB_WIDTH) {
|
||||||
|
tabwidth = match s.parse::<usize>() {
|
||||||
|
Ok(t) => t,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(USimpleError::new(
|
||||||
|
1,
|
||||||
|
format!("Invalid TABWIDTH specification: {}: {}", s.quote(), e),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
if tabwidth < 1 {
|
||||||
|
tabwidth = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
crown,
|
||||||
|
tagged,
|
||||||
|
mail,
|
||||||
|
uniform,
|
||||||
|
quick,
|
||||||
|
split_only,
|
||||||
|
use_prefix,
|
||||||
|
prefix,
|
||||||
|
xprefix,
|
||||||
|
use_anti_prefix,
|
||||||
|
anti_prefix,
|
||||||
|
xanti_prefix,
|
||||||
|
width,
|
||||||
|
goal,
|
||||||
|
tabwidth,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,12 +165,7 @@ impl Default for FmtOptions {
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// A tuple containing a vector of file names and a `FmtOptions` struct.
|
/// A tuple containing a vector of file names and a `FmtOptions` struct.
|
||||||
#[allow(clippy::cognitive_complexity)]
|
|
||||||
#[allow(clippy::field_reassign_with_default)]
|
|
||||||
fn parse_arguments(args: impl uucore::Args) -> UResult<(Vec<String>, FmtOptions)> {
|
fn parse_arguments(args: impl uucore::Args) -> UResult<(Vec<String>, FmtOptions)> {
|
||||||
// by default, goal is 93% of width
|
|
||||||
const DEFAULT_GOAL_TO_WIDTH_RATIO: usize = 93;
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
let mut files: Vec<String> = matches
|
let mut files: Vec<String> = matches
|
||||||
|
@ -103,81 +173,7 @@ fn parse_arguments(args: impl uucore::Args) -> UResult<(Vec<String>, FmtOptions)
|
||||||
.map(|v| v.map(ToString::to_string).collect())
|
.map(|v| v.map(ToString::to_string).collect())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let mut fmt_opts = FmtOptions::default();
|
let fmt_opts = FmtOptions::from_matches(&matches)?;
|
||||||
|
|
||||||
fmt_opts.tagged = matches.get_flag(OPT_TAGGED_PARAGRAPH);
|
|
||||||
if matches.get_flag(OPT_CROWN_MARGIN) {
|
|
||||||
fmt_opts.crown = true;
|
|
||||||
fmt_opts.tagged = false;
|
|
||||||
}
|
|
||||||
fmt_opts.mail = matches.get_flag(OPT_PRESERVE_HEADERS);
|
|
||||||
fmt_opts.uniform = matches.get_flag(OPT_UNIFORM_SPACING);
|
|
||||||
fmt_opts.quick = matches.get_flag(OPT_QUICK);
|
|
||||||
if matches.get_flag(OPT_SPLIT_ONLY) {
|
|
||||||
fmt_opts.split_only = true;
|
|
||||||
fmt_opts.crown = false;
|
|
||||||
fmt_opts.tagged = false;
|
|
||||||
}
|
|
||||||
fmt_opts.xprefix = matches.contains_id(OPT_EXACT_PREFIX);
|
|
||||||
fmt_opts.xanti_prefix = matches.contains_id(OPT_SKIP_PREFIX);
|
|
||||||
|
|
||||||
if let Some(s) = matches.get_one::<String>(OPT_PREFIX).map(String::from) {
|
|
||||||
fmt_opts.prefix = s;
|
|
||||||
fmt_opts.use_prefix = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(s) = matches.get_one::<String>(OPT_SKIP_PREFIX).map(String::from) {
|
|
||||||
fmt_opts.anti_prefix = s;
|
|
||||||
fmt_opts.use_anti_prefix = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(width) = matches.get_one::<usize>(OPT_WIDTH) {
|
|
||||||
fmt_opts.width = *width;
|
|
||||||
if fmt_opts.width > MAX_WIDTH {
|
|
||||||
return Err(USimpleError::new(
|
|
||||||
1,
|
|
||||||
format!(
|
|
||||||
"invalid width: '{}': Numerical result out of range",
|
|
||||||
fmt_opts.width,
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
fmt_opts.goal = cmp::min(
|
|
||||||
fmt_opts.width * DEFAULT_GOAL_TO_WIDTH_RATIO / 100,
|
|
||||||
fmt_opts.width - 3,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(goal) = matches.get_one::<usize>(OPT_GOAL) {
|
|
||||||
fmt_opts.goal = *goal;
|
|
||||||
if !matches.contains_id(OPT_WIDTH) {
|
|
||||||
fmt_opts.width = cmp::max(
|
|
||||||
fmt_opts.goal * 100 / DEFAULT_GOAL_TO_WIDTH_RATIO,
|
|
||||||
fmt_opts.goal + 3,
|
|
||||||
);
|
|
||||||
} else if fmt_opts.goal > fmt_opts.width {
|
|
||||||
return Err(USimpleError::new(1, "GOAL cannot be greater than WIDTH."));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(s) = matches.get_one::<String>(OPT_TAB_WIDTH) {
|
|
||||||
fmt_opts.tabwidth = match s.parse::<usize>() {
|
|
||||||
Ok(t) => t,
|
|
||||||
Err(e) => {
|
|
||||||
return Err(USimpleError::new(
|
|
||||||
1,
|
|
||||||
format!("Invalid TABWIDTH specification: {}: {}", s.quote(), e),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
if fmt_opts.tabwidth < 1 {
|
|
||||||
fmt_opts.tabwidth = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// immutable now
|
|
||||||
let fmt_opts = fmt_opts;
|
|
||||||
|
|
||||||
if files.is_empty() {
|
if files.is_empty() {
|
||||||
files.push("-".to_owned());
|
files.push("-".to_owned());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue