diff options
Diffstat (limited to 'vendor/codeberg.org/gruf/go-kv')
-rw-r--r-- | vendor/codeberg.org/gruf/go-kv/LICENSE | 9 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-kv/README.md | 36 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-kv/field.go | 105 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-kv/field_fmt.go | 63 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-kv/field_format.go | 35 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-kv/format/README.md | 4 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-kv/format/benchmark.png | bin | 36505 -> 0 bytes | |||
-rw-r--r-- | vendor/codeberg.org/gruf/go-kv/format/format.go | 896 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-kv/format/formatter.go | 349 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-kv/format/util.go | 100 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-kv/util.go | 151 |
11 files changed, 0 insertions, 1748 deletions
diff --git a/vendor/codeberg.org/gruf/go-kv/LICENSE b/vendor/codeberg.org/gruf/go-kv/LICENSE deleted file mode 100644 index b7c4417ac..000000000 --- a/vendor/codeberg.org/gruf/go-kv/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) 2021 gruf - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/codeberg.org/gruf/go-kv/README.md b/vendor/codeberg.org/gruf/go-kv/README.md deleted file mode 100644 index ca66d2fd3..000000000 --- a/vendor/codeberg.org/gruf/go-kv/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# go-kv - -This library provides a key-value field structure `kv.Field{}` that plays well with the `"fmt"` package. It gives an easy means of appending key-value fields to log entries, in a manner that also happens to look nice! (it's not far removed from using a `map[string]interface{}`). - -The formatting for these key-value fields is handled by the `"fmt"` package by default. If you set the `kvformat` build tag then it will use a custom formatting library found under `format/`. You can see the benchmarks for both below. - -benchmarks: -``` -grufwub @ ~/Projects/main/go-kv ---> go test -run=none -benchmem -bench=.* -goos: linux -goarch: amd64 -pkg: codeberg.org/gruf/go-kv -cpu: 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz -BenchmarkFieldAppendMulti-8 125241 9389 ns/op 849 B/op 98 allocs/op -BenchmarkFieldStringMulti-8 113227 10444 ns/op 3029 B/op 120 allocs/op -BenchmarkFieldFprintfMulti-8 147915 7448 ns/op 1121 B/op 115 allocs/op -BenchmarkFieldsAppend-8 189126 6255 ns/op 849 B/op 98 allocs/op -BenchmarkFieldsString-8 166219 6517 ns/op 3798 B/op 100 allocs/op -PASS -ok codeberg.org/gruf/go-kv 6.169s - -grufwub @ ~/Projects/main/go-kv ---> go test -run=none -benchmem -bench=.* -tags=kvformat -goos: linux -goarch: amd64 -pkg: codeberg.org/gruf/go-kv -cpu: 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz -BenchmarkFieldAppendMulti-8 190161 5709 ns/op 592 B/op 56 allocs/op -BenchmarkFieldStringMulti-8 161763 7930 ns/op 3240 B/op 95 allocs/op -BenchmarkFieldFprintfMulti-8 181557 6207 ns/op 1120 B/op 115 allocs/op -BenchmarkFieldsAppend-8 247052 4580 ns/op 592 B/op 56 allocs/op -BenchmarkFieldsString-8 231235 5103 ns/op 1768 B/op 58 allocs/op -PASS -ok codeberg.org/gruf/go-kv 6.134s -``` diff --git a/vendor/codeberg.org/gruf/go-kv/field.go b/vendor/codeberg.org/gruf/go-kv/field.go deleted file mode 100644 index 06c2b2573..000000000 --- a/vendor/codeberg.org/gruf/go-kv/field.go +++ /dev/null @@ -1,105 +0,0 @@ -package kv - -import ( - "codeberg.org/gruf/go-byteutil" -) - -// bufsize is the default buffer size per field to alloc -// when calling .AppendFormat() from within .String(). -const bufsize = 64 - -// Fields is a typedef for a []Field slice to provide -// slightly more performant string formatting for multiples. -type Fields []Field - -// Get will return the field with given 'key'. -func (f Fields) Get(key string) (*Field, bool) { - for i := 0; i < len(f); i++ { - if f[i].K == key { - return &f[i], true - } - } - return nil, false -} - -// Set will set an existing field with 'key' to 'value', or append new. -func (f *Fields) Set(key string, value interface{}) { - for i := 0; i < len(*f); i++ { - // Update existing value - if (*f)[i].K == key { - (*f)[i].V = value - return - } - } - - // Append new field - *f = append(*f, Field{ - K: key, - V: value, - }) -} - -// AppendFormat appends a string representation of receiving Field(s) to 'b'. -func (f Fields) AppendFormat(buf *byteutil.Buffer, vbose bool) { - for i := 0; i < len(f); i++ { - f[i].AppendFormat(buf, vbose) - buf.WriteByte(' ') - } - if len(f) > 0 { - buf.Truncate(1) - } -} - -// String returns a string representation of receiving Field(s). -func (f Fields) String() string { - b := make([]byte, 0, bufsize*len(f)) - buf := byteutil.Buffer{B: b} - f.AppendFormat(&buf, false) - return buf.String() -} - -// GoString performs .String() but with type prefix. -func (f Fields) GoString() string { - b := make([]byte, 0, bufsize*len(f)) - buf := byteutil.Buffer{B: b} - f.AppendFormat(&buf, true) - return "kv.Fields{" + buf.String() + "}" -} - -// Field represents an individual key-value field. -type Field struct { - K string // Field key - V interface{} // Field value -} - -// Key returns the formatted key string of this Field. -func (f Field) Key() string { - buf := byteutil.Buffer{B: make([]byte, 0, bufsize/2)} - AppendQuoteString(&buf, f.K) - return buf.String() -} - -// String will return a string representation of this Field -// of the form `key=value` where `value` is formatted using -// fmt package's `%+v` directive. If the .X = true (verbose), -// then it uses '%#v'. Both key and value are escaped and -// quoted if necessary to fit on single line. -// -// If the `kvformat` build tag is provided, the formatting -// will be performed by the `kv/format` package. In this case -// the value will be formatted using the `{:v}` directive, or -// `{:?}` if .X = true (verbose). -func (f Field) String() string { - b := make([]byte, 0, bufsize) - buf := byteutil.Buffer{B: b} - f.AppendFormat(&buf, false) - return buf.String() -} - -// GoString performs .String() but with verbose always enabled. -func (f Field) GoString() string { - b := make([]byte, 0, bufsize) - buf := byteutil.Buffer{B: b} - f.AppendFormat(&buf, true) - return buf.String() -} diff --git a/vendor/codeberg.org/gruf/go-kv/field_fmt.go b/vendor/codeberg.org/gruf/go-kv/field_fmt.go deleted file mode 100644 index 5d6e77f4b..000000000 --- a/vendor/codeberg.org/gruf/go-kv/field_fmt.go +++ /dev/null @@ -1,63 +0,0 @@ -//go:build !kvformat -// +build !kvformat - -package kv - -import ( - "fmt" - "sync" - - "codeberg.org/gruf/go-byteutil" -) - -// bufPool is a memory pool of byte buffers. -var bufPool = sync.Pool{ - New: func() interface{} { - return &byteutil.Buffer{B: make([]byte, 0, 512)} - }, -} - -// AppendFormat will append formatted format of Field to 'buf'. See .String() for details. -func (f Field) AppendFormat(buf *byteutil.Buffer, vbose bool) { - var fmtstr string - if vbose /* verbose */ { - fmtstr = `%#v` - } else /* regular */ { - fmtstr = `%+v` - } - AppendQuoteString(buf, f.K) - buf.WriteByte('=') - appendValuef(buf, fmtstr, f.V) -} - -// Value returns the formatted value string of this Field. -func (f Field) Value(vbose bool) string { - var fmtstr string - if vbose /* verbose */ { - fmtstr = `%#v` - } else /* regular */ { - fmtstr = `%+v` - } - buf := byteutil.Buffer{B: make([]byte, 0, bufsize/2)} - appendValuef(&buf, fmtstr, f.V) - return buf.String() -} - -// appendValuef appends a quoted value string (formatted by fmt.Appendf) to 'buf'. -func appendValuef(buf *byteutil.Buffer, format string, args ...interface{}) { - // Write format string to a byte buffer - fmtbuf := bufPool.Get().(*byteutil.Buffer) - fmtbuf.B = fmt.Appendf(fmtbuf.B, format, args...) - - // Append quoted value to dst buffer - AppendQuoteValue(buf, fmtbuf.String()) - - // Drop overly large capacity buffers - if fmtbuf.Cap() > int(^uint16(0)) { - return - } - - // Replace buffer in pool - fmtbuf.Reset() - bufPool.Put(fmtbuf) -} diff --git a/vendor/codeberg.org/gruf/go-kv/field_format.go b/vendor/codeberg.org/gruf/go-kv/field_format.go deleted file mode 100644 index f27c28ebd..000000000 --- a/vendor/codeberg.org/gruf/go-kv/field_format.go +++ /dev/null @@ -1,35 +0,0 @@ -//go:build kvformat -// +build kvformat - -package kv - -import ( - "codeberg.org/gruf/go-byteutil" - "codeberg.org/gruf/go-kv/format" -) - -// AppendFormat will append formatted format of Field to 'buf'. See .String() for details. -func (f Field) AppendFormat(buf *byteutil.Buffer, vbose bool) { - var fmtstr string - if vbose /* verbose */ { - fmtstr = "{:?}" - } else /* regular */ { - fmtstr = "{:v}" - } - AppendQuoteString(buf, f.K) - buf.WriteByte('=') - format.Appendf(buf, fmtstr, f.V) -} - -// Value returns the formatted value string of this Field. -func (f Field) Value(vbose bool) string { - var fmtstr string - if vbose /* verbose */ { - fmtstr = "{:?}" - } else /* regular */ { - fmtstr = "{:v}" - } - buf := byteutil.Buffer{B: make([]byte, 0, bufsize/2)} - format.Appendf(&buf, fmtstr, f.V) - return buf.String() -} diff --git a/vendor/codeberg.org/gruf/go-kv/format/README.md b/vendor/codeberg.org/gruf/go-kv/format/README.md deleted file mode 100644 index f27e229ef..000000000 --- a/vendor/codeberg.org/gruf/go-kv/format/README.md +++ /dev/null @@ -1,4 +0,0 @@ -String formatting package using Rust-style formatting directives, geared specifcally towards formatting arguments for key-value log output. Provides ONLY default, key, value and verbose formatting directives. For most formatting cases you will be best served by `"fmt"`. - -Generally more visually friendly than `"fmt"` and performance is much improved. - diff --git a/vendor/codeberg.org/gruf/go-kv/format/benchmark.png b/vendor/codeberg.org/gruf/go-kv/format/benchmark.png Binary files differdeleted file mode 100644 index 7151fbc55..000000000 --- a/vendor/codeberg.org/gruf/go-kv/format/benchmark.png +++ /dev/null diff --git a/vendor/codeberg.org/gruf/go-kv/format/format.go b/vendor/codeberg.org/gruf/go-kv/format/format.go deleted file mode 100644 index cd0b574ea..000000000 --- a/vendor/codeberg.org/gruf/go-kv/format/format.go +++ /dev/null @@ -1,896 +0,0 @@ -package format - -import ( - "reflect" - "strconv" - "unicode/utf8" - - "codeberg.org/gruf/go-byteutil" -) - -const ( - // Flag bit constants, note they are prioritised in this order. - IsKeyBit = uint8(1) << 0 // set to indicate key formatting - VboseBit = uint8(1) << 1 // set to indicate verbose formatting - IsValBit = uint8(1) << 2 // set to indicate value formatting - PanicBit = uint8(1) << 3 // set after panic to prevent recursion -) - -// format provides formatting of values into a Buffer. -type format struct { - // Flags are the currently set value flags. - Flags uint8 - - // Derefs is the current value dereference count. - Derefs uint8 - - // CurDepth is the current Format iterator depth. - CurDepth uint8 - - // VType is the current value type. - VType string - - // Config is the set Formatter config (MUST NOT be nil). - Config *Formatter - - // Buffer is the currently set output buffer. - Buffer *byteutil.Buffer -} - -// AtMaxDepth returns whether format is currently at max depth. -func (f format) AtMaxDepth() bool { - return f.CurDepth > f.Config.MaxDepth -} - -// Key returns whether the isKey flag is set. -func (f format) Key() bool { - return (f.Flags & IsKeyBit) != 0 -} - -// Value returns whether the isVal flag is set. -func (f format) Value() bool { - return (f.Flags & IsValBit) != 0 -} - -// Verbose returns whether the verbose flag is set. -func (f format) Verbose() bool { - return (f.Flags & VboseBit) != 0 -} - -// Panic returns whether the panic flag is set. -func (f format) Panic() bool { - return (f.Flags & PanicBit) != 0 -} - -// SetKey returns format instance with the IsKey bit set to true, -// note this resets the dereference count. -func (f format) SetKey() format { - flags := f.Flags | IsKeyBit - flags &= ^IsValBit - return format{ - Flags: flags, - CurDepth: f.CurDepth, - Config: f.Config, - Buffer: f.Buffer, - } -} - -// SetValue returns format instance with the IsVal bit set to true, -// note this resets the dereference count. -func (f format) SetValue() format { - flags := f.Flags | IsValBit - flags &= ^IsKeyBit - return format{ - Flags: flags, - CurDepth: f.CurDepth, - Config: f.Config, - Buffer: f.Buffer, - } -} - -// SetVerbose returns format instance with the Vbose bit set to true, -// note this resets the dereference count. -func (f format) SetVerbose() format { - return format{ - Flags: f.Flags | VboseBit, - CurDepth: f.CurDepth, - Config: f.Config, - Buffer: f.Buffer, - } -} - -// SetPanic returns format instance with the panic bit set to true, -// note this resets the dereference count and sets IsVal (unsetting IsKey) bit. -func (f format) SetPanic() format { - flags := f.Flags | PanicBit - flags |= IsValBit - flags &= ^IsKeyBit - return format{ - Flags: flags, - CurDepth: f.CurDepth, - Config: f.Config, - Buffer: f.Buffer, - } -} - -// IncrDepth returns format instance with depth incremented and derefs reset. -func (f format) IncrDepth() format { - return format{ - Flags: f.Flags, - Derefs: f.Derefs, - CurDepth: f.CurDepth + 1, - Config: f.Config, - Buffer: f.Buffer, - } -} - -// IncrDerefs returns format instance with dereference count incremented. -func (f format) IncrDerefs() format { - return format{ - Flags: f.Flags, - Derefs: f.Derefs + 1, - CurDepth: f.CurDepth, - Config: f.Config, - Buffer: f.Buffer, - } -} - -func (f format) AppendType() { - const derefs = `********************************` + - `********************************` + - `********************************` + - `********************************` + - `********************************` + - `********************************` + - `********************************` + - `********************************` - f.Buffer.B = append(f.Buffer.B, derefs[:f.Derefs]...) - f.Buffer.B = append(f.Buffer.B, f.VType...) -} - -func (f format) AppendNil() { - if !f.Verbose() { - f.Buffer.B = append(f.Buffer.B, `nil`...) - return - } - - // Append nil with type - f.Buffer.B = append(f.Buffer.B, '(') - f.AppendType() - f.Buffer.B = append(f.Buffer.B, `)(nil`...) - f.Buffer.B = append(f.Buffer.B, ')') -} - -func (f format) AppendByte(b byte) { - switch { - // Always quoted - case f.Key(): - f.Buffer.B = append(f.Buffer.B, '\'') - f.Buffer.B = append(f.Buffer.B, Byte2Str(b)...) - f.Buffer.B = append(f.Buffer.B, '\'') - - // Always quoted ASCII with type - case f.Verbose(): - f._AppendPrimitiveTyped(func(f format) { - f.Buffer.B = append(f.Buffer.B, '\'') - f.Buffer.B = append(f.Buffer.B, Byte2Str(b)...) - f.Buffer.B = append(f.Buffer.B, '\'') - }) - - // Always quoted - case f.Value(): - f.Buffer.B = append(f.Buffer.B, '\'') - f.Buffer.B = append(f.Buffer.B, Byte2Str(b)...) - f.Buffer.B = append(f.Buffer.B, '\'') - - // Append as raw byte - default: - f.Buffer.B = append(f.Buffer.B, b) - } -} - -func (f format) AppendBytes(b []byte) { - switch { - // Bytes CAN be nil formatted - case b == nil: - f.AppendNil() - - // Quoted only if spaces/requires escaping - case f.Key(): - s := byteutil.B2S(b) - f.AppendStringSafe(s) - - // Append as separate ASCII quoted bytes in slice - case f.Verbose(): - f._AppendArrayTyped(func(f format) { - for i := 0; i < len(b); i++ { - f.Buffer.B = append(f.Buffer.B, '\'') - f.Buffer.B = append(f.Buffer.B, Byte2Str(b[i])...) - f.Buffer.B = append(f.Buffer.B, `',`...) - } - if len(b) > 0 { - f.Buffer.Truncate(1) - } - }) - - // Quoted only if spaces/requires escaping - case f.Value(): - s := byteutil.B2S(b) - f.AppendStringSafe(s) - - // Append as raw bytes - default: - f.Buffer.B = append(f.Buffer.B, b...) - } -} - -func (f format) AppendRune(r rune) { - switch { - // Quoted only if spaces/requires escaping - case f.Key(): - f.AppendRuneKey(r) - - // Always quoted ASCII with type - case f.Verbose(): - f._AppendPrimitiveTyped(func(f format) { - f.Buffer.B = strconv.AppendQuoteRuneToASCII(f.Buffer.B, r) - }) - - // Always quoted value - case f.Value(): - f.Buffer.B = strconv.AppendQuoteRune(f.Buffer.B, r) - - // Append as raw rune - default: - f.Buffer.WriteRune(r) - } -} - -func (f format) AppendRuneKey(r rune) { - if utf8.RuneLen(r) > 1 && (r < ' ' && r != '\t') || r == '`' || r == '\u007F' { - // Quote and escape this rune - f.Buffer.B = strconv.AppendQuoteRuneToASCII(f.Buffer.B, r) - } else { - // Simply append rune - f.Buffer.WriteRune(r) - } -} - -func (f format) AppendRunes(r []rune) { - switch { - // Runes CAN be nil formatted - case r == nil: - f.AppendNil() - - // Quoted only if spaces/requires escaping - case f.Key(): - f.AppendStringSafe(string(r)) - - // Append as separate ASCII quoted bytes in slice - case f.Verbose(): - f._AppendArrayTyped(func(f format) { - for i := 0; i < len(r); i++ { - f.Buffer.B = strconv.AppendQuoteRuneToASCII(f.Buffer.B, r[i]) - f.Buffer.B = append(f.Buffer.B, ',') - } - if len(r) > 0 { - f.Buffer.Truncate(1) - } - }) - - // Quoted only if spaces/requires escaping - case f.Value(): - f.AppendStringSafe(string(r)) - - // Append as raw bytes - default: - for i := 0; i < len(r); i++ { - f.Buffer.WriteRune(r[i]) - } - } -} - -func (f format) AppendString(s string) { - switch { - // Quoted only if spaces/requires escaping - case f.Key(): - f.AppendStringSafe(s) - - // Always quoted with type - case f.Verbose(): - f._AppendPrimitiveTyped(func(f format) { - f.AppendStringQuoted(s) - }) - - // Quoted only if spaces/requires escaping - case f.Value(): - f.AppendStringSafe(s) - - // All else - default: - f.Buffer.B = append(f.Buffer.B, s...) - } -} - -func (f format) AppendStringSafe(s string) { - if len(s) > SingleTermLine || !IsSafeASCII(s) { - // Requires quoting AND escaping - f.Buffer.B = strconv.AppendQuote(f.Buffer.B, s) - } else if ContainsDoubleQuote(s) { - // Contains double quotes, needs escaping - f.Buffer.B = append(f.Buffer.B, '"') - f.Buffer.B = AppendEscape(f.Buffer.B, s) - f.Buffer.B = append(f.Buffer.B, '"') - } else if len(s) == 0 || ContainsSpaceOrTab(s) { - // Contains space / empty, needs quotes - f.Buffer.B = append(f.Buffer.B, '"') - f.Buffer.B = append(f.Buffer.B, s...) - f.Buffer.B = append(f.Buffer.B, '"') - } else { - // All else write as-is - f.Buffer.B = append(f.Buffer.B, s...) - } -} - -func (f format) AppendStringQuoted(s string) { - if len(s) > SingleTermLine || !IsSafeASCII(s) { - // Requires quoting AND escaping - f.Buffer.B = strconv.AppendQuote(f.Buffer.B, s) - } else if ContainsDoubleQuote(s) { - // Contains double quotes, needs escaping - f.Buffer.B = append(f.Buffer.B, '"') - f.Buffer.B = AppendEscape(f.Buffer.B, s) - f.Buffer.B = append(f.Buffer.B, '"') - } else { - // Simply append with quotes - f.Buffer.B = append(f.Buffer.B, '"') - f.Buffer.B = append(f.Buffer.B, s...) - f.Buffer.B = append(f.Buffer.B, '"') - } -} - -func (f format) AppendBool(b bool) { - if f.Verbose() { - // Append as bool with type information - f._AppendPrimitiveTyped(func(f format) { - f.Buffer.B = strconv.AppendBool(f.Buffer.B, b) - }) - } else { - // Simply append as bool - f.Buffer.B = strconv.AppendBool(f.Buffer.B, b) - } -} - -func (f format) AppendInt(i int64) { - f._AppendPrimitiveType(func(f format) { - f.Buffer.B = strconv.AppendInt(f.Buffer.B, i, 10) - }) -} - -func (f format) AppendUint(u uint64) { - f._AppendPrimitiveType(func(f format) { - f.Buffer.B = strconv.AppendUint(f.Buffer.B, u, 10) - }) -} - -func (f format) AppendFloat(l float64) { - f._AppendPrimitiveType(func(f format) { - f.AppendFloatValue(l) - }) -} - -func (f format) AppendFloatValue(l float64) { - f.Buffer.B = strconv.AppendFloat(f.Buffer.B, l, 'f', -1, 64) -} - -func (f format) AppendComplex(c complex128) { - f._AppendPrimitiveType(func(f format) { - f.AppendFloatValue(real(c)) - f.Buffer.B = append(f.Buffer.B, '+') - f.AppendFloatValue(imag(c)) - f.Buffer.B = append(f.Buffer.B, 'i') - }) -} - -func (f format) AppendPtr(u uint64) { - f._AppendPtrType(func(f format) { - if u == 0 { - // Append as nil - f.Buffer.B = append(f.Buffer.B, `nil`...) - } else { - // Append as hex number - f.Buffer.B = append(f.Buffer.B, `0x`...) - f.Buffer.B = strconv.AppendUint(f.Buffer.B, u, 16) - } - }) -} - -func (f format) AppendInterfaceOrReflect(i interface{}) { - if !f.AppendInterface(i) { - // Interface append failed, used reflected value + type - f.AppendReflectValue(reflect.ValueOf(i), reflect.TypeOf(i)) - } -} - -func (f format) AppendInterfaceOrReflectNext(v reflect.Value, t reflect.Type) { - // Check we haven't hit max - if f.AtMaxDepth() { - f.Buffer.B = append(f.Buffer.B, `...`...) - return - } - - // Incr the depth - f = f.IncrDepth() - - // Make actual call - f.AppendReflectOrInterface(v, t) -} - -func (f format) AppendReflectOrInterface(v reflect.Value, t reflect.Type) { - if !v.CanInterface() || - !f.AppendInterface(v.Interface()) { - // Interface append failed, use reflect - f.AppendReflectValue(v, t) - } -} - -func (f format) AppendInterface(i interface{}) bool { - switch i := i.(type) { - // Reflect types - case reflect.Type: - f.AppendReflectType(i) - case reflect.Value: - f.Buffer.B = append(f.Buffer.B, `reflect.Value`...) - f.Buffer.B = append(f.Buffer.B, '(') - f.Buffer.B = append(f.Buffer.B, i.String()...) - f.Buffer.B = append(f.Buffer.B, ')') - - // Bytes, runes and string types - case rune: - f.VType = `int32` - f.AppendRune(i) - case []rune: - f.VType = `[]int32` - f.AppendRunes(i) - case byte: - f.VType = `uint8` - f.AppendByte(i) - case []byte: - f.VType = `[]uint8` - f.AppendBytes(i) - case string: - f.VType = `string` - f.AppendString(i) - - // Int types - case int: - f.VType = `int` - f.AppendInt(int64(i)) - case int8: - f.VType = `int8` - f.AppendInt(int64(i)) - case int16: - f.VType = `int16` - f.AppendInt(int64(i)) - case int64: - f.VType = `int64` - f.AppendInt(int64(i)) - - // Uint types - case uint: - f.VType = `uint` - f.AppendUint(uint64(i)) - case uint16: - f.VType = `uint16` - f.AppendUint(uint64(i)) - case uint32: - f.VType = `uint32` - f.AppendUint(uint64(i)) - case uint64: - f.VType = `uint64` - f.AppendUint(uint64(i)) - - // Float types - case float32: - f.VType = `float32` - f.AppendFloat(float64(i)) - case float64: - f.VType = `float64` - f.AppendFloat(float64(i)) - - // Bool type - case bool: - f.VType = `bool` - f.AppendBool(i) - - // Complex types - case complex64: - f.VType = `complex64` - f.AppendComplex(complex128(i)) - case complex128: - f.VType = `complex128` - f.AppendComplex(complex128(i)) - - // Method types - case error: - return f._AppendMethodType(func() string { - return i.Error() - }, i) - case interface{ String() string }: - return f._AppendMethodType(func() string { - return i.String() - }, i) - - // No quick handler - default: - return false - } - - return true -} - -func (f format) AppendReflectType(t reflect.Type) { - switch f.VType = `reflect.Type`; { - case isNil(t) /* safer nil check */ : - f.AppendNil() - case f.Verbose(): - f.AppendType() - f.Buffer.B = append(f.Buffer.B, '(') - f.Buffer.B = append(f.Buffer.B, t.String()...) - f.Buffer.B = append(f.Buffer.B, ')') - default: - f.Buffer.B = append(f.Buffer.B, t.String()...) - } -} - -func (f format) AppendReflectValue(v reflect.Value, t reflect.Type) { - switch v.Kind() { - // String/byte types - case reflect.String: - f.VType = t.String() - f.AppendString(v.String()) - case reflect.Uint8: - f.VType = t.String() - f.AppendByte(byte(v.Uint())) - case reflect.Int32: - f.VType = t.String() - f.AppendRune(rune(v.Int())) - - // Float tpyes - case reflect.Float32, reflect.Float64: - f.VType = t.String() - f.AppendFloat(v.Float()) - - // Int types - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int64: - f.VType = t.String() - f.AppendInt(v.Int()) - - // Uint types - case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: - f.VType = t.String() - f.AppendUint(v.Uint()) - - // Complex types - case reflect.Complex64, reflect.Complex128: - f.VType = t.String() - f.AppendComplex(v.Complex()) - - // Bool type - case reflect.Bool: - f.VType = t.String() - f.AppendBool(v.Bool()) - - // Slice and array types - case reflect.Array: - f.AppendArray(v, t) - case reflect.Slice: - f.AppendSlice(v, t) - - // Map types - case reflect.Map: - f.AppendMap(v, t) - - // Struct types - case reflect.Struct: - f.AppendStruct(v, t) - - // Interface type - case reflect.Interface: - if v.IsNil() { - // Append nil ptr type - f.VType = t.String() - f.AppendNil() - } else { - // Append interface - v = v.Elem() - t = v.Type() - f.AppendReflectOrInterface(v, t) - } - - // Deref'able ptr type - case reflect.Ptr: - if v.IsNil() { - // Append nil ptr type - f.VType = t.String() - f.AppendNil() - } else { - // Deref to next level - f = f.IncrDerefs() - v, t = v.Elem(), t.Elem() - f.AppendReflectOrInterface(v, t) - } - - // 'raw' pointer types - case reflect.UnsafePointer, reflect.Func, reflect.Chan: - f.VType = t.String() - f.AppendPtr(uint64(v.Pointer())) - case reflect.Uintptr: - f.VType = t.String() - f.AppendPtr(v.Uint()) - - // Zero reflect value - case reflect.Invalid: - f.Buffer.B = append(f.Buffer.B, `nil`...) - - // All others - default: - f.VType = t.String() - f.AppendType() - } -} - -func (f format) AppendSlice(v reflect.Value, t reflect.Type) { - // Get slice value type - f.VType = t.String() - - if t.Elem().Kind() == reflect.Uint8 { - // This is a byte slice - f.AppendBytes(v.Bytes()) - return - } - - if v.IsNil() { - // Nil slice - f.AppendNil() - return - } - - if f.Verbose() { - // Append array with type information - f._AppendArrayTyped(func(f format) { - f.AppendArrayElems(v, t) - }) - } else { - // Simply append array as elems - f._AppendArray(func(f format) { - f.AppendArrayElems(v, t) - }) - } -} - -func (f format) AppendArray(v reflect.Value, t reflect.Type) { - // Get array value type - f.VType = t.String() - - if f.Verbose() { - // Append array with type information - f._AppendArrayTyped(func(f format) { - f.AppendArrayElems(v, t) - }) - } else { - // Simply append array as elems - f._AppendArray(func(f format) { - f.AppendArrayElems(v, t) - }) - } -} - -func (f format) AppendArrayElems(v reflect.Value, t reflect.Type) { - // Get no. elems - n := v.Len() - - // Get elem type - et := t.Elem() - - // Append values - for i := 0; i < n; i++ { - f.SetValue().AppendInterfaceOrReflectNext(v.Index(i), et) - f.Buffer.B = append(f.Buffer.B, ',') - } - - // Drop last comma - if n > 0 { - f.Buffer.Truncate(1) - } -} - -func (f format) AppendMap(v reflect.Value, t reflect.Type) { - // Get value type - f.VType = t.String() - - if v.IsNil() { - // Nil map -- no fields - f.AppendNil() - return - } - - // Append field formatted map fields - f._AppendFieldType(func(f format) { - f.AppendMapFields(v, t) - }) -} - -func (f format) AppendMapFields(v reflect.Value, t reflect.Type) { - // Get a map iterator - r := v.MapRange() - n := v.Len() - - // Get key/val types - kt := t.Key() - kv := t.Elem() - - // Iterate pairs - for r.Next() { - f.SetKey().AppendInterfaceOrReflectNext(r.Key(), kt) - f.Buffer.B = append(f.Buffer.B, '=') - f.SetValue().AppendInterfaceOrReflectNext(r.Value(), kv) - f.Buffer.B = append(f.Buffer.B, ' ') - } - - // Drop last space - if n > 0 { - f.Buffer.Truncate(1) - } -} - -func (f format) AppendStruct(v reflect.Value, t reflect.Type) { - // Get value type - f.VType = t.String() - - // Append field formatted struct fields - f._AppendFieldType(func(f format) { - f.AppendStructFields(v, t) - }) -} - -func (f format) AppendStructFields(v reflect.Value, t reflect.Type) { - // Get field no. - n := v.NumField() - - // Iterate struct fields - for i := 0; i < n; i++ { - vfield := v.Field(i) - tfield := t.Field(i) - - // Append field name - f.AppendStringSafe(tfield.Name) - f.Buffer.B = append(f.Buffer.B, '=') - f.SetValue().AppendInterfaceOrReflectNext(vfield, tfield.Type) - - // Append separator - f.Buffer.B = append(f.Buffer.B, ' ') - } - - // Drop last space - if n > 0 { - f.Buffer.Truncate(1) - } -} - -func (f format) _AppendMethodType(method func() string, i interface{}) (ok bool) { - // Verbose -- no methods - if f.Verbose() { - return false - } - - // Catch nil type - if isNil(i) { - f.AppendNil() - return true - } - - // Catch any panics - defer func() { - if r := recover(); r != nil { - // DON'T recurse catchPanic() - if f.Panic() { - panic(r) - } - - // Attempt to decode panic into buf - f.Buffer.B = append(f.Buffer.B, `!{PANIC=`...) - f.SetPanic().AppendInterfaceOrReflect(r) - f.Buffer.B = append(f.Buffer.B, '}') - - // Ensure no further attempts - // to format after return - ok = true - } - }() - - // Get method result - result := method() - - switch { - // Append as key formatted - case f.Key(): - f.AppendStringSafe(result) - - // Append as always quoted - case f.Value(): - f.AppendStringQuoted(result) - - // Append as-is - default: - f.Buffer.B = append(f.Buffer.B, result...) - } - - return true -} - -// _AppendPrimitiveType is a helper to append prefix/suffix for primitives (numbers/bools/bytes/runes). -func (f format) _AppendPrimitiveType(appendPrimitive func(format)) { - if f.Verbose() { - // Append value with type information - f._AppendPrimitiveTyped(appendPrimitive) - } else { - // Append simply as-is - appendPrimitive(f) - } -} - -// _AppendPrimitiveTyped is a helper to append prefix/suffix for primitives (numbers/bools/bytes/runes) with their types (if deref'd). -func (f format) _AppendPrimitiveTyped(appendPrimitive func(format)) { - if f.Derefs > 0 { - // Is deref'd, append type info - f.Buffer.B = append(f.Buffer.B, '(') - f.AppendType() - f.Buffer.WriteString(`)(`) - appendPrimitive(f) - f.Buffer.B = append(f.Buffer.B, ')') - } else { - // Simply append value - appendPrimitive(f) - } -} - -// _AppendPtrType is a helper to append prefix/suffix for ptr types (with type if necessary). -func (f format) _AppendPtrType(appendPtr func(format)) { - if f.Verbose() { - // Append value with type information - f.Buffer.B = append(f.Buffer.B, '(') - f.AppendType() - f.Buffer.WriteString(`)(`) - appendPtr(f) - f.Buffer.B = append(f.Buffer.B, ')') - } else { - // Append simply as-is - appendPtr(f) - } -} - -// _AppendArray is a helper to append prefix/suffix for array-types. -func (f format) _AppendArray(appendArray func(format)) { - f.Buffer.B = append(f.Buffer.B, '[') - appendArray(f) - f.Buffer.B = append(f.Buffer.B, ']') -} - -// _AppendArrayTyped is a helper to append prefix/suffix for array-types with their types. -func (f format) _AppendArrayTyped(appendArray func(format)) { - f.AppendType() - f.Buffer.B = append(f.Buffer.B, '{') - appendArray(f) - f.Buffer.B = append(f.Buffer.B, '}') -} - -// _AppendFields is a helper to append prefix/suffix for field-types (with type if necessary). -func (f format) _AppendFieldType(appendFields func(format)) { - if f.Verbose() { - f.AppendType() - } - f.Buffer.B = append(f.Buffer.B, '{') - appendFields(f) - f.Buffer.B = append(f.Buffer.B, '}') -} diff --git a/vendor/codeberg.org/gruf/go-kv/format/formatter.go b/vendor/codeberg.org/gruf/go-kv/format/formatter.go deleted file mode 100644 index fd8cf98df..000000000 --- a/vendor/codeberg.org/gruf/go-kv/format/formatter.go +++ /dev/null @@ -1,349 +0,0 @@ -package format - -import ( - "strconv" - "strings" - - "codeberg.org/gruf/go-byteutil" -) - -// Formatter allows configuring value and string formatting. -type Formatter struct { - // MaxDepth specifies the max depth of fields the formatter will iterate. - // Once max depth is reached, value will simply be formatted as "...". - // e.g. - // - // MaxDepth=1 - // type A struct{ - // Nested B - // } - // type B struct{ - // Nested C - // } - // type C struct{ - // Field string - // } - // - // Append(&buf, A{}) => {Nested={Nested={Field=...}}} - MaxDepth uint8 -} - -// Append will append formatted form of supplied values into 'buf'. -func (f *Formatter) Append(buf *byteutil.Buffer, v ...interface{}) { - fmt := format{Buffer: buf, Config: f} - for i := 0; i < len(v); i++ { - fmt.AppendInterfaceOrReflect(v[i]) - fmt.Buffer.B = append(fmt.Buffer.B, ' ') - } - if len(v) > 0 { - fmt.Buffer.Truncate(1) - } -} - -// Appendf will append the formatted string with supplied values into 'buf'. -// Supported format directives: -// - '{}' => format supplied arg, in place -// - '{0}' => format arg at index 0 of supplied, in place -// - '{:?}' => format supplied arg verbosely, in place -// - '{:k}' => format supplied arg as key, in place -// - '{:v}' => format supplied arg as value, in place -// -// To escape either of '{}' simply append an additional brace e.g. -// - '{{' => '{' -// - '}}' => '}' -// - '{{}}' => '{}' -// - '{{:?}}' => '{:?}' -// -// More formatting directives might be included in the future. -func (f *Formatter) Appendf(buf *byteutil.Buffer, s string, a ...interface{}) { - const ( - // ground state - modeNone = uint8(0) - - // prev reached '{' - modeOpen = uint8(1) - - // prev reached '}' - modeClose = uint8(2) - - // parsing directive index - modeIdx = uint8(3) - - // parsing directive operands - modeOp = uint8(4) - ) - - var ( - // mode is current parsing mode - mode uint8 - - // arg is the current arg index - arg int - - // carg is current directive-set arg index - carg int - - // last is the trailing cursor to see slice windows - last int - - // idx is the current index in 's' - idx int - - // fmt is the base argument formatter - fmt = format{ - Config: f, - Buffer: buf, - } - - // NOTE: these functions are defined here as function - // locals as it turned out to be better for performance - // doing it this way, than encapsulating their logic in - // some kind of parsing structure. Maybe if the parser - // was pooled along with the buffers it might work out - // better, but then it makes more internal functions i.e. - // .Append() .Appendf() less accessible outside package. - // - // Currently, passing '-gcflags "-l=4"' causes a not - // insignificant decrease in ns/op, which is likely due - // to more aggressive function inlining, which this - // function can obviously stand to benefit from :) - - // Str returns current string window slice, and updates - // the trailing cursor 'last' to current 'idx' - Str = func() string { - str := s[last:idx] - last = idx - return str - } - - // MoveUp moves the trailing cursor 'last' just past 'idx' - MoveUp = func() { - last = idx + 1 - } - - // MoveUpTo moves the trailing cursor 'last' either up to - // closest '}', or current 'idx', whichever is furthest. - // NOTE: by calling bytealg.IndexByteString() directly (and - // not the strconv pass-through, we shave-off complexity - // which allows this function to be inlined). - MoveUpTo = func() { - i := strings.IndexByte(s[idx:], '}') - if i >= 0 { - idx += i - } - MoveUp() - } - - // ParseIndex parses an integer from the current string - // window, updating 'last' to 'idx'. The string window - // is ASSUMED to contain only valid ASCII numbers. This - // only returns false if number exceeds platform int size - ParseIndex = func() bool { - var str string - - // Get current window - if str = Str(); len(str) < 1 { - return true - } - - // Index HAS to fit within platform integer size - if !(strconv.IntSize == 32 && (0 < len(s) && len(s) < 10)) || - !(strconv.IntSize == 64 && (0 < len(s) && len(s) < 19)) { - return false - } - - carg = 0 - - // Build integer from string - for i := 0; i < len(str); i++ { - carg = carg*10 + int(str[i]-'0') - } - - return true - } - - // ValidOp checks that for current ending idx, that a valid - // operand was achieved -- only 0, 1 are valid numbers. - ValidOp = func() bool { - diff := (idx - last) - last = idx - return diff < 2 - } - - // AppendArg will take either the directive-set, or - // iterated arg index, check within bounds of 'a' and - // append the that argument formatted to the buffer. - // On failure, it will append an error string - AppendArg = func() { - // Look for idx - if carg < 0 { - carg = arg - } - - // Incr idx - arg++ - - if carg < len(a) { - // Append formatted argument value - fmt.AppendInterfaceOrReflect(a[carg]) - } else { - // No argument found for index - fmt.Buffer.B = append(fmt.Buffer.B, `!{MISSING_ARG}`...) - } - } - - // Reset will reset the mode to ground, the flags - // to empty and parsed 'carg' to empty - Reset = func() { - mode = modeNone - fmt.CurDepth = 0 - fmt.Flags = 0 - fmt.VType = "" - fmt.Derefs = 0 - carg = -1 - } - ) - - for idx = 0; idx < len(s); idx++ { - // Get next char - c := s[idx] - - switch mode { - // Ground mode - case modeNone: - switch c { - case '{': - // Enter open mode - fmt.Buffer.B = append(fmt.Buffer.B, Str()...) - mode = modeOpen - MoveUp() - case '}': - // Enter close mode - fmt.Buffer.B = append(fmt.Buffer.B, Str()...) - mode = modeClose - MoveUp() - } - - // Encountered open '{' - case modeOpen: - switch c { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - // Starting index - mode = modeIdx - MoveUp() - case '{': - // Escaped bracket - fmt.Buffer.B = append(fmt.Buffer.B, '{') - mode = modeNone - MoveUp() - case '}': - // Format arg - AppendArg() - Reset() - MoveUp() - case ':': - // Starting operands - mode = modeOp - MoveUp() - default: - // Bad char, missing a close - fmt.Buffer.B = append(fmt.Buffer.B, `!{MISSING_CLOSE}`...) - mode = modeNone - MoveUpTo() - } - - // Encountered close '}' - case modeClose: - switch c { - case '}': - // Escaped close bracket - fmt.Buffer.B = append(fmt.Buffer.B, '}') - mode = modeNone - MoveUp() - default: - // Missing an open bracket - fmt.Buffer.B = append(fmt.Buffer.B, `!{MISSING_OPEN}`...) - mode = modeNone - MoveUp() - } - - // Preparing index - case modeIdx: - switch c { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - case ':': - if !ParseIndex() { - // Unable to parse an integer - fmt.Buffer.B = append(fmt.Buffer.B, `!{BAD_INDEX}`...) - mode = modeNone - MoveUpTo() - } else { - // Starting operands - mode = modeOp - MoveUp() - } - case '}': - if !ParseIndex() { - // Unable to parse an integer - fmt.Buffer.B = append(fmt.Buffer.B, `!{BAD_INDEX}`...) - } else { - // Format arg - AppendArg() - } - Reset() - MoveUp() - default: - // Not a valid index character - fmt.Buffer.B = append(fmt.Buffer.B, `!{BAD_INDEX}`...) - mode = modeNone - MoveUpTo() - } - - // Preparing operands - case modeOp: - switch c { - case 'k': - fmt.Flags |= IsKeyBit - case 'v': - fmt.Flags |= IsValBit - case '?': - fmt.Flags |= VboseBit - case '}': - if !ValidOp() { - // Bad operands parsed - fmt.Buffer.B = append(fmt.Buffer.B, `!{BAD_OPERAND}`...) - } else { - // Format arg - AppendArg() - } - Reset() - MoveUp() - default: - // Not a valid operand char - fmt.Buffer.B = append(fmt.Buffer.B, `!{BAD_OPERAND}`...) - Reset() - MoveUpTo() - } - } - } - - // Append any remaining - fmt.Buffer.B = append(fmt.Buffer.B, s[last:]...) -} - -// formatter is the default formatter instance. -var formatter = Formatter{ - MaxDepth: 10, -} - -// Append will append formatted form of supplied values into 'buf' using default formatter. -// See Formatter.Append() for more documentation. -func Append(buf *byteutil.Buffer, v ...interface{}) { - formatter.Append(buf, v...) -} - -// Appendf will append the formatted string with supplied values into 'buf' using default formatter. -// See Formatter.Appendf() for more documentation. -func Appendf(buf *byteutil.Buffer, s string, a ...interface{}) { - formatter.Appendf(buf, s, a...) -} diff --git a/vendor/codeberg.org/gruf/go-kv/format/util.go b/vendor/codeberg.org/gruf/go-kv/format/util.go deleted file mode 100644 index dbb918952..000000000 --- a/vendor/codeberg.org/gruf/go-kv/format/util.go +++ /dev/null @@ -1,100 +0,0 @@ -package format - -import ( - "strings" - "unsafe" -) - -const ( - // SingleTermLine: beyond a certain length of string, all of the - // extra checks to handle quoting/not-quoting add a significant - // amount of extra processing time. Quoting in this manner only really - // effects readability on a single line, so a max string length that - // encompasses the maximum number of columns on *most* terminals was - // selected. This was chosen using the metric that 1080p is one of the - // most common display resolutions, and that a relatively small font size - // of 7 requires 223 columns. So 256 should be >= $COLUMNS (fullscreen) - // in 99% of usecases (these figures all pulled out of my ass). - SingleTermLine = 256 -) - -// IsSafeASCII checks whether string is printable (i.e. non-control char) ASCII text. -func IsSafeASCII(str string) bool { - for _, r := range str { - if (r < ' ' && r != '\t') || - r >= 0x7f { - return false - } - } - return true -} - -// ContainsSpaceOrTab checks if "s" contains space or tabs. EXPECTS ASCII. -func ContainsSpaceOrTab(s string) bool { - if i := strings.IndexByte(s, ' '); i >= 0 { - return true // note using indexbyte as it is ASM. - } else if i := strings.IndexByte(s, '\t'); i >= 0 { - return true - } - return false -} - -// ContainsDoubleQuote checks if "s" contains a double quote. EXPECTS ASCII. -func ContainsDoubleQuote(s string) bool { - return (strings.IndexByte(s, '"') >= 0) -} - -// AppendEscape will append 's' to 'dst' and escape any double quotes. EXPECTS ASCII. -func AppendEscape(dst []byte, str string) []byte { - for i := range str { - switch str[i] { - case '\\': - // Append delimited '\' - dst = append(dst, '\\', '\\') - - case '"': - // Append delimited '"' - dst = append(dst, '\\', '"') - default: - // Append char as-is - dst = append(dst, str[i]) - } - } - return dst -} - -// Byte2Str returns 'c' as a string, escaping if necessary. -func Byte2Str(c byte) string { - switch c { - case '\a': - return `\a` - case '\b': - return `\b` - case '\f': - return `\f` - case '\n': - return `\n` - case '\r': - return `\r` - case '\t': - return `\t` - case '\v': - return `\v` - case '\\': - return `\\` - default: - if c < ' ' { - const hex = "0123456789abcdef" - return `\x` + - string(hex[c>>4]) + - string(hex[c&0xF]) - } - return string(c) - } -} - -// isNil will safely check if 'v' is nil without dealing with weird Go interface nil bullshit. -func isNil(i interface{}) bool { - type eface struct{ _type, data unsafe.Pointer } //nolint - return (*(*eface)(unsafe.Pointer(&i))).data == nil //nolint -} diff --git a/vendor/codeberg.org/gruf/go-kv/util.go b/vendor/codeberg.org/gruf/go-kv/util.go deleted file mode 100644 index c0c8ccdab..000000000 --- a/vendor/codeberg.org/gruf/go-kv/util.go +++ /dev/null @@ -1,151 +0,0 @@ -package kv - -import ( - "strconv" - "strings" - - "codeberg.org/gruf/go-byteutil" - "codeberg.org/gruf/go-kv/format" -) - -// AppendQuoteString will append (and escape/quote where necessary) a field string. -func AppendQuoteString(buf *byteutil.Buffer, str string) { - switch { - case len(str) == 0: - // Append empty quotes. - buf.B = append(buf.B, `""`...) - return - - case len(str) == 1: - // Append quote single byte. - buf.B = append(buf.B, '\'') - buf.B = append(buf.B, format.Byte2Str(str[0])...) - buf.B = append(buf.B, '\'') - 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 !isQuoted(str): - // Not single/double quoted already. - - if format.ContainsSpaceOrTab(str) { - // Quote un-enclosed spaces. - buf.B = append(buf.B, '"') - buf.B = append(buf.B, str...) - buf.B = append(buf.B, '"') - return - } - - if format.ContainsDoubleQuote(str) { - // 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 - } - } - - // Double quoted, enclosed in braces, or - // literally anything else: append as-is. - buf.B = append(buf.B, str...) - return -} - -// AppendQuoteValue will append (and escape/quote where necessary) a formatted value string. -func AppendQuoteValue(buf *byteutil.Buffer, str string) { - switch { - case len(str) == 0: - // Append empty quotes. - buf.B = append(buf.B, `""`...) - return - - case len(str) == 1: - // Append quote single byte. - buf.B = append(buf.B, '\'') - buf.B = append(buf.B, format.Byte2Str(str[0])...) - buf.B = append(buf.B, '\'') - 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 !isQuoted(str): - // Not 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) { - // 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 - } - - // 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 -} - -// 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 -} - -// 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 - } - - // Check for starting char in string. - i := strings.IndexByte(str, start) - if i < 0 { - return false - } - - // Check before space. - return i < sp -} |