From 6d721e5d1efefb7ee18ab7694687e44145ee8885 Mon Sep 17 00:00:00 2001 From: mattsu Date: Fri, 14 Nov 2025 20:30:56 +0900 Subject: [PATCH 01/21] feat(fold): add column counting for character width mode in process_ascii_line Implement logic to increment column count in WidthMode::Characters, emitting output when width is reached. This ensures accurate line folding for multi-byte characters, enhancing Unicode support. --- src/uu/fold/src/fold.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index f14ed3cf071..c13ac93f399 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -368,6 +368,13 @@ fn process_ascii_line(line: &[u8], ctx: &mut FoldContext<'_, W>) -> UR } else if !ctx.spaces { *ctx.last_space = None; } + + if ctx.mode == WidthMode::Characters { + *ctx.col_count = ctx.col_count.saturating_add(1); + if *ctx.col_count >= ctx.width { + emit_output(ctx)?; + } + } idx += 1; } _ => { From b21cf3549d2791703f96ac032ef1e42196e524d8 Mon Sep 17 00:00:00 2001 From: mattsu Date: Fri, 14 Nov 2025 23:18:53 +0900 Subject: [PATCH 02/21] fix fold: emit output early when column count reaches width limit - Added conditional check in fold_file function to call emit_output when col_count >= width - Ensures lines are properly wrapped based on byte or character width before final output flush - Improves handling of incomplete lines that need early breaking to respect the specified width --- src/uu/fold/src/fold.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index c13ac93f399..e42c0f02048 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -603,8 +603,23 @@ fn fold_file( } if !output.is_empty() { - writer.write_all(&output)?; - output.clear(); + if col_count >= width { + let mut ctx = FoldContext { + spaces, + width, + mode, + writer, + output: &mut output, + col_count: &mut col_count, + last_space: &mut last_space, + }; + emit_output(&mut ctx)?; + } + + if !output.is_empty() { + writer.write_all(&output)?; + output.clear(); + } } Ok(()) From 77a1c31c43817cb235b974e9b909e150679925e8 Mon Sep 17 00:00:00 2001 From: mattsu Date: Fri, 14 Nov 2025 23:35:17 +0900 Subject: [PATCH 03/21] fix: correct output emission logic in fold for character mode In character width mode, emit output immediately after segments are added if column count exceeds width, preventing redundant flushes. Simplify the file folding logic by removing unnecessary conditional checks at the end, ensuring clean output writing. This fixes potential issues with extra line breaks or incorrect folding behavior. --- src/uu/fold/src/fold.rs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index e42c0f02048..6a52cedc4ca 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -427,6 +427,11 @@ fn push_ascii_segment(segment: &[u8], ctx: &mut FoldContext<'_, W>) -> } remaining = &remaining[take..]; + + if ctx.mode == WidthMode::Characters && *ctx.col_count >= ctx.width && !ctx.output.is_empty() + { + emit_output(ctx)?; + } } Ok(()) @@ -507,6 +512,11 @@ fn process_utf8_line(line: &str, ctx: &mut FoldContext<'_, W>) -> URes ctx.output .extend_from_slice(&line_bytes[byte_idx..next_idx]); *ctx.col_count = ctx.col_count.saturating_add(added); + + if ctx.mode == WidthMode::Characters && *ctx.col_count >= ctx.width && !ctx.output.is_empty() + { + emit_output(ctx)?; + } } Ok(()) @@ -549,6 +559,11 @@ fn process_non_utf8_line(line: &[u8], ctx: &mut FoldContext<'_, W>) -> } ctx.output.push(byte); + + if ctx.mode == WidthMode::Characters && *ctx.col_count >= ctx.width && !ctx.output.is_empty() + { + emit_output(ctx)?; + } } Ok(()) @@ -603,23 +618,8 @@ fn fold_file( } if !output.is_empty() { - if col_count >= width { - let mut ctx = FoldContext { - spaces, - width, - mode, - writer, - output: &mut output, - col_count: &mut col_count, - last_space: &mut last_space, - }; - emit_output(&mut ctx)?; - } - - if !output.is_empty() { - writer.write_all(&output)?; - output.clear(); - } + writer.write_all(&output)?; + output.clear(); } Ok(()) From b0e0033a5812ba1cc0dcc47e4ff92e63eedfebf1 Mon Sep 17 00:00:00 2001 From: mattsu Date: Fri, 14 Nov 2025 23:36:19 +0900 Subject: [PATCH 04/21] refactor(fold): split long if-conditions into multiple lines for readability Refactor code in fold.rs to break lengthy if-condition statements across multiple lines in push_ascii_segment, process_utf8_line, and process_non_utf8_line functions. This improves code readability without changing functionality. --- src/uu/fold/src/fold.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 6a52cedc4ca..9e7381ddbdd 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -428,7 +428,9 @@ fn push_ascii_segment(segment: &[u8], ctx: &mut FoldContext<'_, W>) -> remaining = &remaining[take..]; - if ctx.mode == WidthMode::Characters && *ctx.col_count >= ctx.width && !ctx.output.is_empty() + if ctx.mode == WidthMode::Characters + && *ctx.col_count >= ctx.width + && !ctx.output.is_empty() { emit_output(ctx)?; } @@ -513,7 +515,9 @@ fn process_utf8_line(line: &str, ctx: &mut FoldContext<'_, W>) -> URes .extend_from_slice(&line_bytes[byte_idx..next_idx]); *ctx.col_count = ctx.col_count.saturating_add(added); - if ctx.mode == WidthMode::Characters && *ctx.col_count >= ctx.width && !ctx.output.is_empty() + if ctx.mode == WidthMode::Characters + && *ctx.col_count >= ctx.width + && !ctx.output.is_empty() { emit_output(ctx)?; } @@ -560,7 +564,9 @@ fn process_non_utf8_line(line: &[u8], ctx: &mut FoldContext<'_, W>) -> ctx.output.push(byte); - if ctx.mode == WidthMode::Characters && *ctx.col_count >= ctx.width && !ctx.output.is_empty() + if ctx.mode == WidthMode::Characters + && *ctx.col_count >= ctx.width + && !ctx.output.is_empty() { emit_output(ctx)?; } From ac09d10f0d06e711befa7eeae6fd2949abe8ca76 Mon Sep 17 00:00:00 2001 From: mattsu Date: Sat, 15 Nov 2025 00:10:39 +0900 Subject: [PATCH 05/21] feat(fold): add streaming output with periodic flushing to reduce memory usage Introduce a STREAMING_FLUSH_THRESHOLD constant and helper functions (maybe_flush_unbroken_output, push_byte, push_bytes) to periodically flush the output buffer when it exceeds 8KB and no spaces are being tracked, preventing excessive memory consumption when processing large files. This refactor replaces direct buffer pushes with checks for threshold-based flushing. --- src/uu/fold/src/fold.rs | 52 +++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 9e7381ddbdd..4f99fffa76b 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -19,6 +19,7 @@ const TAB_WIDTH: usize = 8; const NL: u8 = b'\n'; const CR: u8 = b'\r'; const TAB: u8 = b'\t'; +const STREAMING_FLUSH_THRESHOLD: usize = 8 * 1024; mod options { pub const BYTES: &str = "bytes"; @@ -322,6 +323,31 @@ fn emit_output(ctx: &mut FoldContext<'_, W>) -> UResult<()> { Ok(()) } +fn maybe_flush_unbroken_output(ctx: &mut FoldContext<'_, W>) -> UResult<()> { + if ctx.spaces || ctx.output.len() < STREAMING_FLUSH_THRESHOLD { + return Ok(()); + } + + if !ctx.output.is_empty() { + ctx.writer.write_all(ctx.output)?; + ctx.output.clear(); + } + Ok(()) +} + +fn push_byte(ctx: &mut FoldContext<'_, W>, byte: u8) -> UResult<()> { + ctx.output.push(byte); + maybe_flush_unbroken_output(ctx) +} + +fn push_bytes(ctx: &mut FoldContext<'_, W>, bytes: &[u8]) -> UResult<()> { + if bytes.is_empty() { + return Ok(()); + } + ctx.output.extend_from_slice(bytes); + maybe_flush_unbroken_output(ctx) +} + fn process_ascii_line(line: &[u8], ctx: &mut FoldContext<'_, W>) -> UResult<()> { let mut idx = 0; let len = line.len(); @@ -334,12 +360,12 @@ fn process_ascii_line(line: &[u8], ctx: &mut FoldContext<'_, W>) -> UR break; } CR => { - ctx.output.push(CR); + push_byte(ctx, CR)?; *ctx.col_count = 0; idx += 1; } 0x08 => { - ctx.output.push(0x08); + push_byte(ctx, 0x08)?; *ctx.col_count = ctx.col_count.saturating_sub(1); idx += 1; } @@ -358,11 +384,11 @@ fn process_ascii_line(line: &[u8], ctx: &mut FoldContext<'_, W>) -> UR } else { *ctx.last_space = None; } - ctx.output.push(TAB); + push_byte(ctx, TAB)?; idx += 1; } 0x00..=0x07 | 0x0B..=0x0C | 0x0E..=0x1F | 0x7F => { - ctx.output.push(line[idx]); + push_byte(ctx, line[idx])?; if ctx.spaces && line[idx].is_ascii_whitespace() && line[idx] != CR { *ctx.last_space = Some(ctx.output.len() - 1); } else if !ctx.spaces { @@ -412,7 +438,7 @@ fn push_ascii_segment(segment: &[u8], ctx: &mut FoldContext<'_, W>) -> let take = remaining.len().min(available); let base_len = ctx.output.len(); - ctx.output.extend_from_slice(&remaining[..take]); + push_bytes(ctx, &remaining[..take])?; *ctx.col_count += take; if ctx.spaces { @@ -461,15 +487,13 @@ fn process_utf8_line(line: &str, ctx: &mut FoldContext<'_, W>) -> URes } if ch == '\r' { - ctx.output - .extend_from_slice(&line_bytes[byte_idx..next_idx]); + push_bytes(ctx, &line_bytes[byte_idx..next_idx])?; *ctx.col_count = 0; continue; } if ch == '\x08' { - ctx.output - .extend_from_slice(&line_bytes[byte_idx..next_idx]); + push_bytes(ctx, &line_bytes[byte_idx..next_idx])?; *ctx.col_count = ctx.col_count.saturating_sub(1); continue; } @@ -489,8 +513,7 @@ fn process_utf8_line(line: &str, ctx: &mut FoldContext<'_, W>) -> URes } else { *ctx.last_space = None; } - ctx.output - .extend_from_slice(&line_bytes[byte_idx..next_idx]); + push_bytes(ctx, &line_bytes[byte_idx..next_idx])?; continue; } @@ -511,8 +534,7 @@ fn process_utf8_line(line: &str, ctx: &mut FoldContext<'_, W>) -> URes *ctx.last_space = Some(ctx.output.len()); } - ctx.output - .extend_from_slice(&line_bytes[byte_idx..next_idx]); + push_bytes(ctx, &line_bytes[byte_idx..next_idx])?; *ctx.col_count = ctx.col_count.saturating_add(added); if ctx.mode == WidthMode::Characters @@ -551,7 +573,7 @@ fn process_non_utf8_line(line: &[u8], ctx: &mut FoldContext<'_, W>) -> } else { None }; - ctx.output.push(byte); + push_byte(ctx, byte)?; continue; } 0x08 => *ctx.col_count = ctx.col_count.saturating_sub(1), @@ -562,7 +584,7 @@ fn process_non_utf8_line(line: &[u8], ctx: &mut FoldContext<'_, W>) -> _ => *ctx.col_count = ctx.col_count.saturating_add(1), } - ctx.output.push(byte); + push_byte(ctx, byte)?; if ctx.mode == WidthMode::Characters && *ctx.col_count >= ctx.width From dba5b9bb38a043dd60a479dbf34cd670ae26a582 Mon Sep 17 00:00:00 2001 From: mattsu Date: Sat, 15 Nov 2025 08:55:52 +0900 Subject: [PATCH 06/21] fix(fold): correct premature output emission in character mode and add tests Remove conditional checks that incorrectly emitted output when column count reached width in character mode, ensuring proper folding of wide characters and handling of edge cases. Add comprehensive tests for wide characters, invalid UTF-8, zero-width spaces, and buffer boundaries to verify correct behavior. This prevents issues with multi-byte character folding where output was prematurely flushed, improving accuracy for Unicode input. --- src/uu/fold/src/fold.rs | 19 ---- tests/by-util/test_fold.rs | 215 +++++++++++++++++++++++++++++++++++++ 2 files changed, 215 insertions(+), 19 deletions(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 4f99fffa76b..2ebfa65c248 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -454,12 +454,6 @@ fn push_ascii_segment(segment: &[u8], ctx: &mut FoldContext<'_, W>) -> remaining = &remaining[take..]; - if ctx.mode == WidthMode::Characters - && *ctx.col_count >= ctx.width - && !ctx.output.is_empty() - { - emit_output(ctx)?; - } } Ok(()) @@ -537,12 +531,6 @@ fn process_utf8_line(line: &str, ctx: &mut FoldContext<'_, W>) -> URes push_bytes(ctx, &line_bytes[byte_idx..next_idx])?; *ctx.col_count = ctx.col_count.saturating_add(added); - if ctx.mode == WidthMode::Characters - && *ctx.col_count >= ctx.width - && !ctx.output.is_empty() - { - emit_output(ctx)?; - } } Ok(()) @@ -585,13 +573,6 @@ fn process_non_utf8_line(line: &[u8], ctx: &mut FoldContext<'_, W>) -> } push_byte(ctx, byte)?; - - if ctx.mode == WidthMode::Characters - && *ctx.col_count >= ctx.width - && !ctx.output.is_empty() - { - emit_output(ctx)?; - } } Ok(()) diff --git a/tests/by-util/test_fold.rs b/tests/by-util/test_fold.rs index 04072ab157f..f15199fb612 100644 --- a/tests/by-util/test_fold.rs +++ b/tests/by-util/test_fold.rs @@ -59,6 +59,221 @@ fn test_wide_characters_with_characters_option() { .stdout_is("\u{B250}\u{B250}\u{B250}\n"); } +#[test] +fn test_multiple_wide_characters_in_column_mode() { + let wide = '\u{FF1A}'; + let mut input = wide.to_string().repeat(50); + input.push('\n'); + + let mut expected = String::new(); + for i in 1..=50 { + expected.push(wide); + if i % 5 == 0 { + expected.push('\n'); + } + } + + new_ucmd!() + .args(&["-w", "10"]) + .pipe_in(input) + .succeeds() + .stdout_is(expected); +} + +#[test] +fn test_multiple_wide_characters_in_character_mode() { + let wide = '\u{FF1A}'; + let mut input = wide.to_string().repeat(50); + input.push('\n'); + + let mut expected = String::new(); + for i in 1..=50 { + expected.push(wide); + if i % 10 == 0 { + expected.push('\n'); + } + } + + new_ucmd!() + .args(&["--characters", "-w", "10"]) + .pipe_in(input) + .succeeds() + .stdout_is(expected); +} + +#[test] +fn test_unicode_on_reader_buffer_boundary_in_character_mode() { + let boundary = buf_reader_capacity().saturating_sub(1); + assert!(boundary > 0, "BufReader capacity must be greater than 1"); + + let mut input = "a".repeat(boundary); + input.push('\u{B250}'); + input.push_str(&"a".repeat(100)); + input.push('\n'); + + let expected_tail = tail_inclusive( + &fold_characters_reference(&input, 80), + 4, + ); + + let result = new_ucmd!() + .arg("--characters") + .pipe_in(input) + .succeeds(); + + let actual_tail = tail_inclusive(result.stdout_str(), 4); + + assert_eq!(actual_tail, expected_tail); +} + +#[test] +fn test_fold_preserves_invalid_utf8_sequences() { + let bad_input: &[u8] = b"\xC3|\xED\xBA\xAD|\x00|\x89|\xED\xA6\xBF\xED\xBF\xBF\n"; + + new_ucmd!() + .pipe_in(bad_input.to_vec()) + .succeeds() + .stdout_is_bytes(bad_input); +} + +#[test] +fn test_fold_preserves_incomplete_utf8_at_eof() { + let trailing_byte: &[u8] = b"\xC3"; + + new_ucmd!() + .pipe_in(trailing_byte.to_vec()) + .succeeds() + .stdout_is_bytes(trailing_byte); +} + +#[test] +fn test_zero_width_bytes_in_column_mode() { + let len = io_buf_size_times_two(); + let input = vec![0u8; len]; + + new_ucmd!() + .pipe_in(input.clone()) + .succeeds() + .stdout_is_bytes(input); +} + +#[test] +fn test_zero_width_bytes_in_character_mode() { + let len = io_buf_size_times_two(); + let input = vec![0u8; len]; + let expected = fold_characters_reference_bytes(&input, 80); + + new_ucmd!() + .args(&["--characters"]) + .pipe_in(input) + .succeeds() + .stdout_is_bytes(expected); +} + +#[test] +fn test_zero_width_spaces_in_column_mode() { + let len = io_buf_size_times_two(); + let input = "\u{200B}".repeat(len); + + new_ucmd!() + .pipe_in(input.clone()) + .succeeds() + .stdout_is(&input); +} + +#[test] +fn test_zero_width_spaces_in_character_mode() { + let len = io_buf_size_times_two(); + let input = "\u{200B}".repeat(len); + let expected = fold_characters_reference(&input, 80); + + new_ucmd!() + .args(&["--characters"]) + .pipe_in(input) + .succeeds() + .stdout_is(&expected); +} + +#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))] +#[test] +fn test_fold_reports_no_space_left_on_dev_full() { + use std::fs::OpenOptions; + use std::process::Stdio; + + for &byte in &[b'\n', b'\0', 0xC3u8] { + let dev_full = OpenOptions::new() + .write(true) + .open("/dev/full") + .expect("/dev/full must exist on supported targets"); + + new_ucmd!() + .pipe_in(vec![byte; 1024]) + .set_stdout(Stdio::from(dev_full)) + .fails() + .stderr_contains("No space left"); + } +} + +fn buf_reader_capacity() -> usize { + std::io::BufReader::new(&b""[..]).capacity() +} + +fn io_buf_size_times_two() -> usize { + buf_reader_capacity() + .checked_mul(2) + .expect("BufReader capacity overflow") +} + +fn fold_characters_reference(input: &str, width: usize) -> String { + let mut output = String::with_capacity(input.len()); + let mut col_count = 0usize; + + for ch in input.chars() { + if ch == '\n' { + output.push('\n'); + col_count = 0; + continue; + } + + if col_count >= width { + output.push('\n'); + col_count = 0; + } + + output.push(ch); + col_count += 1; + } + + output +} + +fn fold_characters_reference_bytes(input: &[u8], width: usize) -> Vec { + let mut output = Vec::with_capacity(input.len() + input.len() / width + 1); + + for chunk in input.chunks(width) { + output.extend_from_slice(chunk); + if chunk.len() == width { + output.push(b'\n'); + } + } + + output +} + +fn tail_inclusive(text: &str, lines: usize) -> String { + if lines == 0 { + return String::new(); + } + + let segments: Vec<&str> = text.split_inclusive('\n').collect(); + if segments.is_empty() { + return text.to_owned(); + } + + let start = segments.len().saturating_sub(lines); + segments[start..].concat() +} + #[test] fn test_should_preserve_empty_line_without_final_newline() { new_ucmd!() From 556804c2373b566a4e0963dc17f5e5104821852d Mon Sep 17 00:00:00 2001 From: mattsu Date: Sat, 15 Nov 2025 08:57:58 +0900 Subject: [PATCH 07/21] refactor: clean up formatting in fold utility and tests - Remove trailing empty lines in fold.rs - Compact multiline variable assignments in test_fold.rs for readability --- src/uu/fold/src/fold.rs | 2 -- tests/by-util/test_fold.rs | 10 ++-------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 2ebfa65c248..713527a6f54 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -453,7 +453,6 @@ fn push_ascii_segment(segment: &[u8], ctx: &mut FoldContext<'_, W>) -> } remaining = &remaining[take..]; - } Ok(()) @@ -530,7 +529,6 @@ fn process_utf8_line(line: &str, ctx: &mut FoldContext<'_, W>) -> URes push_bytes(ctx, &line_bytes[byte_idx..next_idx])?; *ctx.col_count = ctx.col_count.saturating_add(added); - } Ok(()) diff --git a/tests/by-util/test_fold.rs b/tests/by-util/test_fold.rs index f15199fb612..f8d6e01cca2 100644 --- a/tests/by-util/test_fold.rs +++ b/tests/by-util/test_fold.rs @@ -111,15 +111,9 @@ fn test_unicode_on_reader_buffer_boundary_in_character_mode() { input.push_str(&"a".repeat(100)); input.push('\n'); - let expected_tail = tail_inclusive( - &fold_characters_reference(&input, 80), - 4, - ); + let expected_tail = tail_inclusive(&fold_characters_reference(&input, 80), 4); - let result = new_ucmd!() - .arg("--characters") - .pipe_in(input) - .succeeds(); + let result = new_ucmd!().arg("--characters").pipe_in(input).succeeds(); let actual_tail = tail_inclusive(result.stdout_str(), 4); From a1bbd4036a9126f7917550a5cd65af7ef333f870 Mon Sep 17 00:00:00 2001 From: mattsu Date: Sat, 15 Nov 2025 09:29:43 +0900 Subject: [PATCH 08/21] feat(fold): add unicode-width dependency and tests for zero-width characters Add unicode-width crate to handle zero-width Unicode characters in fold utility. Introduced new test 'test_zero_width_data_line_counts' to verify correct wrapping in --characters mode for zero-width bytes and spaces, ensuring fold behaves consistently with character counts rather than visual width. --- Cargo.lock | 1 + Cargo.toml | 1 + tests/by-util/test_fold.rs | 51 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index f2f8412cc31..7a709e92bc6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -608,6 +608,7 @@ dependencies = [ "tempfile", "textwrap", "time", + "unicode-width 0.2.2", "unindent", "uu_arch", "uu_base32", diff --git a/Cargo.toml b/Cargo.toml index 499eb87412c..3ffacf3ce9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -543,6 +543,7 @@ regex.workspace = true sha1 = { workspace = true, features = ["std"] } tempfile.workspace = true time = { workspace = true, features = ["local-offset"] } +unicode-width.workspace = true unindent = "0.2.3" uutests.workspace = true uucore = { workspace = true, features = [ diff --git a/tests/by-util/test_fold.rs b/tests/by-util/test_fold.rs index f8d6e01cca2..da1265d1503 100644 --- a/tests/by-util/test_fold.rs +++ b/tests/by-util/test_fold.rs @@ -2,6 +2,7 @@ // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. +use unicode_width::UnicodeWidthChar; use uutests::new_ucmd; #[test] @@ -188,6 +189,52 @@ fn test_zero_width_spaces_in_character_mode() { .stdout_is(&expected); } +#[test] +fn test_zero_width_data_line_counts() { + let len = io_buf_size_times_two(); + + let zero_bytes = vec![0u8; len]; + let column_bytes = new_ucmd!().pipe_in(zero_bytes.clone()).succeeds(); + assert_eq!( + newline_count(column_bytes.stdout()), + 0, + "fold should not wrap zero-width bytes in column mode", + ); + + let characters_bytes = new_ucmd!() + .args(&["--characters"]) + .pipe_in(zero_bytes) + .succeeds(); + assert_eq!( + newline_count(characters_bytes.stdout()), + len / 80, + "fold --characters should wrap zero-width bytes every 80 bytes", + ); + + if UnicodeWidthChar::width('\u{200B}') != Some(0) { + eprintln!("skip zero width space checks because width != 0"); + return; + } + + let zero_width_spaces = "\u{200B}".repeat(len); + let column_spaces = new_ucmd!().pipe_in(zero_width_spaces.clone()).succeeds(); + assert_eq!( + newline_count(column_spaces.stdout()), + 0, + "fold should keep zero-width spaces on a single line in column mode", + ); + + let characters_spaces = new_ucmd!() + .args(&["--characters"]) + .pipe_in(zero_width_spaces) + .succeeds(); + assert_eq!( + newline_count(characters_spaces.stdout()), + len / 80, + "fold --characters should wrap zero-width spaces every 80 characters", + ); +} + #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))] #[test] fn test_fold_reports_no_space_left_on_dev_full() { @@ -254,6 +301,10 @@ fn fold_characters_reference_bytes(input: &[u8], width: usize) -> Vec { output } +fn newline_count(bytes: &[u8]) -> usize { + bytes.iter().filter(|&&b| b == b'\n').count() +} + fn tail_inclusive(text: &str, lines: usize) -> String { if lines == 0 { return String::new(); From d176e651ab1ff7d420e4676346256ae85e2148ac Mon Sep 17 00:00:00 2001 From: mattsu Date: Sat, 15 Nov 2025 09:41:06 +0900 Subject: [PATCH 09/21] perf: use bytecount for efficient newline counting in fold tests - Add bytecount dependency to Cargo.toml and Cargo.lock - Refactor newline_count function in test_fold.rs to use bytecount::count instead of manual iteration for better performance --- Cargo.lock | 1 + Cargo.toml | 1 + tests/by-util/test_fold.rs | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 7a709e92bc6..5f2dc510921 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -582,6 +582,7 @@ name = "coreutils" version = "0.4.0" dependencies = [ "bincode", + "bytecount", "chrono", "clap", "clap_complete", diff --git a/Cargo.toml b/Cargo.toml index 3ffacf3ce9a..11d53043b64 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -536,6 +536,7 @@ ctor.workspace = true filetime.workspace = true glob.workspace = true libc.workspace = true +bytecount.workspace = true num-prime.workspace = true pretty_assertions = "1.4.0" rand.workspace = true diff --git a/tests/by-util/test_fold.rs b/tests/by-util/test_fold.rs index da1265d1503..33374a0ebf2 100644 --- a/tests/by-util/test_fold.rs +++ b/tests/by-util/test_fold.rs @@ -2,6 +2,7 @@ // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. +use bytecount::count; use unicode_width::UnicodeWidthChar; use uutests::new_ucmd; @@ -302,7 +303,7 @@ fn fold_characters_reference_bytes(input: &[u8], width: usize) -> Vec { } fn newline_count(bytes: &[u8]) -> usize { - bytes.iter().filter(|&&b| b == b'\n').count() + count(bytes, b'\n') } fn tail_inclusive(text: &str, lines: usize) -> String { From dbad8db67b6218a064834345cee0f39c208197e9 Mon Sep 17 00:00:00 2001 From: mattsu Date: Sat, 15 Nov 2025 11:15:56 +0900 Subject: [PATCH 10/21] refactor: Handle zero-width bytes across buffer boundaries in fold Modify the fold implementation to process input in buffered chunks rather than line-by-line reading, ensuring correct handling of multi-byte characters split across buffer boundaries. Add process_pending_chunk function and new streaming logic to fold_file for better performance on large files. Update tests accordingly. --- src/uu/fold/src/fold.rs | 86 ++++++++++++++++++++++++++++---------- tests/by-util/test_fold.rs | 38 +++++++++++++++++ 2 files changed, 103 insertions(+), 21 deletions(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 713527a6f54..75fbba63c91 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -357,7 +357,7 @@ fn process_ascii_line(line: &[u8], ctx: &mut FoldContext<'_, W>) -> UR NL => { *ctx.last_space = None; emit_output(ctx)?; - break; + idx += 1; } CR => { push_byte(ctx, CR)?; @@ -472,7 +472,7 @@ fn process_utf8_line(line: &str, ctx: &mut FoldContext<'_, W>) -> URes if ch == '\n' { *ctx.last_space = None; emit_output(ctx)?; - break; + continue; } if *ctx.col_count >= ctx.width { @@ -539,7 +539,7 @@ fn process_non_utf8_line(line: &[u8], ctx: &mut FoldContext<'_, W>) -> if byte == NL { *ctx.last_space = None; emit_output(ctx)?; - break; + continue; } if *ctx.col_count >= ctx.width { @@ -576,6 +576,43 @@ fn process_non_utf8_line(line: &[u8], ctx: &mut FoldContext<'_, W>) -> Ok(()) } +fn process_pending_chunk( + pending: &mut Vec, + ctx: &mut FoldContext<'_, W>, +) -> UResult<()> { + loop { + if pending.is_empty() { + break; + } + + match std::str::from_utf8(pending) { + Ok(valid) => { + process_utf8_line(valid, ctx)?; + pending.clear(); + break; + } + Err(err) => { + if let Some(_) = err.error_len() { + process_non_utf8_line(pending, ctx)?; + pending.clear(); + break; + } else { + let valid_up_to = err.valid_up_to(); + if valid_up_to > 0 { + let valid = + std::str::from_utf8(&pending[..valid_up_to]).expect("valid prefix"); + process_utf8_line(valid, ctx)?; + pending.drain(..valid_up_to); + } + break; + } + } + } + } + + Ok(()) +} + /// Fold `file` to fit `width` (number of columns). /// /// By default `fold` treats tab, backspace, and carriage return specially: @@ -592,20 +629,12 @@ fn fold_file( mode: WidthMode, writer: &mut W, ) -> UResult<()> { - let mut line = Vec::new(); let mut output = Vec::new(); let mut col_count = 0; let mut last_space = None; + let mut pending = Vec::new(); - loop { - if file - .read_until(NL, &mut line) - .map_err_context(|| translate!("fold-error-readline"))? - == 0 - { - break; - } - + { let mut ctx = FoldContext { spaces, width, @@ -616,17 +645,32 @@ fn fold_file( last_space: &mut last_space, }; - match std::str::from_utf8(&line) { - Ok(s) => process_utf8_line(s, &mut ctx)?, - Err(_) => process_non_utf8_line(&line, &mut ctx)?, + loop { + let buffer = file + .fill_buf() + .map_err_context(|| translate!("fold-error-readline"))?; + if buffer.is_empty() { + break; + } + pending.extend_from_slice(buffer); + let consumed = buffer.len(); + file.consume(consumed); + + process_pending_chunk(&mut pending, &mut ctx)?; } - line.clear(); - } + if !pending.is_empty() { + match std::str::from_utf8(&pending) { + Ok(s) => process_utf8_line(s, &mut ctx)?, + Err(_) => process_non_utf8_line(&pending, &mut ctx)?, + } + pending.clear(); + } - if !output.is_empty() { - writer.write_all(&output)?; - output.clear(); + if !ctx.output.is_empty() { + ctx.writer.write_all(ctx.output)?; + ctx.output.clear(); + } } Ok(()) diff --git a/tests/by-util/test_fold.rs b/tests/by-util/test_fold.rs index 33374a0ebf2..b022a313e95 100644 --- a/tests/by-util/test_fold.rs +++ b/tests/by-util/test_fold.rs @@ -5,6 +5,8 @@ use bytecount::count; use unicode_width::UnicodeWidthChar; use uutests::new_ucmd; +use uutests::util::TestScenario; +use uutests::util_name; #[test] fn test_invalid_arg() { @@ -190,6 +192,42 @@ fn test_zero_width_spaces_in_character_mode() { .stdout_is(&expected); } +#[test] +fn test_zero_width_bytes_from_file() { + let len = io_buf_size_times_two(); + let input = vec![0u8; len]; + let expected = fold_characters_reference_bytes(&input, 80); + + let ts = TestScenario::new(util_name!()); + let path = "zeros.bin"; + ts.fixtures.write_bytes(path, &input); + + ts.ucmd().arg(path).succeeds().stdout_is_bytes(&input); + + ts.ucmd() + .args(&["--characters", path]) + .succeeds() + .stdout_is_bytes(expected); +} + +#[test] +fn test_zero_width_spaces_from_file() { + let len = io_buf_size_times_two(); + let input = "\u{200B}".repeat(len); + let expected = fold_characters_reference(&input, 80); + + let ts = TestScenario::new(util_name!()); + let path = "zero-width.txt"; + ts.fixtures.write(path, &input); + + ts.ucmd().arg(path).succeeds().stdout_is(&input); + + ts.ucmd() + .args(&["--characters", path]) + .succeeds() + .stdout_is(&expected); +} + #[test] fn test_zero_width_data_line_counts() { let len = io_buf_size_times_two(); From cd6f536bcdab4a56256f7bf4c2ffc6a2cb8819c8 Mon Sep 17 00:00:00 2001 From: mattsu Date: Sat, 15 Nov 2025 11:20:08 +0900 Subject: [PATCH 11/21] refactor(fold): streamline process_pending_chunk loop and error handling Replace loop with early empty check by a while loop conditional on !pending.is_empty() for clarity. Restructure invalid UTF-8 error handling to first check if valid_up_to == 0, then process the valid prefix, improving code readability and flow without changing behavior. --- src/uu/fold/src/fold.rs | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 75fbba63c91..2d131e8c974 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -580,11 +580,7 @@ fn process_pending_chunk( pending: &mut Vec, ctx: &mut FoldContext<'_, W>, ) -> UResult<()> { - loop { - if pending.is_empty() { - break; - } - + while !pending.is_empty() { match std::str::from_utf8(pending) { Ok(valid) => { process_utf8_line(valid, ctx)?; @@ -592,20 +588,21 @@ fn process_pending_chunk( break; } Err(err) => { - if let Some(_) = err.error_len() { + if err.error_len().is_some() { process_non_utf8_line(pending, ctx)?; pending.clear(); break; - } else { - let valid_up_to = err.valid_up_to(); - if valid_up_to > 0 { - let valid = - std::str::from_utf8(&pending[..valid_up_to]).expect("valid prefix"); - process_utf8_line(valid, ctx)?; - pending.drain(..valid_up_to); - } + } + + let valid_up_to = err.valid_up_to(); + if valid_up_to == 0 { break; } + + let valid = + std::str::from_utf8(&pending[..valid_up_to]).expect("valid prefix"); + process_utf8_line(valid, ctx)?; + pending.drain(..valid_up_to); } } } From 75c542f7d79278cb577291862fccb4346a466711 Mon Sep 17 00:00:00 2001 From: mattsu Date: Sat, 15 Nov 2025 11:21:05 +0900 Subject: [PATCH 12/21] refactor(fold): condense variable assignment to single line Consolidate the assignment of the `valid` variable from multiple lines to a single line for improved code readability and adherence to style guidelines favoring concise declarations. --- src/uu/fold/src/fold.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 2d131e8c974..a594ba03450 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -599,8 +599,7 @@ fn process_pending_chunk( break; } - let valid = - std::str::from_utf8(&pending[..valid_up_to]).expect("valid prefix"); + let valid = std::str::from_utf8(&pending[..valid_up_to]).expect("valid prefix"); process_utf8_line(valid, ctx)?; pending.drain(..valid_up_to); } From eb7d8c4f2ad86245f8bef28e343e97bc165fbbf3 Mon Sep 17 00:00:00 2001 From: mattsu Date: Thu, 20 Nov 2025 18:52:41 +0900 Subject: [PATCH 13/21] fix(fold): properly handle combining characters in character-counting mode Only coalesce zero-width combining characters into base characters when folding by display columns (WidthMode::Columns). In character-counting mode, treat every scalar value as advancing the counter to match chars().count() semantics, preventing incorrect line breaking for characters with zero-width marks. This ensures consistent behavior across modes as verified by existing tests. --- src/uu/fold/src/fold.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 35215da5006..b3bef85727a 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -467,12 +467,18 @@ fn process_utf8_line(line: &str, ctx: &mut FoldContext<'_, W>) -> URes let mut iter = line.char_indices().peekable(); while let Some((byte_idx, ch)) = iter.next() { - // Include combining characters with the base character - while let Some(&(_, next_ch)) = iter.peek() { - if unicode_width::UnicodeWidthChar::width(next_ch).unwrap_or(1) == 0 { - iter.next(); - } else { - break; + // Include combining characters with the base character when we are + // measuring by display columns. In character-counting mode every + // scalar value must advance the counter to match `chars().count()` + // semantics (see `fold_characters_reference` in the tests), so we do + // not coalesce zero-width scalars there. + if ctx.mode == WidthMode::Columns { + while let Some(&(_, next_ch)) = iter.peek() { + if unicode_width::UnicodeWidthChar::width(next_ch).unwrap_or(1) == 0 { + iter.next(); + } else { + break; + } } } From e54a74b3f6498e39f0d12e80ad785a89910c4769 Mon Sep 17 00:00:00 2001 From: mattsu Date: Mon, 22 Dec 2025 21:02:25 +0900 Subject: [PATCH 14/21] refactor(fold): add comments to explain streaming flush logic and prevent unbounded buffering Add explanatory comments to constants and functions in fold.rs, detailing the 8 KiB threshold for flushing in streaming mode to avoid unbounded buffer growth, and clarifying line folding behavior with the -s option. Improves code readability without altering functionality. --- src/uu/fold/src/fold.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 38c17570420..3acea901682 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -19,6 +19,7 @@ const TAB_WIDTH: usize = 8; const NL: u8 = b'\n'; const CR: u8 = b'\r'; const TAB: u8 = b'\t'; +// Implementation threshold (8 KiB) to prevent unbounded buffer growth during streaming. const STREAMING_FLUSH_THRESHOLD: usize = 8 * 1024; mod options { @@ -289,6 +290,8 @@ fn compute_col_count(buffer: &[u8], mode: WidthMode) -> usize { } fn emit_output(ctx: &mut FoldContext<'_, W>) -> UResult<()> { + // Emit a folded line and keep the remaining buffer (if any) for the next line. + // When `-s` is active, we prefer breaking at the last recorded whitespace. let consume = match *ctx.last_space { Some(index) => index + 1, None => ctx.output.len(), @@ -324,6 +327,9 @@ fn emit_output(ctx: &mut FoldContext<'_, W>) -> UResult<()> { } fn maybe_flush_unbroken_output(ctx: &mut FoldContext<'_, W>) -> UResult<()> { + // In streaming mode without `-s`, avoid unbounded buffering by periodically + // flushing long unbroken output segments. When `-s` is enabled we must keep + // the buffer to preserve the last whitespace boundary for folding. if ctx.spaces || ctx.output.len() < STREAMING_FLUSH_THRESHOLD { return Ok(()); } @@ -336,11 +342,13 @@ fn maybe_flush_unbroken_output(ctx: &mut FoldContext<'_, W>) -> UResul } fn push_byte(ctx: &mut FoldContext<'_, W>, byte: u8) -> UResult<()> { + // Append a single byte and flush if the buffer grows too large. ctx.output.push(byte); maybe_flush_unbroken_output(ctx) } fn push_bytes(ctx: &mut FoldContext<'_, W>, bytes: &[u8]) -> UResult<()> { + // Append a byte slice and flush if the buffer grows too large. if bytes.is_empty() { return Ok(()); } From 5de4b281837d33b6dd840c961b2cfd442d221b24 Mon Sep 17 00:00:00 2001 From: mattsu Date: Mon, 22 Dec 2025 21:33:42 +0900 Subject: [PATCH 15/21] refactor(fold): extract UTF-8 char processing and improve pending chunk handling - Extract UTF-8 character processing into a new `process_utf8_chars` function for better code organization - Add documentation to `process_pending_chunk` explaining its behavior with buffered bytes and invalid UTF-8 - Modify `process_pending_chunk` to properly handle the result of `process_non_utf8_line`, ensuring errors are propagated after clearing the buffer --- src/uu/fold/src/fold.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 3acea901682..00b3a45cc77 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -471,6 +471,10 @@ fn process_utf8_line(line: &str, ctx: &mut FoldContext<'_, W>) -> URes return process_ascii_line(line.as_bytes(), ctx); } + process_utf8_chars(line, ctx) +} + +fn process_utf8_chars(line: &str, ctx: &mut FoldContext<'_, W>) -> UResult<()> { let line_bytes = line.as_bytes(); let mut iter = line.char_indices().peekable(); @@ -599,6 +603,11 @@ fn process_non_utf8_line(line: &[u8], ctx: &mut FoldContext<'_, W>) -> Ok(()) } +/// Process buffered bytes, emitting output for valid UTF-8 prefixes and +/// deferring incomplete sequences until more input arrives. +/// +/// If the buffer contains invalid UTF-8, it is handled in non-UTF-8 mode and +/// the buffer is fully consumed. fn process_pending_chunk( pending: &mut Vec, ctx: &mut FoldContext<'_, W>, @@ -612,8 +621,9 @@ fn process_pending_chunk( } Err(err) => { if err.error_len().is_some() { - process_non_utf8_line(pending, ctx)?; + let res = process_non_utf8_line(pending, ctx); pending.clear(); + res?; break; } From 654c1281e2848a91e2831a8fcb92db245947cd2c Mon Sep 17 00:00:00 2001 From: mattsu Date: Tue, 30 Dec 2025 14:01:15 +0900 Subject: [PATCH 16/21] refactor(fold): add streaming flush threshold and enhance comments in fold logic - Introduce STREAMING_FLUSH_THRESHOLD constant (8 KiB) to prevent unbounded buffer growth during streaming, ensuring memory efficiency when input lacks fold points. - Improve comments in emit_output, maybe_flush_unbroken_output, push_byte, and push_bytes functions for better clarity on folding behavior, whitespace handling, and buffer management. - Adjust last_space index rebasing logic in emit_output to correctly track whitespace positions after partial consumption, maintaining accurate breaks with -s flag. --- src/uu/fold/src/fold.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 00b3a45cc77..c049bc7a7f2 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -20,6 +20,8 @@ const NL: u8 = b'\n'; const CR: u8 = b'\r'; const TAB: u8 = b'\t'; // Implementation threshold (8 KiB) to prevent unbounded buffer growth during streaming. +// Chosen as a small, fixed cap: large enough to avoid excessive flushes, but +// small enough to keep memory bounded when the input has no fold points. const STREAMING_FLUSH_THRESHOLD: usize = 8 * 1024; mod options { @@ -290,8 +292,10 @@ fn compute_col_count(buffer: &[u8], mode: WidthMode) -> usize { } fn emit_output(ctx: &mut FoldContext<'_, W>) -> UResult<()> { - // Emit a folded line and keep the remaining buffer (if any) for the next line. - // When `-s` is active, we prefer breaking at the last recorded whitespace. + // Emit one folded line: + // - with `-s`, cut at the last remembered whitespace when possible + // - otherwise, cut at the current buffer end + // The remainder (if any) stays in the buffer for the next line. let consume = match *ctx.last_space { Some(index) => index + 1, None => ctx.output.len(), @@ -313,6 +317,7 @@ fn emit_output(ctx: &mut FoldContext<'_, W>) -> UResult<()> { *ctx.col_count = compute_col_count(ctx.output, ctx.mode); if ctx.spaces { + // Rebase the remembered whitespace position into the remaining buffer. *ctx.last_space = last_space.and_then(|idx| { if idx < consume { None @@ -328,13 +333,15 @@ fn emit_output(ctx: &mut FoldContext<'_, W>) -> UResult<()> { fn maybe_flush_unbroken_output(ctx: &mut FoldContext<'_, W>) -> UResult<()> { // In streaming mode without `-s`, avoid unbounded buffering by periodically - // flushing long unbroken output segments. When `-s` is enabled we must keep - // the buffer to preserve the last whitespace boundary for folding. + // flushing long unbroken segments. With `-s` we must keep the buffer so we + // can still break at the last whitespace boundary. if ctx.spaces || ctx.output.len() < STREAMING_FLUSH_THRESHOLD { return Ok(()); } if !ctx.output.is_empty() { + // Write raw bytes without inserting a newline; folding will continue + // based on updated column tracking in the caller. ctx.writer.write_all(ctx.output)?; ctx.output.clear(); } @@ -342,13 +349,13 @@ fn maybe_flush_unbroken_output(ctx: &mut FoldContext<'_, W>) -> UResul } fn push_byte(ctx: &mut FoldContext<'_, W>, byte: u8) -> UResult<()> { - // Append a single byte and flush if the buffer grows too large. + // Append a single byte to the buffer and flush if it grows too large. ctx.output.push(byte); maybe_flush_unbroken_output(ctx) } fn push_bytes(ctx: &mut FoldContext<'_, W>, bytes: &[u8]) -> UResult<()> { - // Append a byte slice and flush if the buffer grows too large. + // Append a byte slice to the buffer and flush if it grows too large. if bytes.is_empty() { return Ok(()); } From 8aa275125de16645ed307758f627246119ee7cf6 Mon Sep 17 00:00:00 2001 From: mattsu Date: Wed, 31 Dec 2025 08:21:57 +0900 Subject: [PATCH 17/21] refactor(fold): remove auto-flush from push_byte function Updated push_byte to only append bytes to the buffer without triggering flush checks, removing the call to maybe_flush_unbroken_output and adjusting the comment to reflect the new behavior. This change simplifies the function's logic, potentially improving performance by deferring flushes to other parts of the code. --- src/uu/fold/src/fold.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index c049bc7a7f2..526288a04e3 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -349,9 +349,9 @@ fn maybe_flush_unbroken_output(ctx: &mut FoldContext<'_, W>) -> UResul } fn push_byte(ctx: &mut FoldContext<'_, W>, byte: u8) -> UResult<()> { - // Append a single byte to the buffer and flush if it grows too large. + // Append a single byte to the buffer. ctx.output.push(byte); - maybe_flush_unbroken_output(ctx) + Ok(()) } fn push_bytes(ctx: &mut FoldContext<'_, W>, bytes: &[u8]) -> UResult<()> { From 71f845c3c7505e47ec87ba1b35625bda47bc2b75 Mon Sep 17 00:00:00 2001 From: mattsu Date: Wed, 31 Dec 2025 08:25:43 +0900 Subject: [PATCH 18/21] refactor(fold): optimize output flushing and vector preallocation Remove unnecessary empty check in maybe_flush_unbroken_output to simplify logic and reduce overhead. Preallocate capacity for pending vector in fold_file to improve performance by minimizing reallocations. --- src/uu/fold/src/fold.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 526288a04e3..8a69b8c272c 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -339,12 +339,10 @@ fn maybe_flush_unbroken_output(ctx: &mut FoldContext<'_, W>) -> UResul return Ok(()); } - if !ctx.output.is_empty() { - // Write raw bytes without inserting a newline; folding will continue - // based on updated column tracking in the caller. - ctx.writer.write_all(ctx.output)?; - ctx.output.clear(); - } + // Write raw bytes without inserting a newline; folding will continue + // based on updated column tracking in the caller. + ctx.writer.write_all(ctx.output)?; + ctx.output.clear(); Ok(()) } @@ -668,7 +666,7 @@ fn fold_file( let mut output = Vec::new(); let mut col_count = 0; let mut last_space = None; - let mut pending = Vec::new(); + let mut pending = Vec::with_capacity(8 * 1024); { let mut ctx = FoldContext { From 7331d2382fed6c9da435cb88023c7480944ec64c Mon Sep 17 00:00:00 2001 From: mattsu Date: Sat, 10 Jan 2026 08:36:47 +0900 Subject: [PATCH 19/21] fix(fold): flush output after pushing byte in push_byte function Previously, the push_byte function only appended the byte to the buffer and returned Ok(()), potentially leaving output unflushed. This change adds a call to maybe_flush_unbroken_output to ensure proper flushing after each byte push, improving output reliability in the fold utility. --- src/uu/fold/src/fold.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 8a69b8c272c..d79d6d42233 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -349,7 +349,7 @@ fn maybe_flush_unbroken_output(ctx: &mut FoldContext<'_, W>) -> UResul fn push_byte(ctx: &mut FoldContext<'_, W>, byte: u8) -> UResult<()> { // Append a single byte to the buffer. ctx.output.push(byte); - Ok(()) + maybe_flush_unbroken_output(ctx) } fn push_bytes(ctx: &mut FoldContext<'_, W>, bytes: &[u8]) -> UResult<()> { From afbd393edf4cda3345a921e2bbd5abcd98ffff05 Mon Sep 17 00:00:00 2001 From: mattsu Date: Sat, 10 Jan 2026 08:51:20 +0900 Subject: [PATCH 20/21] chore(deps): update Rust dependencies to latest versions - Updated multiple crates including aho-corasick (1.1.3 -> 1.1.4), anstream (0.6.19 -> 0.6.21), and toml (0.22.27 -> 0.23.10+spec-1.0.0) - Added toml_parser dependency as required by updated toml crate - Ensures compatibility, security patches, and performance improvements across the project --- Cargo.lock | 588 +++++++++++++++++++++++++++++------------------------ 1 file changed, 323 insertions(+), 265 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a001f5935d..17a01e3f420 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,9 +10,9 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] @@ -43,9 +43,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.19" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -58,9 +58,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" @@ -73,22 +73,22 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.9" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -108,9 +108,9 @@ dependencies = [ [[package]] name = "arbitrary" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" dependencies = [ "derive_arbitrary", ] @@ -129,9 +129,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "base64-simd" @@ -171,7 +171,7 @@ version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "cexpr", "clang-sys", "itertools 0.13.0", @@ -193,9 +193,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "bitvec" @@ -243,6 +243,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2", +] + [[package]] name = "bstr" version = "1.12.1" @@ -256,9 +265,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.18.1" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "bytecount" @@ -274,10 +283,11 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.2.27" +version = "1.2.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" +checksum = "cd4932aefd12402b36c60956a4fe0035421f544799057659ff86f923657aada3" dependencies = [ + "find-msvc-tools", "shlex", ] @@ -292,9 +302,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" @@ -357,9 +367,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "clap_mangen" @@ -461,15 +471,15 @@ checksum = "baf0a07a401f374238ab8e2f11a104d2851bf9ce711ec69804834de8af45c7af" [[package]] name = "console" -version = "0.16.0" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e09ced7ebbccb63b4c65413d821f2e00ce54c5ca4514ddc6b3c892fdbcbc69d" +checksum = "03e45a4a8926227e4197636ba97a9fc9b00477e9f4bd711395687c5f0734bec4" dependencies = [ "encode_unicode", "libc", "once_cell", "unicode-width 0.2.2", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -506,9 +516,9 @@ checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" [[package]] name = "convert_case" -version = "0.7.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" dependencies = [ "unicode-segmentation", ] @@ -523,6 +533,7 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" name = "coreutils" version = "0.5.0" dependencies = [ + "bytecount", "clap", "clap_complete", "clap_mangen", @@ -737,7 +748,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "crossterm_winapi", "derive_more", "document-features", @@ -761,15 +772,15 @@ dependencies = [ [[package]] name = "crunchy" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", "typenum", @@ -793,12 +804,13 @@ checksum = "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1" [[package]] name = "ctrlc" -version = "3.4.7" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f93780a459b7d656ef7f071fe699c4d3d2cb201c4b24d085b6ddc505276e73" +checksum = "73736a89c4aff73035ba2ed2e565061954da00d4970fc9ac25dcc85a2a20d790" dependencies = [ + "dispatch2", "nix", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -864,18 +876,18 @@ dependencies = [ [[package]] name = "deranged" -version = "0.5.2" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75d7cc94194b4dd0fa12845ef8c911101b7f37633cda14997a6e82099aa0b693" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" dependencies = [ "powerfmt", ] [[package]] name = "derive_arbitrary" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", @@ -884,22 +896,23 @@ dependencies = [ [[package]] name = "derive_more" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" dependencies = [ "derive_more-impl", ] [[package]] name = "derive_more-impl" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" dependencies = [ "convert_case", "proc-macro2", "quote", + "rustc_version", "syn", ] @@ -919,6 +932,18 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "dispatch2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags 2.10.0", + "block2", + "libc", + "objc2", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -964,18 +989,18 @@ dependencies = [ [[package]] name = "document-features" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" dependencies = [ "litrs", ] [[package]] name = "dtor" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e58a0764cddb55ab28955347b45be00ade43d4d6f3ba4bf3dc354e4ec9432934" +checksum = "404d02eeb088a82cfd873006cb713fe411306c7d182c344905e101fb1167d301" dependencies = [ "dtor-proc-macro", ] @@ -1012,12 +1037,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.12" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1026,7 +1051,7 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22be12de19decddab85d09f251ec8363f060ccb22ec9c81bc157c0c8433946d8" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "log", "scopeguard", "uuid", @@ -1067,11 +1092,17 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f449e6c6c08c865631d4890cfacf252b3d396c9bcc83adb6623cdb02a8336c41" + [[package]] name = "fixed_decimal" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35943d22b2f19c0cb198ecf915910a8158e94541c89dcc63300d7799d46c2c5e" +checksum = "35eabf480f94d69182677e37571d3be065822acfafd12f2f085db44fbbcc8e57" dependencies = [ "displaydoc", "smallvec", @@ -1080,9 +1111,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.1.2" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" dependencies = [ "crc32fast", "libz-rs-sys", @@ -1117,9 +1148,9 @@ dependencies = [ [[package]] name = "fluent-langneg" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c4ad0989667548f06ccd0e306ed56b61bd4d35458d54df5ec7587c0e8ed5e94" +checksum = "7eebbe59450baee8282d71676f3bfed5689aeab00b27545e83e5f14b1195e8b0" dependencies = [ "unic-langid", ] @@ -1244,19 +1275,19 @@ checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasip2", ] [[package]] @@ -1273,7 +1304,7 @@ checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", - "zerocopy 0.8.27", + "zerocopy 0.8.33", ] [[package]] @@ -1284,15 +1315,21 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "hashbrown" -version = "0.15.4" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", "equivalent", "foldhash", ] +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + [[package]] name = "hex" version = "0.4.3" @@ -1459,9 +1496,9 @@ checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ "icu_collections", "icu_locale_core", @@ -1473,9 +1510,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" [[package]] name = "icu_provider" @@ -1502,12 +1539,12 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "indexmap" -version = "2.9.0" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", - "hashbrown 0.15.4", + "hashbrown 0.16.1", ] [[package]] @@ -1529,7 +1566,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "inotify-sys", "libc", ] @@ -1564,9 +1601,9 @@ dependencies = [ [[package]] name = "is_terminal_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itertools" @@ -1588,9 +1625,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jiff" @@ -1620,9 +1657,9 @@ dependencies = [ [[package]] name = "jiff-tzdb" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1283705eb0a21404d2bfd6eef2a7593d240bc42a0bdb39db0ad6fa2ec026524" +checksum = "68971ebff725b9e2ca27a601c5eb38a4c5d64422c4cbab0c535f248087eda5c2" [[package]] name = "jiff-tzdb-platform" @@ -1635,9 +1672,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ "once_cell", "wasm-bindgen", @@ -1686,12 +1723,12 @@ checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" [[package]] name = "libloading" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-targets 0.53.2", + "windows-link", ] [[package]] @@ -1702,20 +1739,20 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.3" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "libc", - "redox_syscall", + "redox_syscall 0.7.0", ] [[package]] name = "libz-rs-sys" -version = "0.5.1" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "172a788537a2221661b480fee8dc5f96c580eb34fa88764d3205dc356c7e4221" +checksum = "c10501e7805cee23da17c7790e59df2870c0d4043ec6d03f67d31e2b53e77415" dependencies = [ "zlib-rs", ] @@ -1734,31 +1771,30 @@ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "litrs" -version = "0.4.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.27" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "lru" @@ -1766,7 +1802,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.4", + "hashbrown 0.15.5", ] [[package]] @@ -1826,17 +1862,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", ] [[package]] name = "mio" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", "log", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", "windows-sys 0.61.2", ] @@ -1846,7 +1883,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "cfg-if", "cfg_aliases", "libc", @@ -1878,7 +1915,7 @@ version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "fsevent-sys", "inotify", "kqueue", @@ -1976,6 +2013,21 @@ dependencies = [ "libc", ] +[[package]] +name = "objc2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + [[package]] name = "once_cell" version = "1.21.3" @@ -1984,9 +2036,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "once_cell_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "onig" @@ -1994,7 +2046,7 @@ version = "6.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "336b9c63443aceef14bea841b899035ae3abe89b7c486aaf4c5bd8aafedac3f0" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "libc", "once_cell", "onig_sys", @@ -2037,9 +2089,9 @@ checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" [[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -2047,15 +2099,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.18", "smallvec", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -2138,9 +2190,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.11.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" [[package]] name = "portable-atomic-util" @@ -2174,7 +2226,7 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.8.27", + "zerocopy 0.8.33", ] [[package]] @@ -2189,9 +2241,9 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.34" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6837b9e10d61f45f987d50808f83d1ee3d206c66acf650c3e4ae2e1f6ddedf55" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", "syn", @@ -2199,9 +2251,9 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ "toml_edit", ] @@ -2221,7 +2273,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25485360a54d6861439d60facef26de713b1e126bf015ec8f98239467a2b82f7" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "chrono", "flate2", "procfs-core", @@ -2234,7 +2286,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6401bf7b6af22f78b563665d15a22e9aef27775b79b149a66ca022468a4e405" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "chrono", "hex", ] @@ -2250,9 +2302,9 @@ dependencies = [ [[package]] name = "r-efi" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "radium" @@ -2316,7 +2368,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", ] [[package]] @@ -2341,11 +2393,20 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.13" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.10.0", +] + +[[package]] +name = "redox_syscall" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" +checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", ] [[package]] @@ -2362,9 +2423,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "722166aa0d7438abbaa4d5cc2c649dac844e8c56d82fb3d33e9c34b5cd268fc6" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -2373,15 +2434,15 @@ dependencies = [ [[package]] name = "regex-lite" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943f41321c63ef1c92fd763bfe054d2668f7f225a5c29f0105903dc2fc04ba30" +checksum = "8d942b98df5e658f56f20d592c7f868833fe38115e65c33003d8cd224b0155da" [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "relative-path" @@ -2460,11 +2521,11 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "errno", "libc", "linux-raw-sys 0.11.0", @@ -2473,15 +2534,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" - -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "same-file" @@ -2510,7 +2565,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ef2ca58174235414aee5465f5d8ef9f5833023b31484eb52ca505f306f4573c" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "errno", "libc", "once_cell", @@ -2533,9 +2588,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" [[package]] name = "serde" @@ -2569,14 +2624,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.140" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", - "ryu", "serde", + "serde_core", + "zmij", ] [[package]] @@ -2650,18 +2706,19 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.5" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ + "errno", "libc", ] [[package]] name = "simd-adler32" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" [[package]] name = "siphasher" @@ -2671,12 +2728,9 @@ checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "slab" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] name = "sm3" @@ -2701,12 +2755,12 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" [[package]] name = "socket2" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -2717,9 +2771,9 @@ checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "statrs" @@ -2737,7 +2791,7 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23de088478b31c349c9ba67816fa55d9355232d63c3afea8bf513e31f0f1d2c0" dependencies = [ - "hashbrown 0.15.4", + "hashbrown 0.15.5", "serde", ] @@ -2777,12 +2831,12 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.23.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ "fastrand", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", "rustix", "windows-sys 0.61.2", @@ -2894,28 +2948,42 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", + "serde_core", "zerovec", ] [[package]] name = "toml_datetime" -version = "0.6.11" +version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] [[package]] name = "toml_edit" -version = "0.22.27" +version = "0.23.10+spec-1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" dependencies = [ "indexmap", "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +dependencies = [ "winnow", ] @@ -2930,9 +2998,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "unic-langid" @@ -2954,9 +3022,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-linebreak" @@ -4276,9 +4344,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.17.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" dependencies = [ "js-sys", "wasm-bindgen", @@ -4338,45 +4406,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4384,22 +4439,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" dependencies = [ "unicode-ident", ] @@ -4551,7 +4606,7 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.2", + "windows-targets 0.53.5", ] [[package]] @@ -4581,18 +4636,19 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.2" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -4603,9 +4659,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" @@ -4615,9 +4671,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" @@ -4627,9 +4683,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" @@ -4639,9 +4695,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" @@ -4651,9 +4707,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" @@ -4663,9 +4719,9 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" @@ -4675,9 +4731,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" @@ -4687,27 +4743,24 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.11" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" dependencies = [ "memchr", ] [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.9.1", -] +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "write16" @@ -4748,11 +4801,10 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "yoke" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ - "serde", "stable_deref_trait", "yoke-derive", "zerofrom", @@ -4760,9 +4812,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", @@ -4788,11 +4840,11 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.27" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd" dependencies = [ - "zerocopy-derive 0.8.27", + "zerocopy-derive 0.8.33", ] [[package]] @@ -4808,9 +4860,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.8.27" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1" dependencies = [ "proc-macro2", "quote", @@ -4840,9 +4892,9 @@ dependencies = [ [[package]] name = "zerotrie" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" dependencies = [ "displaydoc", "yoke", @@ -4863,9 +4915,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", @@ -4888,15 +4940,21 @@ dependencies = [ [[package]] name = "zlib-rs" -version = "0.5.1" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626bd9fa9734751fc50d6060752170984d7053f5a39061f524cda68023d4db8a" +checksum = "40990edd51aae2c2b6907af74ffb635029d5788228222c4bb811e9351c0caad3" + +[[package]] +name = "zmij" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fc5a66a20078bf1251bde995aa2fdcc4b800c70b5d92dd2c62abc5c60f679f8" [[package]] name = "zopfli" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfc5ee405f504cd4984ecc6f14d02d55cfda60fa4b689434ef4102aae150cd7" +checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249" dependencies = [ "bumpalo", "crc32fast", From 9ab12710080c7f8853cff278d77c2f98d5a01757 Mon Sep 17 00:00:00 2001 From: mattsu Date: Thu, 15 Jan 2026 20:15:18 +0900 Subject: [PATCH 21/21] chore: update Rust dependencies to latest versions - Updated chrono from 0.4.42 to 0.4.43 - Updated clap_lex from 0.7.6 to 0.7.7 - Updated getrandom from 0.2.16 to 0.2.17 - Updated flate2 from 1.1.5 to 1.1.8 with dependency changes - Updated icu_locale_data from 2.1.1 to 2.1.2 - Updated js-sys from 0.3.83 to 0.3.85 - Updated wasm-bindgen from 0.2.106 to 0.2.108 - Removed unused arbitrary and derive_arbitrary packages - Ensured compatibility and security fixes in dependencies --- Cargo.lock | 81 ++++++++++++++++++------------------------------------ 1 file changed, 26 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 94e31c458e2..2807c460406 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -106,15 +106,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "arbitrary" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" -dependencies = [ - "derive_arbitrary", -] - [[package]] name = "arrayref" version = "0.3.9" @@ -314,9 +305,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.42" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" dependencies = [ "iana-time-zone", "num-traits", @@ -367,9 +358,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" [[package]] name = "clap_mangen" @@ -390,7 +381,7 @@ dependencies = [ "anyhow", "cc", "colored", - "getrandom 0.2.16", + "getrandom 0.2.17", "glob", "libc", "nix", @@ -497,7 +488,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "once_cell", "tiny-keccak", ] @@ -877,17 +868,6 @@ dependencies = [ "powerfmt", ] -[[package]] -name = "derive_arbitrary" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "derive_more" version = "2.1.1" @@ -1105,13 +1085,13 @@ dependencies = [ [[package]] name = "flate2" -version = "1.1.5" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" +checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369" dependencies = [ "crc32fast", - "libz-rs-sys", "miniz_oxide", + "zlib-rs", ] [[package]] @@ -1263,9 +1243,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "libc", @@ -1461,9 +1441,9 @@ dependencies = [ [[package]] name = "icu_locale_data" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03e2fcaefecdf05619f3d6f91740e79ab969b4dd54f77cbf546b1d0d28e3147" +checksum = "1c5f1d16b4c3a2642d3a719f18f6b06070ab0aef246a6418130c955ae08aa831" [[package]] name = "icu_normalizer" @@ -1666,9 +1646,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.83" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" dependencies = [ "once_cell", "wasm-bindgen", @@ -1742,15 +1722,6 @@ dependencies = [ "redox_syscall 0.7.0", ] -[[package]] -name = "libz-rs-sys" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c10501e7805cee23da17c7790e59df2870c0d4043ec6d03f67d31e2b53e77415" -dependencies = [ - "zlib-rs", -] - [[package]] name = "linux-raw-sys" version = "0.11.0" @@ -2353,7 +2324,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", ] [[package]] @@ -4410,9 +4381,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" dependencies = [ "cfg-if", "once_cell", @@ -4423,9 +4394,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4433,9 +4404,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" dependencies = [ "bumpalo", "proc-macro2", @@ -4446,9 +4417,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" dependencies = [ "unicode-ident", ] @@ -4939,9 +4910,9 @@ checksum = "40990edd51aae2c2b6907af74ffb635029d5788228222c4bb811e9351c0caad3" [[package]] name = "zmij" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fc5a66a20078bf1251bde995aa2fdcc4b800c70b5d92dd2c62abc5c60f679f8" +checksum = "bd8f3f50b848df28f887acb68e41201b5aea6bc8a8dacc00fb40635ff9a72fea" [[package]] name = "zopfli"