mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
update dependencies
This commit is contained in:
565
vendor/codeberg.org/gruf/go-format/format.go
generated
vendored
Normal file
565
vendor/codeberg.org/gruf/go-format/format.go
generated
vendored
Normal file
@ -0,0 +1,565 @@
|
||||
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
|
||||
}
|
Reference in New Issue
Block a user