--- a/vendor/github.com/pelletier/go-toml/tomltree_write.go Mon Jun 07 20:58:18 2021 +0200
+++ b/vendor/github.com/pelletier/go-toml/tomltree_write.go Sun Jul 11 10:35:56 2021 +0200
@@ -28,23 +28,35 @@
// Encodes a string to a TOML-compliant multi-line string value
// This function is a clone of the existing encodeTomlString function, except that whitespace characters
// are preserved. Quotation marks and backslashes are also not escaped.
-func encodeMultilineTomlString(value string) string {
+func encodeMultilineTomlString(value string, commented string) string {
var b bytes.Buffer
+ adjacentQuoteCount := 0
- for _, rr := range value {
+ b.WriteString(commented)
+ for i, rr := range value {
+ if rr != '"' {
+ adjacentQuoteCount = 0
+ } else {
+ adjacentQuoteCount++
+ }
switch rr {
case '\b':
b.WriteString(`\b`)
case '\t':
b.WriteString("\t")
case '\n':
- b.WriteString("\n")
+ b.WriteString("\n" + commented)
case '\f':
b.WriteString(`\f`)
case '\r':
b.WriteString("\r")
case '"':
- b.WriteString(`"`)
+ if adjacentQuoteCount >= 3 || i == len(value)-1 {
+ adjacentQuoteCount = 0
+ b.WriteString(`\"`)
+ } else {
+ b.WriteString(`"`)
+ }
case '\\':
b.WriteString(`\`)
default:
@@ -91,7 +103,30 @@
return b.String()
}
-func tomlValueStringRepresentation(v interface{}, indent string, arraysOneElementPerLine bool) (string, error) {
+func tomlTreeStringRepresentation(t *Tree, ord MarshalOrder) (string, error) {
+ var orderedVals []sortNode
+ switch ord {
+ case OrderPreserve:
+ orderedVals = sortByLines(t)
+ default:
+ orderedVals = sortAlphabetical(t)
+ }
+
+ var values []string
+ for _, node := range orderedVals {
+ k := node.key
+ v := t.values[k]
+
+ repr, err := tomlValueStringRepresentation(v, "", "", ord, false)
+ if err != nil {
+ return "", err
+ }
+ values = append(values, quoteKeyIfNeeded(k)+" = "+repr)
+ }
+ return "{ " + strings.Join(values, ", ") + " }", nil
+}
+
+func tomlValueStringRepresentation(v interface{}, commented string, indent string, ord MarshalOrder, arraysOneElementPerLine bool) (string, error) {
// this interface check is added to dereference the change made in the writeTo function.
// That change was made to allow this function to see formatting options.
tv, ok := v.(*tomlValue)
@@ -123,12 +158,20 @@
return strings.ToLower(strconv.FormatFloat(value, 'f', -1, bits)), nil
case string:
if tv.multiline {
- return "\"\"\"\n" + encodeMultilineTomlString(value) + "\"\"\"", nil
+ if tv.literal {
+ b := strings.Builder{}
+ b.WriteString("'''\n")
+ b.Write([]byte(value))
+ b.WriteString("\n'''")
+ return b.String(), nil
+ } else {
+ return "\"\"\"\n" + encodeMultilineTomlString(value, commented) + "\"\"\"", nil
+ }
}
return "\"" + encodeTomlString(value) + "\"", nil
case []byte:
b, _ := v.([]byte)
- return tomlValueStringRepresentation(string(b), indent, arraysOneElementPerLine)
+ return string(b), nil
case bool:
if value {
return "true", nil
@@ -142,6 +185,8 @@
return value.String(), nil
case LocalTime:
return value.String(), nil
+ case *Tree:
+ return tomlTreeStringRepresentation(value, ord)
case nil:
return "", nil
}
@@ -152,7 +197,7 @@
var values []string
for i := 0; i < rv.Len(); i++ {
item := rv.Index(i).Interface()
- itemRepr, err := tomlValueStringRepresentation(item, indent, arraysOneElementPerLine)
+ itemRepr, err := tomlValueStringRepresentation(item, commented, indent, ord, arraysOneElementPerLine)
if err != nil {
return "", err
}
@@ -166,22 +211,24 @@
for _, value := range values {
stringBuffer.WriteString(valueIndent)
- stringBuffer.WriteString(value)
+ stringBuffer.WriteString(commented + value)
stringBuffer.WriteString(`,`)
stringBuffer.WriteString("\n")
}
- stringBuffer.WriteString(indent + "]")
+ stringBuffer.WriteString(indent + commented + "]")
return stringBuffer.String(), nil
}
- return "[" + strings.Join(values, ",") + "]", nil
+ return "[" + strings.Join(values, ", ") + "]", nil
}
return "", fmt.Errorf("unsupported value type %T: %v", v, v)
}
func getTreeArrayLine(trees []*Tree) (line int) {
- // get lowest line number that is not 0
+ // Prevent returning 0 for empty trees
+ line = int(^uint(0) >> 1)
+ // get lowest line number >= 0
for _, tv := range trees {
if tv.position.Line < line || line == 0 {
line = tv.position.Line
@@ -270,10 +317,10 @@
}
func (t *Tree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64, arraysOneElementPerLine bool) (int64, error) {
- return t.writeToOrdered(w, indent, keyspace, bytesCount, arraysOneElementPerLine, OrderAlphabetical)
+ return t.writeToOrdered(w, indent, keyspace, bytesCount, arraysOneElementPerLine, OrderAlphabetical, " ", false, false)
}
-func (t *Tree) writeToOrdered(w io.Writer, indent, keyspace string, bytesCount int64, arraysOneElementPerLine bool, ord marshalOrder) (int64, error) {
+func (t *Tree) writeToOrdered(w io.Writer, indent, keyspace string, bytesCount int64, arraysOneElementPerLine bool, ord MarshalOrder, indentString string, compactComments, parentCommented bool) (int64, error) {
var orderedVals []sortNode
switch ord {
@@ -289,14 +336,10 @@
k := node.key
v := t.values[k]
- combinedKey := k
+ combinedKey := quoteKeyIfNeeded(k)
if keyspace != "" {
combinedKey = keyspace + "." + combinedKey
}
- var commented string
- if t.commented {
- commented = "# "
- }
switch node := v.(type) {
// node has to be of those two types given how keys are sorted above
@@ -317,24 +360,33 @@
return bytesCount, errc
}
}
+
+ var commented string
+ if parentCommented || t.commented || tv.commented {
+ commented = "# "
+ }
writtenBytesCount, err := writeStrings(w, "\n", indent, commented, "[", combinedKey, "]\n")
bytesCount += int64(writtenBytesCount)
if err != nil {
return bytesCount, err
}
- bytesCount, err = node.writeToOrdered(w, indent+" ", combinedKey, bytesCount, arraysOneElementPerLine, ord)
+ bytesCount, err = node.writeToOrdered(w, indent+indentString, combinedKey, bytesCount, arraysOneElementPerLine, ord, indentString, compactComments, parentCommented || t.commented || tv.commented)
if err != nil {
return bytesCount, err
}
case []*Tree:
for _, subTree := range node {
+ var commented string
+ if parentCommented || t.commented || subTree.commented {
+ commented = "# "
+ }
writtenBytesCount, err := writeStrings(w, "\n", indent, commented, "[[", combinedKey, "]]\n")
bytesCount += int64(writtenBytesCount)
if err != nil {
return bytesCount, err
}
- bytesCount, err = subTree.writeToOrdered(w, indent+" ", combinedKey, bytesCount, arraysOneElementPerLine, ord)
+ bytesCount, err = subTree.writeToOrdered(w, indent+indentString, combinedKey, bytesCount, arraysOneElementPerLine, ord, indentString, compactComments, parentCommented || t.commented || subTree.commented)
if err != nil {
return bytesCount, err
}
@@ -347,7 +399,11 @@
return bytesCount, fmt.Errorf("invalid value type at %s: %T", k, t.values[k])
}
- repr, err := tomlValueStringRepresentation(v, indent, arraysOneElementPerLine)
+ var commented string
+ if parentCommented || t.commented || v.commented {
+ commented = "# "
+ }
+ repr, err := tomlValueStringRepresentation(v, commented, indent, ord, arraysOneElementPerLine)
if err != nil {
return bytesCount, err
}
@@ -358,17 +414,20 @@
if strings.HasPrefix(comment, "#") {
start = ""
}
- writtenBytesCountComment, errc := writeStrings(w, "\n", indent, start, comment, "\n")
+ if !compactComments {
+ writtenBytesCountComment, errc := writeStrings(w, "\n")
+ bytesCount += int64(writtenBytesCountComment)
+ if errc != nil {
+ return bytesCount, errc
+ }
+ }
+ writtenBytesCountComment, errc := writeStrings(w, indent, start, comment, "\n")
bytesCount += int64(writtenBytesCountComment)
if errc != nil {
return bytesCount, errc
}
}
- var commented string
- if v.commented {
- commented = "# "
- }
quotedKey := quoteKeyIfNeeded(k)
writtenBytesCount, err := writeStrings(w, indent, commented, quotedKey, " = ", repr, "\n")
bytesCount += int64(writtenBytesCount)
@@ -468,8 +527,26 @@
case *Tree:
result[k] = node.ToMap()
case *tomlValue:
- result[k] = node.value
+ result[k] = tomlValueToGo(node.value)
}
}
return result
}
+
+func tomlValueToGo(v interface{}) interface{} {
+ if tree, ok := v.(*Tree); ok {
+ return tree.ToMap()
+ }
+
+ rv := reflect.ValueOf(v)
+
+ if rv.Kind() != reflect.Slice {
+ return v
+ }
+ values := make([]interface{}, rv.Len())
+ for i := 0; i < rv.Len(); i++ {
+ item := rv.Index(i).Interface()
+ values[i] = tomlValueToGo(item)
+ }
+ return values
+}