Skip to content

feat(implode): add implode command — inverse of explode (#917)#3733

Merged
jqnatividad merged 6 commits into
masterfrom
implode-command
Apr 23, 2026
Merged

feat(implode): add implode command — inverse of explode (#917)#3733
jqnatividad merged 6 commits into
masterfrom
implode-command

Conversation

@jqnatividad

Copy link
Copy Markdown
Collaborator

Summary

  • Adds qsv implode as the inverse of qsv explode: groups rows by key column(s) and joins the values of a single column with a separator, producing one row per group.
  • Multi-column -k selector, single-column -v, optional -r/--rename, --skip-empty (default keeps empty tokens for lossless round-trip with explode), and --sorted streaming path for pre-sorted input (memory bounded by the largest group).
  • Registered in both qsv and qsvlite; includes generated help markdown, README/TOC entries, and MCP skill JSON.

Closes #917.

Test plan

  • cargo build --locked --bin qsv -F all_features
  • cargo build --locked --bin qsvlite -F lite
  • cargo t implode -F all_features — 14/14 pass
  • cargo t implode -F lite — 14/14 pass
  • cargo t explode -F all_features — no regression
  • cargo clippy --bin qsv -F all_features — clean
  • End-to-end smoke: printf 'name,color\nJohn,blue\nJohn,yellow\nJohn,light red\nMary,red\n' | qsv implode -k name -v color -r colors ";" produces the expected output
  • Round-trip smoke: implode ";" | explode ";" recovers the original 4 rows

Notes

Test coverage includes: basic single-key, composite key (buffered + --sorted), --rename, empty-value handling (default include + --skip-empty), --sorted streaming, --no-headers, empty input, round-trip with explode, value-column-must-be-single-column error, value-column-can't-also-be-a-key-column error, unknown key column error. Error-path tests assert the specific stderr message.

🤖 Generated with Claude Code

jqnatividad and others added 5 commits April 23, 2026 14:59
Groups rows by key column(s) and joins values of another column with a
separator. Supports multi-column -k selectors, single-column -v, -r/--rename,
--skip-empty to drop empty tokens, and --sorted for O(1)-memory streaming
on pre-sorted input. Default buffered path emits groups in first-seen order.

Closes #917.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Regenerated by 'qsv --update-mcp-skills'. No behavioral changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Tighten USAGE: --sorted is not O(1); memory is bounded by the size of
  the largest group, not the whole input.
- Extract a small key/value extraction helper; share between the sorted
  and buffered paths.
- In the buffered path, switch to std's HashMap Entry API so --skip-empty
  no longer clones the key on every hit. Satisfies clippy::map_entry while
  avoiding the allocation.
- Replace the manual join loop in write_group with <[Vec<u8>]>::join.
- Tests: add coverage for the value==key error (with stderr assertion),
  unknown key column, empty input, --sorted + --skip-empty, and --sorted
  with a composite key. Upgrade the value-multi-column test to also
  verify the stderr message.

Refresh docs/help/implode.md and MCP skill JSON for the updated USAGE.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The two composite-key tests used ',' as both the implode separator and
the CSV delimiter, which forced the joined visitor field to be quoted in
the raw output and obscured what was being asserted. Switch to '|' so
the separator is distinct from the delimiter.

Addresses review #1620.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jqnatividad jqnatividad requested a review from Copilot April 23, 2026 19:18
@codacy-production

codacy-production Bot commented Apr 23, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 52 complexity

Metric Results
Complexity 52

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

Adds a new qsv implode command (inverse of qsv explode) that groups rows by key column(s) and joins a single value column using a user-provided separator, with optional streaming support for pre-sorted input.

Changes:

  • Added implode command implementation with buffered (first-seen order) and --sorted streaming modes, plus --skip-empty and --rename.
  • Wired the command into qsv and qsvlite, and added comprehensive integration tests.
  • Updated generated help/docs, README/TOC entries, and MCP skill metadata (including new qsv-implode skill JSON).

Reviewed changes

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

Show a summary per file
File Description
tests/tests.rs Registers the new test_implode integration test module under appropriate feature flags.
tests/test_implode.rs Adds integration tests covering basic behavior, composite keys, rename, empty handling, streaming mode, and error paths.
src/mcp_skills_gen.rs Includes implode in the MCP skills generation list.
src/mainlite.rs Adds implode to qsvlite’s command list, enum, and dispatch.
src/main.rs Adds implode to qsv’s help text, enum, and dispatch.
src/cmd/mod.rs Exposes the new cmd::implode module behind the same feature gates as other lite-capable commands.
src/cmd/implode.rs Implements the implode command (group-by keys + join value column; buffered and --sorted streaming paths).
README.md Adds implode to the command list/table.
docs/help/TableOfContents.md Adds implode to generated help TOC.
docs/help/implode.md Adds generated help page for implode.
.claude/skills/qsv/qsv-blake3.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-cat.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-count.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-datefmt.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-dedup.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-describegpt.json Skill metadata version bump to 19.1.0 (plus wording tweak in option description).
.claude/skills/qsv/qsv-diff.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-enum.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-excel.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-exclude.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-explode.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-extdedup.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-extsort.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-fill.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-fixlengths.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-fmt.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-frequency.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-geocode.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-headers.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-implode.json Adds new MCP skill metadata for the implode subcommand.
.claude/skills/qsv/qsv-index.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-input.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-join.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-joinp.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-json.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-jsonl.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-luau.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-moarstats.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-partition.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-pivotp.json Skill metadata version bump to 19.1.0 (plus clarified option descriptions).
.claude/skills/qsv/qsv-pragmastat.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-pseudo.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-rename.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-replace.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-reverse.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-safenames.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-sample.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-schema.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-search.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-searchset.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-select.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-slice.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-sniff.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-sort.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-sortcheck.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-split.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-sqlp.json Skill metadata version bump to 19.1.0 (plus clarified compression option description).
.claude/skills/qsv/qsv-stats.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-table.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-template.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-to.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-tojsonl.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-transpose.json Skill metadata version bump to 19.1.0.
.claude/skills/qsv/qsv-validate.json Skill metadata version bump to 19.1.0.

Comment thread tests/test_implode.rs Outdated
Comment thread tests/test_implode.rs Outdated
Comment thread .claude/skills/qsv/qsv-implode.json Outdated
- tests: replace the `assert_err` + `output_stderr` pair in the two
  error-path tests with a single `output_stderr` call and a stderr
  assertion. `output_stderr` already runs the command; pairing it with
  `assert_err` ran each failing command twice.
- Correct the MCP skill memory hint: implode buffers all input unless
  --sorted is used, so it is 'proportional', not 'constant'. Added 😣
  to the README row so the generator emits the right hint; regenerated
  docs/help/implode.md, TableOfContents.md, and qsv-implode.json.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jqnatividad jqnatividad merged commit e34ecc0 into master Apr 23, 2026
27 checks passed
@jqnatividad jqnatividad deleted the implode-command branch April 23, 2026 19:37
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.

unfold and unfold operation

2 participants