mirror of
https://github.com/mikefarah/yq.git
synced 2026-07-02 10:31:40 +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
|
||||
)
|
||||
|
||||
// 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 {
|
||||
var node = &CandidateNode{Kind: ScalarNode}
|
||||
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.
|
||||
EvaluateTogether bool
|
||||
IsMapKey bool
|
||||
// For formats like HCL and TOML: indicates that child entries should be emitted as separate blocks/tables
|
||||
// rather than consolidated into nested mappings (default behaviour)
|
||||
EncodeSeparate bool
|
||||
// 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
|
||||
// EncodeHint controls how a mapping node is serialised by format-specific encoders
|
||||
// (e.g. TOML, HCL) that support both inline and block/section representations.
|
||||
EncodeHint EncodeHint
|
||||
}
|
||||
|
||||
func (n *CandidateNode) CreateChild() *CandidateNode {
|
||||
@ -414,8 +427,7 @@ func (n *CandidateNode) doCopy(cloneContent bool) *CandidateNode {
|
||||
EvaluateTogether: n.EvaluateTogether,
|
||||
IsMapKey: n.IsMapKey,
|
||||
|
||||
EncodeSeparate: n.EncodeSeparate,
|
||||
TomlInline: n.TomlInline,
|
||||
EncodeHint: n.EncodeHint,
|
||||
}
|
||||
|
||||
if cloneContent {
|
||||
@ -469,10 +481,8 @@ func (n *CandidateNode) UpdateAttributesFrom(other *CandidateNode, prefs assignP
|
||||
n.Anchor = other.Anchor
|
||||
}
|
||||
|
||||
// Preserve EncodeSeparate flag for format-specific encoding hints
|
||||
n.EncodeSeparate = other.EncodeSeparate
|
||||
// Preserve TomlInline flag for TOML inline table round-trips
|
||||
n.TomlInline = other.TomlInline
|
||||
// Preserve EncodeHint for format-specific encoding hints
|
||||
n.EncodeHint = other.EncodeHint
|
||||
|
||||
// merge will pickup the style of the new thing
|
||||
// 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
|
||||
// This tells the encoder to emit them as separate blocks rather than consolidating them
|
||||
if isMultipleBlocksOfType {
|
||||
typeNode.EncodeSeparate = true
|
||||
typeNode.EncodeHint = EncodeHintSeparateBlock
|
||||
}
|
||||
}
|
||||
current = typeNode
|
||||
|
||||
@ -152,7 +152,7 @@ func (dec *tomlDecoder) createInlineTableMap(tomlNode *toml.Node) (*CandidateNod
|
||||
return &CandidateNode{
|
||||
Kind: MappingNode,
|
||||
Tag: "!!map",
|
||||
TomlInline: true,
|
||||
EncodeHint: EncodeHintInline,
|
||||
Content: content,
|
||||
}, nil
|
||||
}
|
||||
@ -346,10 +346,10 @@ func (dec *tomlDecoder) processTable(currentNode *toml.Node) (bool, error) {
|
||||
}
|
||||
|
||||
tableNodeValue := &CandidateNode{
|
||||
Kind: MappingNode,
|
||||
Tag: "!!map",
|
||||
Content: make([]*CandidateNode, 0),
|
||||
EncodeSeparate: true,
|
||||
Kind: MappingNode,
|
||||
Tag: "!!map",
|
||||
Content: make([]*CandidateNode, 0),
|
||||
EncodeHint: EncodeHintSeparateBlock,
|
||||
}
|
||||
|
||||
// Attach pending head comments to the table
|
||||
@ -443,9 +443,9 @@ func (dec *tomlDecoder) processArrayTable(currentNode *toml.Node) (bool, error)
|
||||
hasValue := dec.parser.NextExpression()
|
||||
|
||||
tableNodeValue := &CandidateNode{
|
||||
Kind: MappingNode,
|
||||
Tag: "!!map",
|
||||
EncodeSeparate: true,
|
||||
Kind: MappingNode,
|
||||
Tag: "!!map",
|
||||
EncodeHint: EncodeHintSeparateBlock,
|
||||
}
|
||||
|
||||
// Attach pending head comments to the array table
|
||||
|
||||
@ -449,8 +449,8 @@ func (he *hclEncoder) encodeBlockIfMapping(body *hclwrite.Body, key string, valu
|
||||
return false
|
||||
}
|
||||
|
||||
// If EncodeSeparate is set, emit children as separate blocks regardless of label extraction
|
||||
if valueNode.EncodeSeparate {
|
||||
// If EncodeHintSeparateBlock is set, emit children as separate blocks regardless of label extraction
|
||||
if valueNode.EncodeHint == EncodeHintSeparateBlock {
|
||||
if handled, _ := he.encodeMappingChildrenAsBlocks(body, key, valueNode); handled {
|
||||
return true
|
||||
}
|
||||
@ -537,9 +537,9 @@ func (he *hclEncoder) encodeMappingChildrenAsBlocks(body *hclwrite.Body, blockTy
|
||||
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
|
||||
if !valueNode.EncodeSeparate {
|
||||
if valueNode.EncodeHint != EncodeHintSeparateBlock {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
|
||||
@ -164,7 +164,7 @@ func (te *tomlEncoder) encodeTopLevelEntry(w io.Writer, path []string, node *Can
|
||||
case MappingNode:
|
||||
// Use inline table syntax for nodes explicitly marked as TOML inline tables
|
||||
// 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.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.
|
||||
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).
|
||||
// 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
|
||||
for i := 0; i < len(m.Content); i += 2 {
|
||||
v := m.Content[i+1]
|
||||
@ -435,7 +435,7 @@ func (te *tomlEncoder) encodeSeparateMapping(w io.Writer, path []string, m *Cand
|
||||
hasAttrs = true
|
||||
break
|
||||
}
|
||||
if v.Kind == MappingNode && (v.TomlInline || v.Style&FlowStyle != 0) {
|
||||
if v.Kind == MappingNode && (v.EncodeHint == EncodeHintInline || v.Style&FlowStyle != 0) {
|
||||
hasAttrs = true
|
||||
break
|
||||
}
|
||||
@ -511,21 +511,11 @@ func (te *tomlEncoder) encodeSeparateMapping(w io.Writer, path []string, m *Cand
|
||||
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 {
|
||||
for i := 0; i < len(m.Content); i += 2 {
|
||||
v := m.Content[i+1]
|
||||
// Only consider it structural if mapping has EncodeSeparate or is non-empty
|
||||
if v.Kind == MappingNode && v.EncodeSeparate {
|
||||
// Only consider it structural if mapping has EncodeHintSeparateBlock or is non-empty
|
||||
if v.Kind == MappingNode && v.EncodeHint == EncodeHintSeparateBlock {
|
||||
return true
|
||||
}
|
||||
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.
|
||||
for i := 0; i < len(m.Content); i += 2 {
|
||||
k := m.Content[i].Value
|
||||
v := m.Content[i+1]
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user