Skip to content

sortcheck: review-driven cleanup, add --numeric/--natural, allocation-free streaming loop#3756

Merged
jqnatividad merged 2 commits into
masterfrom
sortcheck-review-202604
Apr 27, 2026
Merged

sortcheck: review-driven cleanup, add --numeric/--natural, allocation-free streaming loop#3756
jqnatividad merged 2 commits into
masterfrom
sortcheck-review-202604

Conversation

@jqnatividad

Copy link
Copy Markdown
Collaborator

Summary

Brings sortcheck in line with the recent review-driven cleanups for sort (#3755), dedup (#3754), datefmt (#3753), and util (#3752), and closes a real feature gap.

  • Feature: sortcheck previously only supported lex / --ignore-case, so users could not pre-verify a CSV before piping into sort --numeric, sort --natural, or dedup --numeric --sorted. Adds --numeric (-N) and --natural, reusing iter_cmp_num, iter_cmp_natural, and iter_cmp_natural_ignore_case already exported from cmd/sort.rs — no new comparators.
  • Resolution: flags resolve into a ComparisonMode enum once before the loop, with the same precedence as sort/dedup: --natural > --numeric > --ignore-case. Dispatch is a single match per row that monomorphizes to one comparator.
  • Allocation hygiene: record.clone_from(&next_record)std::mem::swap(...) on both Less and Greater arms — zero-copy buffer rotation, matching dedup dedup: review-driven cleanup, allocation-free ignore-case, edge-case fixes #3754.
  • Misc cleanup:
    • args.flag_json | args.flag_pretty_json|| (idiomatic logical OR).
    • dupe_count as i64i64::try_from(...).unwrap_or(i64::MAX) with a comment on why -1 signals "not applicable".
    • Dropped stale #[allow(dead_code)] on Args.
    • Comment on the do_json-forces-full-scan invariant that makes scan_ctr equivalent to record_count in the JSON path.
  • Docs: USAGE updated with the new flags + precedence + an Examples block; the extsort paragraph tightened (sort itself is now multi-threaded). docs/help/sortcheck.md regenerated via qsv --generate-help-md.

Test plan

  • cargo test sortcheck -F all_features19/19 pass (10 new + 9 existing).
  • cargo clippy --bin qsv -F all_features -- -D warnings — clean.
  • cargo build --bin qsv -F all_features — clean.
  • Help-doc regeneration verified: docs/help/sortcheck.md reflects the new flags.
  • New tests added: --ignore-case sorted/unsorted (incl. a real lex-vs-ignore-case discriminator), empty input, single-row input, --numeric sorted/unsorted, --natural sorted/unsorted, --natural + --ignore-case composition, and a precedence test confirming --natural overrides --numeric.
  • Manual smoke after merge:
    • printf 'n\n10\n2\n30\n' | qsv sortcheck -n → exit 1 (lex unsorted)
    • printf 'n\n2\n10\n30\n' | qsv sortcheck -n --numeric → exit 0
    • printf 'n\nitem1\nitem2\nitem10\n' | qsv sortcheck -n --natural --json → sorted JSON, exit 0

🤖 Generated with Claude Code

…-free streaming loop

Bring sortcheck in line with the recent review-driven cleanups for sort
(#3755), dedup (#3754), datefmt (#3753), and util (#3752), and close a
real feature gap: sortcheck previously only supported lex / --ignore-case,
so users could not pre-verify a CSV before piping into `sort --numeric`,
`sort --natural`, or `dedup --numeric --sorted`.

Changes
- Add --numeric (-N) and --natural flags, reusing iter_cmp_num,
  iter_cmp_natural, and iter_cmp_natural_ignore_case already exported
  from cmd/sort.rs (no new comparators).
- Resolve flags into a ComparisonMode enum once before the loop, with
  the same precedence as sort/dedup: --natural > --numeric > --ignore-case.
  Dispatch is a single match per row, monomorphizing to one comparator.
- Replace record.clone_from(&next_record) with std::mem::swap on both
  Less and Greater arms — zero-copy buffer rotation, matching dedup #3754.
- args.flag_json | args.flag_pretty_json -> || (idiomatic logical OR).
- dupe_count as i64 -> i64::try_from(...).unwrap_or(i64::MAX) with a
  comment on why -1 signals "not applicable".
- Drop stale #[allow(dead_code)] on Args; add a comment on the
  do_json-forces-full-scan invariant that makes scan_ctr equivalent to
  record_count in the JSON path.
- USAGE: documented the new flags + their precedence, added an Examples
  block, tightened the extsort paragraph (sort itself is multi-threaded).
- Regenerated docs/help/sortcheck.md via `qsv --generate-help-md`.

Tests
- 10 new tests in tests/test_sortcheck.rs covering --ignore-case
  (including a real lex-vs-ignore-case discriminator), empty input,
  single-row input, --numeric sorted/unsorted, --natural sorted/unsorted,
  --natural + --ignore-case composition, and a precedence test
  confirming --natural overrides --numeric.
- 19/19 sortcheck tests pass; `cargo clippy -F all_features -- -D warnings` clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codacy-production

codacy-production Bot commented Apr 27, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 15 complexity

Metric Results
Complexity 15

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR upgrades sortcheck to support the same comparison modes as sort/dedup (notably --numeric and --natural), while also tightening the streaming loop to reduce allocations and updating tests/docs accordingly.

Changes:

  • Add --numeric (-N) and --natural comparison modes (with the same precedence rules as sort/dedup).
  • Replace clone_from with std::mem::swap in the streaming loop to avoid per-row buffer copies.
  • Expand sortcheck tests and regenerate docs/help/sortcheck.md to cover the new flags and examples.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
src/cmd/sortcheck.rs Adds numeric/natural comparison dispatch and allocation-free record rotation; updates USAGE/docs text.
tests/test_sortcheck.rs Adds new cases for ignore-case, empty/single-row inputs, numeric/natural checks, and precedence.
docs/help/sortcheck.md Regenerated help markdown to reflect new flags, precedence, and examples.

Comment thread src/cmd/sortcheck.rs Outdated
Comment thread src/cmd/sortcheck.rs Outdated
Comment thread src/cmd/sortcheck.rs Outdated
Comment thread tests/test_sortcheck.rs Outdated
Comment thread tests/test_sortcheck.rs Outdated
…omparisonMode Copy, test rename

- Fix empty-input bug: a header-only CSV used to report
  `record_count: 1` because the loop incremented scan_ctr once even when
  the initial read_byte_record returned false. Guard the loop and
  simplify the JSON path to always use scan_ctr (do_json forces a full
  scan, so it's authoritative).
- Reword the --ignore-case USAGE block so no continuation line begins
  with `--natural` (docopt scans for option-like prefixes; lines starting
  with `--` could be misinterpreted as a second option definition).
- Also clarify the wording: --ignore-case is only ignored under PURE
  numeric comparison (--numeric without --natural), since the documented
  precedence allows --natural --numeric --ignore-case where ignore-case
  does apply.
- Derive Clone/Copy on ComparisonMode to mirror SortMode in cmd/sort.rs.
  Functionally a no-op (matching unit variants doesn't move), but
  defensive and consistent with sort.rs.
- Rename test sortcheck_ignore_case_sorted -> sortcheck_ignore_case_notsorted
  (the test asserts an error; the prior name was misleading — the
  truly-sorted-under-ignore-case case is covered by
  sortcheck_ignore_case_actually_sorted).
- Update sortcheck_empty test to expect record_count: 0 (was 1, codifying
  the off-by-one).
- Regenerated docs/help/sortcheck.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jqnatividad jqnatividad merged commit a63d458 into master Apr 27, 2026
15 of 16 checks passed
@jqnatividad jqnatividad deleted the sortcheck-review-202604 branch April 27, 2026 01:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants