field.go (2757B)
1 package kv 2 3 import ( 4 "codeberg.org/gruf/go-byteutil" 5 ) 6 7 // bufsize is the default buffer size per field to alloc 8 // when calling .AppendFormat() from within .String(). 9 const bufsize = 64 10 11 // Fields is a typedef for a []Field slice to provide 12 // slightly more performant string formatting for multiples. 13 type Fields []Field 14 15 // Get will return the field with given 'key'. 16 func (f Fields) Get(key string) (*Field, bool) { 17 for i := 0; i < len(f); i++ { 18 if f[i].K == key { 19 return &f[i], true 20 } 21 } 22 return nil, false 23 } 24 25 // Set will set an existing field with 'key' to 'value', or append new. 26 func (f *Fields) Set(key string, value interface{}) { 27 for i := 0; i < len(*f); i++ { 28 // Update existing value 29 if (*f)[i].K == key { 30 (*f)[i].V = value 31 return 32 } 33 } 34 35 // Append new field 36 *f = append(*f, Field{ 37 K: key, 38 V: value, 39 }) 40 } 41 42 // AppendFormat appends a string representation of receiving Field(s) to 'b'. 43 func (f Fields) AppendFormat(buf *byteutil.Buffer, vbose bool) { 44 for i := 0; i < len(f); i++ { 45 f[i].AppendFormat(buf, vbose) 46 buf.WriteByte(' ') 47 } 48 if len(f) > 0 { 49 buf.Truncate(1) 50 } 51 } 52 53 // String returns a string representation of receiving Field(s). 54 func (f Fields) String() string { 55 b := make([]byte, 0, bufsize*len(f)) 56 buf := byteutil.Buffer{B: b} 57 f.AppendFormat(&buf, false) 58 return buf.String() 59 } 60 61 // GoString performs .String() but with type prefix. 62 func (f Fields) GoString() string { 63 b := make([]byte, 0, bufsize*len(f)) 64 buf := byteutil.Buffer{B: b} 65 f.AppendFormat(&buf, true) 66 return "kv.Fields{" + buf.String() + "}" 67 } 68 69 // Field represents an individual key-value field. 70 type Field struct { 71 K string // Field key 72 V interface{} // Field value 73 } 74 75 // Key returns the formatted key string of this Field. 76 func (f Field) Key() string { 77 buf := byteutil.Buffer{B: make([]byte, 0, bufsize/2)} 78 AppendQuoteString(&buf, f.K) 79 return buf.String() 80 } 81 82 // String will return a string representation of this Field 83 // of the form `key=value` where `value` is formatted using 84 // fmt package's `%+v` directive. If the .X = true (verbose), 85 // then it uses '%#v'. Both key and value are escaped and 86 // quoted if necessary to fit on single line. 87 // 88 // If the `kvformat` build tag is provided, the formatting 89 // will be performed by the `kv/format` package. In this case 90 // the value will be formatted using the `{:v}` directive, or 91 // `{:?}` if .X = true (verbose). 92 func (f Field) String() string { 93 b := make([]byte, 0, bufsize) 94 buf := byteutil.Buffer{B: b} 95 f.AppendFormat(&buf, false) 96 return buf.String() 97 } 98 99 // GoString performs .String() but with verbose always enabled. 100 func (f Field) GoString() string { 101 b := make([]byte, 0, bufsize) 102 buf := byteutil.Buffer{B: b} 103 f.AppendFormat(&buf, true) 104 return buf.String() 105 }