refactor: adopted idiomatic combinators and updated the rust toolchain

- Updated the nightly rust toolchain channel in rust-toolchain.toml to nightly-2026-07-28.
- Adopted slice chunking and multiple-of helper methods across native and vendor crates.
- Replaced option map adapters and conditional patterns with idiomatic combinators.
This commit is contained in:
can1357
2026-07-28 10:01:56 +02:00
parent 169a1b81c7
commit 34e88b344b
19 changed files with 71 additions and 82 deletions
+1 -1
View File
@@ -200,7 +200,7 @@ fn quote_bare_metavars(pattern: &str) -> String {
} }
/// Byte index of the end of the UTF-8 character starting at `index`. /// Byte index of the end of the UTF-8 character starting at `index`.
fn next_char_boundary(bytes: &[u8], index: usize) -> usize { const fn next_char_boundary(bytes: &[u8], index: usize) -> usize {
let mut end = index + 1; let mut end = index + 1;
while end < bytes.len() && (bytes[end] & 0b1100_0000) == 0b1000_0000 { while end < bytes.len() && (bytes[end] & 0b1100_0000) == 0b1000_0000 {
end += 1; end += 1;
+2 -2
View File
@@ -814,7 +814,7 @@ pub(crate) struct GrepConfig {
/// Check if `bytes[start]` (which must be `b'{'`) begins a valid repetition /// Check if `bytes[start]` (which must be `b'{'`) begins a valid repetition
/// quantifier: `{N}`, `{N,}`, or `{N,M}` where N and M are decimal digits. /// quantifier: `{N}`, `{N,}`, or `{N,M}` where N and M are decimal digits.
/// Returns the byte index of the closing `}` if valid. /// Returns the byte index of the closing `}` if valid.
fn find_valid_repetition(bytes: &[u8], start: usize) -> Option<usize> { const fn find_valid_repetition(bytes: &[u8], start: usize) -> Option<usize> {
let len = bytes.len(); let len = bytes.len();
let mut i = start + 1; let mut i = start + 1;
// Must start with at least one digit. // Must start with at least one digit.
@@ -847,7 +847,7 @@ fn find_valid_repetition(bytes: &[u8], start: usize) -> Option<usize> {
None None
} }
fn find_braced_escape_end(bytes: &[u8], start: usize) -> Option<usize> { const fn find_braced_escape_end(bytes: &[u8], start: usize) -> Option<usize> {
let mut i = start + 1; let mut i = start + 1;
while i < bytes.len() { while i < bytes.len() {
if bytes[i] == b'}' { if bytes[i] == b'}' {
+3 -9
View File
@@ -323,9 +323,7 @@ pub fn matches_kitty_sequence(
&& base == expected_codepoint && base == expected_codepoint
{ {
let cp = parsed.codepoint; let cp = parsed.codepoint;
let is_ascii_letter = u8::try_from(cp) let is_ascii_letter = u8::try_from(cp).is_ok_and(|b| b.is_ascii_alphabetic());
.ok()
.is_some_and(|b| b.is_ascii_alphabetic());
let is_known_symbol = is_symbol_key(cp); let is_known_symbol = is_symbol_key(cp);
if !is_ascii_letter && !is_known_symbol { if !is_ascii_letter && !is_known_symbol {
return true; return true;
@@ -637,9 +635,7 @@ fn matches_key_inner(bytes: &[u8], key_id: &str, kitty_protocol_active: bool) ->
if let Some(base) = parsed_base if let Some(base) = parsed_base
&& base == codepoint && base == codepoint
{ {
let is_ascii_letter = u8::try_from(parsed_codepoint) let is_ascii_letter = u8::try_from(parsed_codepoint).is_ok_and(|b| b.is_ascii_alphabetic());
.ok()
.is_some_and(|b| b.is_ascii_alphabetic());
let is_known_symbol = is_symbol_key(parsed_codepoint); let is_known_symbol = is_symbol_key(parsed_codepoint);
if !is_ascii_letter && !is_known_symbol { if !is_ascii_letter && !is_known_symbol {
return true; return true;
@@ -1389,9 +1385,7 @@ fn format_kitty_key(parsed: &ParsedKittySequence) -> Option<Cow<'static, str>> {
text_codepoint text_codepoint
} else { } else {
let cp = parsed.codepoint; let cp = parsed.codepoint;
let is_ascii_letter = u8::try_from(cp) let is_ascii_letter = u8::try_from(cp).is_ok_and(|b| b.is_ascii_alphabetic());
.ok()
.is_some_and(|b| b.is_ascii_alphabetic());
let is_known_symbol = is_symbol_key(cp); let is_known_symbol = is_symbol_key(cp);
if is_ascii_letter || is_known_symbol { if is_ascii_letter || is_known_symbol {
cp cp
+2 -2
View File
@@ -410,7 +410,7 @@ fn fill_repeat_bands_rgb(pixels: &mut [u8], width: usize, height: usize, grid: &
for copy in 1..grid.repeat { for copy in 1..grid.repeat {
let band_top = (row * grid.repeat + copy) * grid.cell_h; let band_top = (row * grid.repeat + copy) * grid.cell_h;
for y in band_top..(band_top + grid.cell_h).min(height) { for y in band_top..(band_top + grid.cell_h).min(height) {
for px in pixels[y * width * 3..(y + 1) * width * 3].chunks_exact_mut(3) { for px in pixels[y * width * 3..(y + 1) * width * 3].as_chunks_mut::<3>().0 {
px.copy_from_slice(&band); px.copy_from_slice(&band);
} }
} }
@@ -1302,7 +1302,7 @@ fn render_snapcompact_png_sync(
render_bitmap(&text, src_w, src_h, font, &native, black_ink) render_bitmap(&text, src_w, src_h, font, &native, black_ink)
}; };
let mut rgb = vec![0f32; src_w * src_h * 3]; let mut rgb = vec![0f32; src_w * src_h * 3];
for (dst, &idx) in rgb.chunks_exact_mut(3).zip(&indexed) { for (dst, &idx) in rgb.as_chunks_mut::<3>().0.iter_mut().zip(&indexed) {
let [r, g, b] = PALETTE[idx as usize]; let [r, g, b] = PALETTE[idx as usize];
dst[0] = f32::from(r); dst[0] = f32::from(r);
dst[1] = f32::from(g); dst[1] = f32::from(g);
+1 -1
View File
@@ -405,7 +405,7 @@ fn ansi_seq_len_u16(data: &[u16], pos: usize) -> Option<usize> {
} }
#[inline] #[inline]
fn is_sgr_u16(seq: &[u16]) -> bool { const fn is_sgr_u16(seq: &[u16]) -> bool {
seq.len() >= 3 && seq[1] == b'[' as u16 && *seq.last().unwrap() == b'm' as u16 seq.len() >= 3 && seq[1] == b'[' as u16 && *seq.last().unwrap() == b'm' as u16
} }
@@ -745,7 +745,7 @@ mod tests {
// Two separate groups, not merged // Two separate groups, not merged
let unused_pos = out.find("unused_variables").unwrap(); let unused_pos = out.find("unused_variables").unwrap();
let clone_pos = out.find("clippy::redundant_clone").unwrap(); let clone_pos = out.find("clippy::redundant_clone").unwrap();
assert!(unused_pos != clone_pos); assert_ne!(unused_pos, clone_pos);
} }
#[test] #[test]
+2 -2
View File
@@ -315,12 +315,12 @@ fn summarize_golangci_json(line: &str) -> Option<String> {
.get("Pos") .get("Pos")
.and_then(|pos| pos.get("Line")) .and_then(|pos| pos.get("Line"))
.and_then(serde_json::Value::as_u64) .and_then(serde_json::Value::as_u64)
.map_or(0, |value| value); .unwrap_or(0);
let col_no = issue let col_no = issue
.get("Pos") .get("Pos")
.and_then(|pos| pos.get("Column")) .and_then(|pos| pos.get("Column"))
.and_then(serde_json::Value::as_u64) .and_then(serde_json::Value::as_u64)
.map_or(0, |value| value); .unwrap_or(0);
let linter = issue let linter = issue
.get("FromLinter") .get("FromLinter")
.and_then(|v| v.as_str()) .and_then(|v| v.as_str())
+1 -1
View File
@@ -189,7 +189,7 @@ impl CommonCompleteCommandArgs {
actions actions
} }
fn has_completion_spec(&self) -> bool { const fn has_completion_spec(&self) -> bool {
!self.options.is_empty() !self.options.is_empty()
|| !self.actions.is_empty() || !self.actions.is_empty()
|| self.glob_pattern.is_some() || self.glob_pattern.is_some()
+6 -9
View File
@@ -200,15 +200,12 @@ fn expand_history_args(
let mut result = ExecutionResult::success(); let mut result = ExecutionResult::success();
for arg in args { for arg in args {
match expand_history_arg(history, arg) { if let Ok(expanded) = expand_history_arg(history, arg) {
Ok(expanded) => { writeln!(stdout, "{expanded}")?;
writeln!(stdout, "{expanded}")?; } else {
}, writeln!(stderr, "history: {arg}: history expansion failed")?;
Err(()) => { result = ExecutionResult::general_error();
writeln!(stderr, "history: {arg}: history expansion failed")?; }
result = ExecutionResult::general_error();
},
}
} }
Ok(result) Ok(result)
+1 -1
View File
@@ -158,7 +158,7 @@ impl MapFileCommand {
let array_index = self.origin.unwrap_or(0) + i64::try_from(entry_count)?; let array_index = self.origin.unwrap_or(0) + i64::try_from(entry_count)?;
if let Some(callback) = &self.callback if let Some(callback) = &self.callback
&& (entry_count + 1) % callback_group_size == 0 && (entry_count + 1).is_multiple_of(callback_group_size)
{ {
let result = run_callback(callback, array_index, &line_str, context).await?; let result = run_callback(callback, array_index, &line_str, context).await?;
if !result.is_normal_flow() { if !result.is_normal_flow() {
+1 -1
View File
@@ -78,7 +78,7 @@ impl TrapCommand {
signal_type: TrapSignal, signal_type: TrapSignal,
) -> Result<(), brush_core::Error> { ) -> Result<(), brush_core::Error> {
if let Some(handler) = context.shell.traps().get_handler(signal_type) { if let Some(handler) = context.shell.traps().get_handler(signal_type) {
writeln!(context.stdout(), "trap -- '{}' {signal_type}", &handler.command)?; writeln!(context.stdout(), "trap -- '{}' {signal_type}", handler.command)?;
} }
Ok(()) Ok(())
} }
+1 -1
View File
@@ -179,7 +179,7 @@ mod tests {
use super::*; use super::*;
fn parse(mode: &str, current_umask: u32) -> u32 { fn parse(mode: &str, current_umask: u32) -> u32 {
parse_symbolic_umask(mode, current_umask).unwrap() as u32 u32::from(parse_symbolic_umask(mode, current_umask).unwrap())
} }
#[test] #[test]
+1 -1
View File
@@ -1018,7 +1018,7 @@ pub enum ChildSessionAction {
/// `child_stdin_is_terminal` arm before pipeline membership would ever matter. /// `child_stdin_is_terminal` arm before pipeline membership would ever matter.
/// ///
/// Foregrounding remains gated on `new_pg && child_stdin_is_terminal`. /// Foregrounding remains gated on `new_pg && child_stdin_is_terminal`.
pub fn child_session_action( pub const fn child_session_action(
new_pg: bool, new_pg: bool,
child_stdin_is_terminal: bool, child_stdin_is_terminal: bool,
_in_pipeline_group: bool, _in_pipeline_group: bool,
+2 -3
View File
@@ -1286,10 +1286,9 @@ fn try_get_variable_completions(
return None; return None;
} }
(prefix, true) (prefix, true)
} else if let Some(prefix) = token.strip_prefix('$') {
(prefix, false)
} else { } else {
return None; let prefix = token.strip_prefix('$')?;
(prefix, false)
}; };
// If there's a path separator, this is a path like $HOME/foo, not a variable to // If there's a path separator, this is a path like $HOME/foo, not a variable to
+2 -3
View File
@@ -465,7 +465,8 @@ impl<'a> Iterator for Search<'a> {
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
loop { loop {
if let Some(index) = self.next_index { {
let index = self.next_index?;
// Make sure we haven't hit the end of the history. // Make sure we haven't hit the end of the history.
if index >= self.history.items.len() { if index >= self.history.items.len() {
return None; return None;
@@ -494,8 +495,6 @@ impl<'a> Iterator for Search<'a> {
return Some(item); return Some(item);
} }
} }
} else {
return None;
} }
} }
} }
+2 -2
View File
@@ -133,7 +133,7 @@ impl ExecutionParameters {
} }
/// Disables external-command output marking for this execution branch. /// Disables external-command output marking for this execution branch.
pub fn disable_command_output_marking(&mut self) { pub const fn disable_command_output_marking(&mut self) {
self.command_output_disabled = true; self.command_output_disabled = true;
} }
@@ -1181,7 +1181,7 @@ impl Execute for ast::CaseClauseCommand {
// switched on, but that's not it. // switched on, but that's not it.
if shell.options().print_commands_and_arguments { if shell.options().print_commands_and_arguments {
shell shell
.trace_command(params, std::format!("case {} in", &self.value)) .trace_command(params, std::format!("case {} in", self.value))
.await; .await;
} }
+40 -40
View File
@@ -5,8 +5,8 @@ use std::{
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
/// Normalizes shell-facing path aliases before std::fs sees them. /// Normalizes shell-facing path aliases before `std::fs` sees them.
pub fn normalize_shell_path(path: &Path) -> Cow<'_, Path> { pub const fn normalize_shell_path(path: &Path) -> Cow<'_, Path> {
#[cfg(windows)] #[cfg(windows)]
{ {
translate_unix_drive_path(path).map_or(Cow::Borrowed(path), Cow::Owned) translate_unix_drive_path(path).map_or(Cow::Borrowed(path), Cow::Owned)
@@ -18,7 +18,7 @@ pub fn normalize_shell_path(path: &Path) -> Cow<'_, Path> {
} }
/// Returns a Windows drive root for a shell pattern that starts with an MSYS/WSL drive alias. /// Returns a Windows drive root for a shell pattern that starts with an MSYS/WSL drive alias.
pub fn pattern_drive_alias_root( pub const fn pattern_drive_alias_root(
starts_with_forward_slash: bool, starts_with_forward_slash: bool,
first: &str, first: &str,
second: Option<&str>, second: Option<&str>,
@@ -72,7 +72,7 @@ fn drive_root_path(drive: u8) -> PathBuf {
} }
#[cfg(any(windows, test))] #[cfg(any(windows, test))]
fn is_ascii_drive_component(value: &str) -> bool { const fn is_ascii_drive_component(value: &str) -> bool {
value.len() == 1 && value.as_bytes()[0].is_ascii_alphabetic() value.len() == 1 && value.as_bytes()[0].is_ascii_alphabetic()
} }
@@ -122,6 +122,42 @@ const fn is_path_separator(byte: u8) -> bool {
byte == b'/' || byte == b'\\' byte == b'/' || byte == b'\\'
} }
pub use super::platform::fs::*;
/// Extension trait for path-related filesystem operations.
pub trait PathExt {
/// Returns true if the path exists and is readable by the current user.
fn readable(&self) -> bool;
/// Returns true if the path exists and is writable by the current user.
fn writable(&self) -> bool;
/// Returns true if the path exists and is executable by the current user.
///
/// On Windows, this returns true if *either* the path itself is a file with
/// a `PATHEXT` extension *or* appending some `PATHEXT` extension resolves
/// to an existing file. To recover the actual on-disk path in the
/// latter case, use [`resolve_executable`] which takes ownership
/// and avoids copies on platforms where no resolution is needed.
fn executable(&self) -> bool;
/// Returns true if the path exists and is a block device.
fn exists_and_is_block_device(&self) -> bool;
/// Returns true if the path exists and is a character device.
fn exists_and_is_char_device(&self) -> bool;
/// Returns true if the path exists and is a FIFO (named pipe).
fn exists_and_is_fifo(&self) -> bool;
/// Returns true if the path exists and is a socket.
fn exists_and_is_socket(&self) -> bool;
/// Returns true if the path exists and has the setgid bit set.
fn exists_and_is_setgid(&self) -> bool;
/// Returns true if the path exists and has the setuid bit set.
fn exists_and_is_setuid(&self) -> bool;
/// Returns true if the path exists and has the sticky bit set.
fn exists_and_is_sticky_bit(&self) -> bool;
/// Returns the device ID and inode number for the path.
fn get_device_and_inode(&self) -> Result<(u64, u64), crate::error::Error>;
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@@ -183,39 +219,3 @@ mod tests {
assert_eq!(translate_unix_drive_path(Path::new("\\mnt\\d\\logs")).as_deref(), None); assert_eq!(translate_unix_drive_path(Path::new("\\mnt\\d\\logs")).as_deref(), None);
} }
} }
pub use super::platform::fs::*;
/// Extension trait for path-related filesystem operations.
pub trait PathExt {
/// Returns true if the path exists and is readable by the current user.
fn readable(&self) -> bool;
/// Returns true if the path exists and is writable by the current user.
fn writable(&self) -> bool;
/// Returns true if the path exists and is executable by the current user.
///
/// On Windows, this returns true if *either* the path itself is a file with
/// a `PATHEXT` extension *or* appending some `PATHEXT` extension resolves
/// to an existing file. To recover the actual on-disk path in the
/// latter case, use [`resolve_executable`] which takes ownership
/// and avoids copies on platforms where no resolution is needed.
fn executable(&self) -> bool;
/// Returns true if the path exists and is a block device.
fn exists_and_is_block_device(&self) -> bool;
/// Returns true if the path exists and is a character device.
fn exists_and_is_char_device(&self) -> bool;
/// Returns true if the path exists and is a FIFO (named pipe).
fn exists_and_is_fifo(&self) -> bool;
/// Returns true if the path exists and is a socket.
fn exists_and_is_socket(&self) -> bool;
/// Returns true if the path exists and has the setgid bit set.
fn exists_and_is_setgid(&self) -> bool;
/// Returns true if the path exists and has the setuid bit set.
fn exists_and_is_setuid(&self) -> bool;
/// Returns true if the path exists and has the sticky bit set.
fn exists_and_is_sticky_bit(&self) -> bool;
/// Returns the device ID and inode number for the path.
fn get_device_and_inode(&self) -> Result<(u64, u64), crate::error::Error>;
}
+1 -1
View File
@@ -198,7 +198,7 @@ impl Matcher for MultiExecMatcher {
writeln!( writeln!(
&mut stderr(), &mut stderr(),
"Cannot fit a single argument {}: {}", "Cannot fit a single argument {}: {}",
&path_to_file.to_string_lossy(), path_to_file.to_string_lossy(),
e e
) )
.unwrap(); .unwrap();
+1 -1
View File
@@ -1,4 +1,4 @@
[toolchain] [toolchain]
channel = "nightly-2026-04-29" channel = "nightly-2026-07-28"
components = ["rustfmt", "clippy", "rust-analyzer"] components = ["rustfmt", "clippy", "rust-analyzer"]
targets = ["x86_64-unknown-linux-gnu", "x86_64-pc-windows-msvc"] targets = ["x86_64-unknown-linux-gnu", "x86_64-pc-windows-msvc"]