diff options
Diffstat (limited to 'vendor/codeberg.org/gruf/go-format/format.go')
-rw-r--r-- | vendor/codeberg.org/gruf/go-format/format.go | 565 |
1 files changed, 0 insertions, 565 deletions
diff --git a/vendor/codeberg.org/gruf/go-format/format.go b/vendor/codeberg.org/gruf/go-format/format.go deleted file mode 100644 index 856fe890e..000000000 --- a/vendor/codeberg.org/gruf/go-format/format.go +++ /dev/null @@ -1,565 +0,0 @@ -package format - -import ( - "reflect" - "strconv" - "unsafe" -) - -// Formattable defines a type capable of being formatted and appended to a byte buffer. -type Formattable interface { - AppendFormat([]byte) []byte -} - -// format is the object passed among the append___ formatting functions. -type format struct { - flags uint8 // 'isKey' and 'verbose' flags - drefs uint8 // current value deref count - curd uint8 // current depth - maxd uint8 // maximum depth - buf *Buffer // out buffer -} - -const ( - // flag bit constants. - isKeyBit = uint8(1) << 0 - isValBit = uint8(1) << 1 - vboseBit = uint8(1) << 2 - panicBit = uint8(1) << 3 -) - -// AtMaxDepth returns whether format is currently at max depth. -func (f format) AtMaxDepth() bool { - return f.curd > f.maxd -} - -// Derefs returns no. times current value has been dereferenced. -func (f format) Derefs() uint8 { - return f.drefs -} - -// IsKey returns whether the isKey flag is set. -func (f format) IsKey() bool { - return (f.flags & isKeyBit) != 0 -} - -// IsValue returns whether the isVal flag is set. -func (f format) IsValue() 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 -} - -// SetIsKey returns format instance with the isKey bit set to value. -func (f format) SetIsKey() format { - return format{ - flags: f.flags & ^isValBit | isKeyBit, - curd: f.curd, - maxd: f.maxd, - buf: f.buf, - } -} - -// SetIsValue returns format instance with the isVal bit set to value. -func (f format) SetIsValue() format { - return format{ - flags: f.flags & ^isKeyBit | isValBit, - curd: f.curd, - maxd: f.maxd, - buf: f.buf, - } -} - -// SetPanic returns format instance with the panic bit set to value. -func (f format) SetPanic() format { - return format{ - flags: f.flags | panicBit /* handle panic as value */ | isValBit & ^isKeyBit, - curd: f.curd, - maxd: f.maxd, - buf: f.buf, - } -} - -// IncrDepth returns format instance with depth incremented. -func (f format) IncrDepth() format { - return format{ - flags: f.flags, - curd: f.curd + 1, - maxd: f.maxd, - buf: f.buf, - } -} - -// IncrDerefs returns format instance with dereference count incremented. -func (f format) IncrDerefs() format { - return format{ - flags: f.flags, - drefs: f.drefs + 1, - curd: f.curd, - maxd: f.maxd, - buf: f.buf, - } -} - -// appendType appends a type using supplied type str. -func appendType(fmt format, t string) { - for i := uint8(0); i < fmt.Derefs(); i++ { - fmt.buf.AppendByte('*') - } - fmt.buf.AppendString(t) -} - -// appendNilType Appends nil to buf, type included if verbose. -func appendNilType(fmt format, t string) { - if fmt.Verbose() { - fmt.buf.AppendByte('(') - appendType(fmt, t) - fmt.buf.AppendString(`)(nil)`) - } else { - fmt.buf.AppendString(`nil`) - } -} - -// appendByte Appends a single byte to buf. -func appendByte(fmt format, b byte) { - if fmt.IsValue() || fmt.Verbose() { - fmt.buf.AppendString(`'` + string(b) + `'`) - } else { - fmt.buf.AppendByte(b) - } -} - -// appendBytes Appends a quoted byte slice to buf. -func appendBytes(fmt format, b []byte) { - if b == nil { - // Bytes CAN be nil formatted - appendNilType(fmt, `[]byte`) - } else { - // Append bytes as slice - fmt.buf.AppendByte('[') - for _, b := range b { - fmt.buf.AppendByte(b) - fmt.buf.AppendByte(',') - } - if len(b) > 0 { - fmt.buf.Truncate(1) - } - fmt.buf.AppendByte(']') - } -} - -// appendString Appends an escaped, double-quoted string to buf. -func appendString(fmt format, s string) { - switch { - // Key in a key-value pair - case fmt.IsKey(): - if !strconv.CanBackquote(s) { - // Requires quoting AND escaping - fmt.buf.B = strconv.AppendQuote(fmt.buf.B, s) - } else if containsSpaceOrTab(s) { - // Contains space, needs quotes - fmt.buf.AppendString(`"` + s + `"`) - } else { - // All else write as-is - fmt.buf.AppendString(s) - } - - // Value in a key-value pair (always escape+quote) - case fmt.IsValue(): - fmt.buf.B = strconv.AppendQuote(fmt.buf.B, s) - - // Verbose but neither key nor value (always quote) - case fmt.Verbose(): - fmt.buf.AppendString(`"` + s + `"`) - - // All else - default: - fmt.buf.AppendString(s) - } -} - -// appendBool Appends a formatted bool to buf. -func appendBool(fmt format, b bool) { - fmt.buf.B = strconv.AppendBool(fmt.buf.B, b) -} - -// appendInt Appends a formatted int to buf. -func appendInt(fmt format, i int64) { - fmt.buf.B = strconv.AppendInt(fmt.buf.B, i, 10) -} - -// appendUint Appends a formatted uint to buf. -func appendUint(fmt format, u uint64) { - fmt.buf.B = strconv.AppendUint(fmt.buf.B, u, 10) -} - -// appendFloat Appends a formatted float to buf. -func appendFloat(fmt format, f float64) { - fmt.buf.B = strconv.AppendFloat(fmt.buf.B, f, 'G', -1, 64) -} - -// appendComplex Appends a formatted complex128 to buf. -func appendComplex(fmt format, c complex128) { - appendFloat(fmt, real(c)) - fmt.buf.AppendByte('+') - appendFloat(fmt, imag(c)) - fmt.buf.AppendByte('i') -} - -// isNil will safely check if 'v' is nil without dealing with weird Go interface nil bullshit. -func isNil(i interface{}) bool { - e := *(*struct { - _ unsafe.Pointer // type - v unsafe.Pointer // value - })(unsafe.Pointer(&i)) - return (e.v == nil) -} - -// appendIfaceOrReflectValue will attempt to append as interface, falling back to reflection. -func appendIfaceOrRValue(fmt format, i interface{}) { - if !appendIface(fmt, i) { - appendRValue(fmt, reflect.ValueOf(i)) - } -} - -// appendValueNext checks for interface methods before performing appendRValue, checking + incr depth. -func appendRValueOrIfaceNext(fmt format, v reflect.Value) { - // Check we haven't hit max - if fmt.AtMaxDepth() { - fmt.buf.AppendString("...") - return - } - - // Incr the depth - fmt = fmt.IncrDepth() - - // Make actual call - if !v.CanInterface() || !appendIface(fmt, v.Interface()) { - appendRValue(fmt, v) - } -} - -// appendIface parses and Appends a formatted interface value to buf. -func appendIface(fmt format, i interface{}) (ok bool) { - ok = true // default - catchPanic := func() { - if r := recover(); r != nil { - // DON'T recurse catchPanic() - if fmt.Panic() { - panic(r) - } - - // Attempt to decode panic into buf - fmt.buf.AppendString(`!{PANIC=`) - appendIfaceOrRValue(fmt.SetPanic(), r) - fmt.buf.AppendByte('}') - - // Ensure return - ok = true - } - } - - switch i := i.(type) { - // Nil type - case nil: - fmt.buf.AppendString(`nil`) - - // Reflect types - case reflect.Type: - if isNil(i) /* safer nil check */ { - appendNilType(fmt, `reflect.Type`) - } else { - appendType(fmt, `reflect.Type`) - fmt.buf.AppendString(`(` + i.String() + `)`) - } - case reflect.Value: - appendType(fmt, `reflect.Value`) - fmt.buf.AppendByte('(') - fmt.flags |= vboseBit - appendRValue(fmt, i) - fmt.buf.AppendByte(')') - - // Bytes and string types - case byte: - appendByte(fmt, i) - case []byte: - appendBytes(fmt, i) - case string: - appendString(fmt, i) - - // Int types - case int: - appendInt(fmt, int64(i)) - case int8: - appendInt(fmt, int64(i)) - case int16: - appendInt(fmt, int64(i)) - case int32: - appendInt(fmt, int64(i)) - case int64: - appendInt(fmt, i) - - // Uint types - case uint: - appendUint(fmt, uint64(i)) - // case uint8 :: this is 'byte' - case uint16: - appendUint(fmt, uint64(i)) - case uint32: - appendUint(fmt, uint64(i)) - case uint64: - appendUint(fmt, i) - - // Float types - case float32: - appendFloat(fmt, float64(i)) - case float64: - appendFloat(fmt, i) - - // Bool type - case bool: - appendBool(fmt, i) - - // Complex types - case complex64: - appendComplex(fmt, complex128(i)) - case complex128: - appendComplex(fmt, i) - - // Method types - case error: - switch { - case fmt.Verbose(): - ok = false - case isNil(i) /* use safer nil check */ : - appendNilType(fmt, reflect.TypeOf(i).String()) - default: - defer catchPanic() - appendString(fmt, i.Error()) - } - case Formattable: - switch { - case fmt.Verbose(): - ok = false - case isNil(i) /* use safer nil check */ : - appendNilType(fmt, reflect.TypeOf(i).String()) - default: - defer catchPanic() - fmt.buf.B = i.AppendFormat(fmt.buf.B) - } - case interface{ String() string }: - switch { - case fmt.Verbose(): - ok = false - case isNil(i) /* use safer nil check */ : - appendNilType(fmt, reflect.TypeOf(i).String()) - default: - defer catchPanic() - appendString(fmt, i.String()) - } - - // No quick handler - default: - ok = false - } - - return ok -} - -// appendReflectValue will safely append a reflected value. -func appendRValue(fmt format, v reflect.Value) { - switch v.Kind() { - // String and byte types - case reflect.Uint8: - appendByte(fmt, byte(v.Uint())) - case reflect.String: - appendString(fmt, v.String()) - - // Float tpyes - case reflect.Float32, reflect.Float64: - appendFloat(fmt, v.Float()) - - // Int types - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - appendInt(fmt, v.Int()) - - // Uint types - case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: - appendUint(fmt, v.Uint()) - - // Complex types - case reflect.Complex64, reflect.Complex128: - appendComplex(fmt, v.Complex()) - - // Bool type - case reflect.Bool: - appendBool(fmt, v.Bool()) - - // Slice and array types - case reflect.Array: - appendArrayType(fmt, v) - case reflect.Slice: - if v.IsNil() { - appendNilType(fmt, v.Type().String()) - } else { - appendArrayType(fmt, v) - } - - // Map types - case reflect.Map: - if v.IsNil() { - appendNilType(fmt, v.Type().String()) - } else { - appendMapType(fmt, v) - } - - // Struct types - case reflect.Struct: - appendStructType(fmt, v) - - // Deref'able ptr types - case reflect.Ptr, reflect.Interface: - if v.IsNil() { - appendNilType(fmt, v.Type().String()) - } else { - appendRValue(fmt.IncrDerefs(), v.Elem()) - } - - // 'raw' pointer types - case reflect.UnsafePointer: - appendType(fmt, `unsafe.Pointer`) - fmt.buf.AppendByte('(') - if u := v.Pointer(); u != 0 { - fmt.buf.AppendString("0x") - fmt.buf.B = strconv.AppendUint(fmt.buf.B, uint64(u), 16) - } else { - fmt.buf.AppendString(`nil`) - } - fmt.buf.AppendByte(')') - case reflect.Uintptr: - appendType(fmt, `uintptr`) - fmt.buf.AppendByte('(') - if u := v.Uint(); u != 0 { - fmt.buf.AppendString("0x") - fmt.buf.B = strconv.AppendUint(fmt.buf.B, u, 16) - } else { - fmt.buf.AppendString(`nil`) - } - fmt.buf.AppendByte(')') - - // Generic types we don't *exactly* handle - case reflect.Func, reflect.Chan: - if v.IsNil() { - appendNilType(fmt, v.Type().String()) - } else { - fmt.buf.AppendString(v.String()) - } - - // Unhandled kind - default: - fmt.buf.AppendString(v.String()) - } -} - -// appendArrayType Appends an array of unknown type (parsed by reflection) to buf, unlike appendSliceType does NOT catch nil slice. -func appendArrayType(fmt format, v reflect.Value) { - // get no. elements - n := v.Len() - - fmt.buf.AppendByte('[') - - // Append values - for i := 0; i < n; i++ { - appendRValueOrIfaceNext(fmt.SetIsValue(), v.Index(i)) - fmt.buf.AppendByte(',') - } - - // Drop last comma - if n > 0 { - fmt.buf.Truncate(1) - } - - fmt.buf.AppendByte(']') -} - -// appendMapType Appends a map of unknown types (parsed by reflection) to buf. -func appendMapType(fmt format, v reflect.Value) { - // Prepend type if verbose - if fmt.Verbose() { - appendType(fmt, v.Type().String()) - } - - // Get a map iterator - r := v.MapRange() - n := v.Len() - - fmt.buf.AppendByte('{') - - // Iterate pairs - for r.Next() { - appendRValueOrIfaceNext(fmt.SetIsKey(), r.Key()) - fmt.buf.AppendByte('=') - appendRValueOrIfaceNext(fmt.SetIsValue(), r.Value()) - fmt.buf.AppendByte(' ') - } - - // Drop last space - if n > 0 { - fmt.buf.Truncate(1) - } - - fmt.buf.AppendByte('}') -} - -// appendStructType Appends a struct (as a set of key-value fields) to buf. -func appendStructType(fmt format, v reflect.Value) { - // Get value type & no. fields - t := v.Type() - n := v.NumField() - - // Prepend type if verbose - if fmt.Verbose() { - appendType(fmt, v.Type().String()) - } - - fmt.buf.AppendByte('{') - - // Iterate fields - for i := 0; i < n; i++ { - vfield := v.Field(i) - tfield := t.Field(i) - - // Append field name - fmt.buf.AppendString(tfield.Name) - fmt.buf.AppendByte('=') - appendRValueOrIfaceNext(fmt.SetIsValue(), vfield) - - // Iter written count - fmt.buf.AppendByte(' ') - } - - // Drop last space - if n > 0 { - fmt.buf.Truncate(1) - } - - fmt.buf.AppendByte('}') -} - -// containsSpaceOrTab checks if "s" contains space or tabs. -func containsSpaceOrTab(s string) bool { - for _, r := range s { - if r == ' ' || r == '\t' { - return true - } - } - return false -} |