1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 03:27:44 +00:00

Merge pull request #7702 from nyurik/iters

feat: optimize iter matching
This commit is contained in:
Yuri Astrakhan 2025-04-15 13:54:58 -04:00 committed by GitHub
parent a37c4a6dc6
commit 8a5a2eed2a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 28 additions and 34 deletions

View file

@ -53,22 +53,20 @@ struct Options {
///
/// The `spec` must be of the form `[USER][:[GROUP]]`, otherwise an
/// error is returned.
fn parse_userspec(spec: &str) -> UResult<UserSpec> {
match &spec.splitn(2, ':').collect::<Vec<&str>>()[..] {
fn parse_userspec(spec: &str) -> UserSpec {
match spec.split_once(':') {
// ""
[""] => Ok(UserSpec::NeitherGroupNorUser),
None if spec.is_empty() => UserSpec::NeitherGroupNorUser,
// "usr"
[usr] => Ok(UserSpec::UserOnly(usr.to_string())),
None => UserSpec::UserOnly(spec.to_string()),
// ":"
["", ""] => Ok(UserSpec::NeitherGroupNorUser),
Some(("", "")) => UserSpec::NeitherGroupNorUser,
// ":grp"
["", grp] => Ok(UserSpec::GroupOnly(grp.to_string())),
Some(("", grp)) => UserSpec::GroupOnly(grp.to_string()),
// "usr:"
[usr, ""] => Ok(UserSpec::UserOnly(usr.to_string())),
Some((usr, "")) => UserSpec::UserOnly(usr.to_string()),
// "usr:grp"
[usr, grp] => Ok(UserSpec::UserAndGroup(usr.to_string(), grp.to_string())),
// everything else
_ => Err(ChrootError::InvalidUserspec(spec.to_string()).into()),
Some((usr, grp)) => UserSpec::UserAndGroup(usr.to_string(), grp.to_string()),
}
}
@ -144,10 +142,9 @@ impl Options {
}
};
let skip_chdir = matches.get_flag(options::SKIP_CHDIR);
let userspec = match matches.get_one::<String>(options::USERSPEC) {
None => None,
Some(s) => Some(parse_userspec(s)?),
};
let userspec = matches
.get_one::<String>(options::USERSPEC)
.map(|s| parse_userspec(s));
Ok(Self {
newroot,
skip_chdir,

View file

@ -34,10 +34,6 @@ pub enum ChrootError {
#[error("invalid group list: {list}", list = .0.quote())]
InvalidGroupList(String),
/// The given user and group specification was invalid.
#[error("invalid userspec: {spec}", spec = .0.quote())]
InvalidUserspec(String),
/// The new root directory was not given.
#[error(
"Missing operand: NEWROOT\nTry '{0} --help' for more information.",

View file

@ -3,7 +3,7 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
// spell-checker:ignore (ToDO) NPROCESSORS nprocs numstr threadstr sysconf
// spell-checker:ignore (ToDO) NPROCESSORS nprocs numstr sysconf
use clap::{Arg, ArgAction, Command};
use std::{env, thread};
@ -47,7 +47,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
// Uses the OpenMP variable to limit the number of threads
// If the parsing fails, returns the max size (so, no impact)
// If OMP_THREAD_LIMIT=0, rejects the value
Ok(threadstr) => match threadstr.parse() {
Ok(threads) => match threads.parse() {
Ok(0) | Err(_) => usize::MAX,
Ok(n) => n,
},
@ -63,14 +63,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
match env::var("OMP_NUM_THREADS") {
// Uses the OpenMP variable to force the number of threads
// If the parsing fails, returns the number of CPU
Ok(threadstr) => {
Ok(threads) => {
// In some cases, OMP_NUM_THREADS can be "x,y,z"
// In this case, only take the first one (like GNU)
// If OMP_NUM_THREADS=0, rejects the value
let thread: Vec<&str> = threadstr.split_terminator(',').collect();
match &thread[..] {
[] => available_parallelism(),
[s, ..] => match s.parse() {
match threads.split_terminator(',').next() {
None => available_parallelism(),
Some(s) => match s.parse() {
Ok(0) | Err(_) => available_parallelism(),
Ok(n) => n,
},

View file

@ -108,7 +108,7 @@ impl NumberType {
/// # Errors
///
/// If the string is not one of the valid number types,
/// if `K` is not a nonnegative integer,
/// if `K` is not a non-negative integer,
/// or if `K` is 0,
/// or if `N` is not a positive integer,
/// or if `K` is greater than `N`
@ -117,9 +117,9 @@ impl NumberType {
fn is_invalid_chunk(chunk_number: u64, num_chunks: u64) -> bool {
chunk_number > num_chunks || chunk_number == 0
}
let parts: Vec<&str> = s.split('/').collect();
match &parts[..] {
[n_str] => {
let mut parts = s.splitn(4, '/');
match (parts.next(), parts.next(), parts.next(), parts.next()) {
(Some(n_str), None, None, None) => {
let num_chunks = parse_size_u64(n_str)
.map_err(|_| NumberTypeError::NumberOfChunks(n_str.to_string()))?;
if num_chunks > 0 {
@ -128,7 +128,9 @@ impl NumberType {
Err(NumberTypeError::NumberOfChunks(s.to_string()))
}
}
[k_str, n_str] if !k_str.starts_with('l') && !k_str.starts_with('r') => {
(Some(k_str), Some(n_str), None, None)
if !k_str.starts_with('l') && !k_str.starts_with('r') =>
{
let num_chunks = parse_size_u64(n_str)
.map_err(|_| NumberTypeError::NumberOfChunks(n_str.to_string()))?;
let chunk_number = parse_size_u64(k_str)
@ -138,12 +140,12 @@ impl NumberType {
}
Ok(Self::KthBytes(chunk_number, num_chunks))
}
["l", n_str] => {
(Some("l"), Some(n_str), None, None) => {
let num_chunks = parse_size_u64(n_str)
.map_err(|_| NumberTypeError::NumberOfChunks(n_str.to_string()))?;
Ok(Self::Lines(num_chunks))
}
["l", k_str, n_str] => {
(Some("l"), Some(k_str), Some(n_str), None) => {
let num_chunks = parse_size_u64(n_str)
.map_err(|_| NumberTypeError::NumberOfChunks(n_str.to_string()))?;
let chunk_number = parse_size_u64(k_str)
@ -153,12 +155,12 @@ impl NumberType {
}
Ok(Self::KthLines(chunk_number, num_chunks))
}
["r", n_str] => {
(Some("r"), Some(n_str), None, None) => {
let num_chunks = parse_size_u64(n_str)
.map_err(|_| NumberTypeError::NumberOfChunks(n_str.to_string()))?;
Ok(Self::RoundRobin(num_chunks))
}
["r", k_str, n_str] => {
(Some("r"), Some(k_str), Some(n_str), None) => {
let num_chunks = parse_size_u64(n_str)
.map_err(|_| NumberTypeError::NumberOfChunks(n_str.to_string()))?;
let chunk_number = parse_size_u64(k_str)