mirror of
https://github.com/mikefarah/yq.git
synced 2026-07-07 22:35:37 +00:00
Refactor EncodeSeparate+TomlInline into a single EncodeHint enum
Agent-Logs-Url: https://github.com/mikefarah/yq/sessions/24db9a8f-601d-4ccf-ada7-129ed3226bb6 Co-authored-by: mikefarah <1151925+mikefarah@users.noreply.github.com>
This commit is contained in:
parent
d1ffec12e6
commit
8c1cb6a5f0
@ -27,6 +27,22 @@ const (
|
|||||||
FlowStyle
|
FlowStyle
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// EncodeHint controls how a mapping node is serialised by format-specific encoders
|
||||||
|
// that distinguish between inline and block/section representations (e.g. TOML, HCL).
|
||||||
|
type EncodeHint int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// EncodeHintDefault lets the encoder choose the representation (e.g. TOML block
|
||||||
|
// mappings default to [section] headers).
|
||||||
|
EncodeHintDefault EncodeHint = iota
|
||||||
|
// EncodeHintSeparateBlock forces the node to be emitted as a separate block or
|
||||||
|
// table-section header (used by TOML [section] and HCL block decoders).
|
||||||
|
EncodeHintSeparateBlock
|
||||||
|
// EncodeHintInline forces the node to be emitted as an inline / flow table
|
||||||
|
// (used by TOML inline-table decoder and TOML encoder).
|
||||||
|
EncodeHintInline
|
||||||
|
)
|
||||||
|
|
||||||
func createStringScalarNode(stringValue string) *CandidateNode {
|
func createStringScalarNode(stringValue string) *CandidateNode {
|
||||||
var node = &CandidateNode{Kind: ScalarNode}
|
var node = &CandidateNode{Kind: ScalarNode}
|
||||||
node.Value = stringValue
|
node.Value = stringValue
|
||||||
@ -97,12 +113,9 @@ type CandidateNode struct {
|
|||||||
// (e.g. top level cross document merge). This property does not propagate to child nodes.
|
// (e.g. top level cross document merge). This property does not propagate to child nodes.
|
||||||
EvaluateTogether bool
|
EvaluateTogether bool
|
||||||
IsMapKey bool
|
IsMapKey bool
|
||||||
// For formats like HCL and TOML: indicates that child entries should be emitted as separate blocks/tables
|
// EncodeHint controls how a mapping node is serialised by format-specific encoders
|
||||||
// rather than consolidated into nested mappings (default behaviour)
|
// (e.g. TOML, HCL) that support both inline and block/section representations.
|
||||||
EncodeSeparate bool
|
EncodeHint EncodeHint
|
||||||
// For TOML: indicates that this mapping was originally a TOML inline table and should be
|
|
||||||
// re-encoded as an inline table rather than a separate table section.
|
|
||||||
TomlInline bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *CandidateNode) CreateChild() *CandidateNode {
|
func (n *CandidateNode) CreateChild() *CandidateNode {
|
||||||
@ -414,8 +427,7 @@ func (n *CandidateNode) doCopy(cloneContent bool) *CandidateNode {
|
|||||||
EvaluateTogether: n.EvaluateTogether,
|
EvaluateTogether: n.EvaluateTogether,
|
||||||
IsMapKey: n.IsMapKey,
|
IsMapKey: n.IsMapKey,
|
||||||
|
|
||||||
EncodeSeparate: n.EncodeSeparate,
|
EncodeHint: n.EncodeHint,
|
||||||
TomlInline: n.TomlInline,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if cloneContent {
|
if cloneContent {
|
||||||
@ -469,10 +481,8 @@ func (n *CandidateNode) UpdateAttributesFrom(other *CandidateNode, prefs assignP
|
|||||||
n.Anchor = other.Anchor
|
n.Anchor = other.Anchor
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preserve EncodeSeparate flag for format-specific encoding hints
|
// Preserve EncodeHint for format-specific encoding hints
|
||||||
n.EncodeSeparate = other.EncodeSeparate
|
n.EncodeHint = other.EncodeHint
|
||||||
// Preserve TomlInline flag for TOML inline table round-trips
|
|
||||||
n.TomlInline = other.TomlInline
|
|
||||||
|
|
||||||
// merge will pickup the style of the new thing
|
// merge will pickup the style of the new thing
|
||||||
// when autocreating nodes
|
// when autocreating nodes
|
||||||
|
|||||||
@ -226,7 +226,7 @@ func addBlockToMapping(parent *CandidateNode, block *hclsyntax.Block, src []byte
|
|||||||
// Mark the type node if there are multiple blocks of this type at this level
|
// Mark the type node if there are multiple blocks of this type at this level
|
||||||
// This tells the encoder to emit them as separate blocks rather than consolidating them
|
// This tells the encoder to emit them as separate blocks rather than consolidating them
|
||||||
if isMultipleBlocksOfType {
|
if isMultipleBlocksOfType {
|
||||||
typeNode.EncodeSeparate = true
|
typeNode.EncodeHint = EncodeHintSeparateBlock
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current = typeNode
|
current = typeNode
|
||||||
|
|||||||
@ -152,7 +152,7 @@ func (dec *tomlDecoder) createInlineTableMap(tomlNode *toml.Node) (*CandidateNod
|
|||||||
return &CandidateNode{
|
return &CandidateNode{
|
||||||
Kind: MappingNode,
|
Kind: MappingNode,
|
||||||
Tag: "!!map",
|
Tag: "!!map",
|
||||||
TomlInline: true,
|
EncodeHint: EncodeHintInline,
|
||||||
Content: content,
|
Content: content,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@ -349,7 +349,7 @@ func (dec *tomlDecoder) processTable(currentNode *toml.Node) (bool, error) {
|
|||||||
Kind: MappingNode,
|
Kind: MappingNode,
|
||||||
Tag: "!!map",
|
Tag: "!!map",
|
||||||
Content: make([]*CandidateNode, 0),
|
Content: make([]*CandidateNode, 0),
|
||||||
EncodeSeparate: true,
|
EncodeHint: EncodeHintSeparateBlock,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach pending head comments to the table
|
// Attach pending head comments to the table
|
||||||
@ -445,7 +445,7 @@ func (dec *tomlDecoder) processArrayTable(currentNode *toml.Node) (bool, error)
|
|||||||
tableNodeValue := &CandidateNode{
|
tableNodeValue := &CandidateNode{
|
||||||
Kind: MappingNode,
|
Kind: MappingNode,
|
||||||
Tag: "!!map",
|
Tag: "!!map",
|
||||||
EncodeSeparate: true,
|
EncodeHint: EncodeHintSeparateBlock,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach pending head comments to the array table
|
// Attach pending head comments to the array table
|
||||||
|
|||||||
@ -449,8 +449,8 @@ func (he *hclEncoder) encodeBlockIfMapping(body *hclwrite.Body, key string, valu
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// If EncodeSeparate is set, emit children as separate blocks regardless of label extraction
|
// If EncodeHintSeparateBlock is set, emit children as separate blocks regardless of label extraction
|
||||||
if valueNode.EncodeSeparate {
|
if valueNode.EncodeHint == EncodeHintSeparateBlock {
|
||||||
if handled, _ := he.encodeMappingChildrenAsBlocks(body, key, valueNode); handled {
|
if handled, _ := he.encodeMappingChildrenAsBlocks(body, key, valueNode); handled {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -537,9 +537,9 @@ func (he *hclEncoder) encodeMappingChildrenAsBlocks(body *hclwrite.Body, blockTy
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only emit as separate blocks if EncodeSeparate is true
|
// Only emit as separate blocks if EncodeHintSeparateBlock is set
|
||||||
// This allows the encoder to respect the original block structure preserved by the decoder
|
// This allows the encoder to respect the original block structure preserved by the decoder
|
||||||
if !valueNode.EncodeSeparate {
|
if valueNode.EncodeHint != EncodeHintSeparateBlock {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -164,7 +164,7 @@ func (te *tomlEncoder) encodeTopLevelEntry(w io.Writer, path []string, node *Can
|
|||||||
case MappingNode:
|
case MappingNode:
|
||||||
// Use inline table syntax for nodes explicitly marked as TOML inline tables
|
// Use inline table syntax for nodes explicitly marked as TOML inline tables
|
||||||
// or YAML flow mappings. All other mappings become readable TOML table sections.
|
// or YAML flow mappings. All other mappings become readable TOML table sections.
|
||||||
if node.TomlInline || node.Style&FlowStyle != 0 {
|
if node.EncodeHint == EncodeHintInline || node.Style&FlowStyle != 0 {
|
||||||
return te.writeInlineTableAttribute(w, path[len(path)-1], node)
|
return te.writeInlineTableAttribute(w, path[len(path)-1], node)
|
||||||
}
|
}
|
||||||
return te.encodeSeparateMapping(w, path, node)
|
return te.encodeSeparateMapping(w, path, node)
|
||||||
@ -427,7 +427,7 @@ func (te *tomlEncoder) writeTableHeader(w io.Writer, path []string, m *Candidate
|
|||||||
// It emits the table header for this mapping if it has any content, then processes children.
|
// It emits the table header for this mapping if it has any content, then processes children.
|
||||||
func (te *tomlEncoder) encodeSeparateMapping(w io.Writer, path []string, m *CandidateNode) error {
|
func (te *tomlEncoder) encodeSeparateMapping(w io.Writer, path []string, m *CandidateNode) error {
|
||||||
// Check if this mapping has any non-mapping, non-array-of-tables children (i.e., attributes).
|
// Check if this mapping has any non-mapping, non-array-of-tables children (i.e., attributes).
|
||||||
// TomlInline mapping children also count as attributes since they render as key = { ... }.
|
// Inline mapping children also count as attributes since they render as key = { ... }.
|
||||||
hasAttrs := false
|
hasAttrs := false
|
||||||
for i := 0; i < len(m.Content); i += 2 {
|
for i := 0; i < len(m.Content); i += 2 {
|
||||||
v := m.Content[i+1]
|
v := m.Content[i+1]
|
||||||
@ -435,7 +435,7 @@ func (te *tomlEncoder) encodeSeparateMapping(w io.Writer, path []string, m *Cand
|
|||||||
hasAttrs = true
|
hasAttrs = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if v.Kind == MappingNode && (v.TomlInline || v.Style&FlowStyle != 0) {
|
if v.Kind == MappingNode && (v.EncodeHint == EncodeHintInline || v.Style&FlowStyle != 0) {
|
||||||
hasAttrs = true
|
hasAttrs = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -511,21 +511,11 @@ func (te *tomlEncoder) encodeSeparateMapping(w io.Writer, path []string, m *Cand
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (te *tomlEncoder) hasEncodeSeparateChild(m *CandidateNode) bool {
|
|
||||||
for i := 0; i < len(m.Content); i += 2 {
|
|
||||||
v := m.Content[i+1]
|
|
||||||
if v.Kind == MappingNode && v.EncodeSeparate {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (te *tomlEncoder) hasStructuralChildren(m *CandidateNode) bool {
|
func (te *tomlEncoder) hasStructuralChildren(m *CandidateNode) bool {
|
||||||
for i := 0; i < len(m.Content); i += 2 {
|
for i := 0; i < len(m.Content); i += 2 {
|
||||||
v := m.Content[i+1]
|
v := m.Content[i+1]
|
||||||
// Only consider it structural if mapping has EncodeSeparate or is non-empty
|
// Only consider it structural if mapping has EncodeHintSeparateBlock or is non-empty
|
||||||
if v.Kind == MappingNode && v.EncodeSeparate {
|
if v.Kind == MappingNode && v.EncodeHint == EncodeHintSeparateBlock {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if v.Kind == SequenceNode {
|
if v.Kind == SequenceNode {
|
||||||
@ -597,13 +587,13 @@ func (te *tomlEncoder) encodeMappingBodyWithPath(w io.Writer, path []string, m *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, child mappings: TomlInline or flow-style ones become inline table attributes,
|
// Finally, child mappings: inline-hint or flow-style ones become inline table attributes,
|
||||||
// while all others are emitted as separate sub-table sections.
|
// while all others are emitted as separate sub-table sections.
|
||||||
for i := 0; i < len(m.Content); i += 2 {
|
for i := 0; i < len(m.Content); i += 2 {
|
||||||
k := m.Content[i].Value
|
k := m.Content[i].Value
|
||||||
v := m.Content[i+1]
|
v := m.Content[i+1]
|
||||||
if v.Kind == MappingNode {
|
if v.Kind == MappingNode {
|
||||||
if v.TomlInline || v.Style&FlowStyle != 0 {
|
if v.EncodeHint == EncodeHintInline || v.Style&FlowStyle != 0 {
|
||||||
if err := te.writeInlineTableAttribute(w, k, v); err != nil {
|
if err := te.writeInlineTableAttribute(w, k, v); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user