-
-
Notifications
You must be signed in to change notification settings - Fork 756
Expand file tree
/
Copy pathencoder_ini.go
More file actions
113 lines (96 loc) · 3.11 KB
/
encoder_ini.go
File metadata and controls
113 lines (96 loc) · 3.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//go:build !yq_noini
package yqlib
import (
"bytes"
"fmt"
"io"
ini "gopkg.in/ini.v1"
)
type iniEncoder struct {
indentString string
}
// NewINIEncoder creates a new INI encoder
func NewINIEncoder() Encoder {
// Hardcoded indent value of 0, meaning no additional spacing.
return &iniEncoder{""}
}
// CanHandleAliases indicates whether the encoder supports aliases. INI does not support aliases.
func (ie *iniEncoder) CanHandleAliases() bool {
return false
}
// PrintDocumentSeparator is a no-op since INI does not support multiple documents.
func (ie *iniEncoder) PrintDocumentSeparator(_ io.Writer) error {
return nil
}
// PrintLeadingContent is a no-op since INI does not support leading content or comments at the encoder level.
func (ie *iniEncoder) PrintLeadingContent(_ io.Writer, _ string) error {
return nil
}
// Encode converts a CandidateNode into INI format and writes it to the provided writer.
func (ie *iniEncoder) Encode(writer io.Writer, node *CandidateNode) error {
log.Debugf("I need to encode %v", NodeToString(node))
log.Debugf("kids %v", len(node.Content))
if node.Kind == ScalarNode {
return writeStringINI(writer, node.Value+"\n")
}
// Create a new INI configuration.
cfg := ini.Empty()
if node.Kind == MappingNode {
// Default section for key-value pairs at the root level.
defaultSection, err := cfg.NewSection(ini.DefaultSection)
if err != nil {
return err
}
// Process the node's content.
for i := 0; i < len(node.Content); i += 2 {
keyNode := node.Content[i]
valueNode := node.Content[i+1]
key := keyNode.Value
switch valueNode.Kind {
case ScalarNode:
// Add key-value pair to the default section.
_, err := defaultSection.NewKey(key, valueNode.Value)
if err != nil {
return err
}
case MappingNode:
// Create a new section for nested MappingNode.
section, err := cfg.NewSection(key)
if err != nil {
return err
}
// Process nested key-value pairs.
for j := 0; j < len(valueNode.Content); j += 2 {
nestedKeyNode := valueNode.Content[j]
nestedValueNode := valueNode.Content[j+1]
if nestedValueNode.Kind == ScalarNode {
_, err := section.NewKey(nestedKeyNode.Value, nestedValueNode.Value)
if err != nil {
return err
}
} else {
log.Debugf("Skipping nested non-scalar value for key %s: %v", nestedKeyNode.Value, nestedValueNode.Kind)
}
}
default:
log.Debugf("Skipping non-scalar value for key %s: %v", key, valueNode.Kind)
}
}
} else {
return fmt.Errorf("INI encoder supports only MappingNode at the root level, got %v", node.Kind)
}
// Use a buffer to store the INI output as the library doesn't support direct io.Writer with indent.
var buffer bytes.Buffer
_, err := cfg.WriteToIndent(&buffer, ie.indentString)
if err != nil {
return err
}
// Write the buffer content to the provided writer.
_, err = writer.Write(buffer.Bytes())
return err
}
// writeStringINI is a helper function to write a string to the provided writer for INI encoder.
func writeStringINI(writer io.Writer, content string) error {
_, err := writer.Write([]byte(content))
return err
}