Skip to content

TOML encoder: prefer readable table sections over inline tables#2649

Draft
Copilot wants to merge 3 commits intomasterfrom
copilot/featurereadable-toml-output
Draft

TOML encoder: prefer readable table sections over inline tables#2649
Copilot wants to merge 3 commits intomasterfrom
copilot/featurereadable-toml-output

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 6, 2026

When encoding to TOML from YAML/JSON, nested mappings were collapsed into compact inline table syntax (key = { ... }) instead of idiomatic TOML table sections ([key]). This affected both direct YAML→TOML conversion and round-trips through YAML.

Changes

Encoder (encoder_toml.go)

  • encodeTopLevelEntry: Check TomlInline/FlowStyle — only nodes marked as inline stay inline; all block mappings become table sections
  • encodeSeparateMapping: Count TomlInline/FlowStyle mapping children as hasAttrs (they render as key = { ... }); use recursive encodeSeparateMapping in the "no attrs" loop
  • encodeMappingBodyWithPath: Emit non-inline child mappings as sub-table sections ([parent.child]) instead of inline tables

Decoder (decoder_toml.go)

  • Set TomlInline: true on decoded TOML inline tables, distinguishing them from block mappings so they survive re-encoding as inline

Core (candidate_node.go)

  • Added TomlInline bool field to CandidateNode — a TOML-specific marker invisible to the YAML encoder, copied by UpdateAttributesFrom so it survives DeeplyAssign deep-merges

Tests (toml_test.go)

  • Add encode scenario type (YAML→TOML) and coverage for table section output
  • TOML roundtrip tests preserved: inline tables stay inline, table sections stay as sections

Before / After

# input YAML
arg:
  hello: foo
# before
arg = { hello = "foo" }

# after
[arg]
hello = "foo"

YAML flow mappings (arg: {hello: foo}) and TOML inline tables are preserved as TOML inline tables, respecting the author's explicit style intent. TOML table sections and YAML block mappings both produce readable [section] headers.

When converting from YAML/JSON to TOML, the encoder now always uses
readable TOML table section syntax ([section]) instead of compact inline
hash table syntax (key = { ... }), which better matches TOML's goal as
a human-focused configuration format.

Changes:
- decoder_toml.go: Mark inline TOML tables with FlowStyle so round-trips
  can be distinguished from YAML flow mappings
- encoder_toml.go:
  - encodeTopLevelEntry: use FlowStyle check instead of EncodeSeparate to
    decide inline vs table section (all block mappings now become tables)
  - encodeSeparateMapping: count FlowStyle children as attributes; use
    recursive encodeSeparateMapping for nested non-flow mappings
  - encodeMappingBodyWithPath: emit non-flow child mappings as sub-table
    sections instead of inline tables
- toml_test.go: add encode (YAML→TOML) test scenarios, update roundtrip
  expectations for inline tables (now expanded to table sections)

Agent-Logs-Url: https://github.com/mikefarah/yq/sessions/4824a219-6d5e-42e7-bca1-a8a277bf8c6a

Co-authored-by: mikefarah <1151925+mikefarah@users.noreply.github.com>
Copilot AI changed the title [WIP] Add support for readable TOML output in yq TOML encoder: prefer readable table sections over inline tables Apr 6, 2026
Copilot AI requested a review from mikefarah April 6, 2026 10:01
input: rtInlineTableAttr,
expression: ".",
expected: rtInlineTableAttr,
expected: rtInlineTableAttrEncoded,
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@copilot the point of the roundtrip tests is to maintain the format as much as possible...this no longer does that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in d1ffec1. The root cause was that FlowStyle (used in the previous commit to mark inline tables) also affects the YAML encoder, which was changing the TOML→YAML decode output.

The fix introduces a new TomlInline bool field on CandidateNode — TOML-specific and invisible to the YAML encoder. The TOML decoder sets it for inline tables, UpdateAttributesFrom propagates it through DeeplyAssign merges, and the TOML encoder checks it to decide inline vs table-section output.

TOML roundtrip tests are restored to their original expected values: inline tables stay inline, table sections stay as table sections.

…rve inline tables

FlowStyle affected YAML decode output (causing inline tables to appear as
YAML flow mappings). Replace it with a new TOML-specific TomlInline bool
on CandidateNode that:
- Is set by the TOML decoder for inline tables (not FlowStyle)
- Is copied by UpdateAttributesFrom so it survives DeeplyAssign merges
- Is checked by the TOML encoder alongside FlowStyle (for YAML flow maps)
- Has no effect on the YAML encoder, preserving existing TOML→YAML output

TOML roundtrip tests are restored to their original expected values (inline
tables stay inline, table sections stay as sections).

Agent-Logs-Url: https://github.com/mikefarah/yq/sessions/f59bdf62-6d16-4664-991b-38eb87c9d81c

Co-authored-by: mikefarah <1151925+mikefarah@users.noreply.github.com>
Copilot AI requested a review from mikefarah April 8, 2026 07:08
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.

yq TOML output prioritizes compact hash table syntax over readability

2 participants