summaryrefslogtreecommitdiff
path: root/vendor/codeberg.org/gruf/go-kv/util.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/codeberg.org/gruf/go-kv/util.go')
-rw-r--r--vendor/codeberg.org/gruf/go-kv/util.go148
1 files changed, 104 insertions, 44 deletions
diff --git a/vendor/codeberg.org/gruf/go-kv/util.go b/vendor/codeberg.org/gruf/go-kv/util.go
index 3d249e5d4..dfd91ad9d 100644
--- a/vendor/codeberg.org/gruf/go-kv/util.go
+++ b/vendor/codeberg.org/gruf/go-kv/util.go
@@ -2,70 +2,130 @@ package kv
import (
"strconv"
+ "strings"
"codeberg.org/gruf/go-byteutil"
"codeberg.org/gruf/go-kv/format"
)
-// AppendQuoteKey will append and escape/quote a formatted key string.
-func AppendQuoteKey(buf *byteutil.Buffer, str string) {
+// AppendQuote will append (and escape/quote where necessary) a formatted field string.
+func AppendQuote(buf *byteutil.Buffer, str string) {
switch {
- case len(str) > format.SingleTermLine || !strconv.CanBackquote(str):
- // Append quoted and escaped string
- buf.B = strconv.AppendQuote(buf.B, str)
- case format.ContainsDoubleQuote(str):
- // Double quote and escape string
- buf.B = append(buf.B, '"')
- buf.B = format.AppendEscape(buf.B, str)
- buf.B = append(buf.B, '"')
- case len(str) < 1 || format.ContainsSpaceOrTab(str):
- // Double quote this string as-is
- buf.WriteString(`"` + str + `"`)
- default:
- // Append string as-is
- buf.WriteString(str)
- }
-}
+ case len(str) == 0:
+ // Append empty quotes.
+ buf.B = append(buf.B, `""`...)
+ return
-// AppendQuoteValue will append and escape/quote a formatted value string.
-func AppendQuoteValue(buf *byteutil.Buffer, str string) {
- switch {
- case len(str) > format.SingleTermLine || !strconv.CanBackquote(str):
- // Append quoted and escaped string
+ case len(str) == 1:
+ // Append quote single byte.
+ appendQuoteByte(buf, str[0])
+ return
+
+ case len(str) > format.SingleTermLine || !format.IsSafeASCII(str):
+ // Long line or contains non-ascii chars.
buf.B = strconv.AppendQuote(buf.B, str)
return
- case !doubleQuoted(str):
+
+ case !isQuoted(str):
+ // Single/double quoted already.
+
+ // Get space / tab indices (if any).
+ s := strings.IndexByte(str, ' ')
+ t := strings.IndexByte(str, '\t')
+
+ // Find first whitespace.
+ sp0 := smallest(s, t)
+ if sp0 < 0 {
+ break
+ }
+
+ // Check if str is enclosed by braces.
+ // (but without any key-value separator).
+ if (enclosedBy(str, sp0, '{', '}') ||
+ enclosedBy(str, sp0, '[', ']') ||
+ enclosedBy(str, sp0, '(', ')')) &&
+ strings.IndexByte(str, '=') < 0 {
+ break
+ }
+
if format.ContainsDoubleQuote(str) {
- // Double quote and escape string
+ // Contains double quote, double quote
+ // and append escaped existing.
buf.B = append(buf.B, '"')
buf.B = format.AppendEscape(buf.B, str)
buf.B = append(buf.B, '"')
return
- } else if format.ContainsSpaceOrTab(str) {
- // Double quote this string as-is
- buf.WriteString(`"` + str + `"`)
- return
}
+
+ // Quote un-enclosed spaces.
+ buf.B = append(buf.B, '"')
+ buf.B = append(buf.B, str...)
+ buf.B = append(buf.B, '"')
+ return
+ }
+
+ // Double quoted, enclosed in braces, or
+ // literally anything else: append as-is.
+ buf.B = append(buf.B, str...)
+ return
+}
+
+// appendEscapeByte will append byte to buffer, quoting and escaping where necessary.
+func appendQuoteByte(buf *byteutil.Buffer, c byte) {
+ switch c {
+ // Double quote space.
+ case ' ':
+ buf.B = append(buf.B, '"', c, '"')
+
+ // Escape + double quote.
+ case '\a':
+ buf.B = append(buf.B, '"', '\\', 'a', '"')
+ case '\b':
+ buf.B = append(buf.B, '"', '\\', 'b', '"')
+ case '\f':
+ buf.B = append(buf.B, '"', '\\', 'f', '"')
+ case '\n':
+ buf.B = append(buf.B, '"', '\\', 'n', '"')
+ case '\r':
+ buf.B = append(buf.B, '"', '\\', 'r', '"')
+ case '\t':
+ buf.B = append(buf.B, '"', '\\', 't', '"')
+ case '\v':
+ buf.B = append(buf.B, '"', '\\', 'v', '"')
+
+ // Append as-is.
+ default:
+ buf.B = append(buf.B, c)
}
+}
- // Append string as-is
- buf.WriteString(str)
+// isQuoted checks if string is single or double quoted.
+func isQuoted(str string) bool {
+ return (str[0] == '"' && str[len(str)-1] == '"') ||
+ (str[0] == '\'' && str[len(str)-1] == '\'')
+}
+
+// smallest attempts to return the smallest positive value of those given.
+func smallest(i1, i2 int) int {
+ if i1 >= 0 && (i2 < 0 || i1 < i2) {
+ return i1
+ }
+ return i2
}
-// doubleQuoted will return whether 'str' is double quoted.
-func doubleQuoted(str string) bool {
- if len(str) < 2 ||
- str[0] != '"' || str[len(str)-1] != '"' {
+// enclosedBy will check if given string is enclosed by end, and at least non-whitespace up to start.
+func enclosedBy(str string, sp int, start, end byte) bool {
+ // Check for ending char in string.
+ if str[len(str)-1] != end {
return false
}
- var delim bool
- for i := len(str) - 2; i >= 0; i-- {
- switch str[i] {
- case '\\':
- delim = !delim
- default:
- return !delim
- }
+
+ // Check for starting char in string.
+ i := strings.IndexByte(str, start)
+ if i < 0 {
+ return false
}
- return !delim
+
+ // Check before space.
+ return i < sp
}