mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
This updates our configuration code generator to now also include map marshal and unmarshalers. So we now have much more control over how things get read from pflags, and stored / read from viper configuration. This allows us to set ALL configuration variables by CLI and environment now, AND support nested configuration files. e.g. ```yaml advanced: scraper-deterrence = true http-client: allow-ips = ["127.0.0.1"] ``` is the same as ```yaml advanced-scraper-deterrence = true http-client-allow-ips = ["127.0.0.1"] ``` This also starts cleaning up of our jumbled Configuration{} type by moving the advanced configuration options into their own nested structs, also as a way to show what it's capable of. It's worth noting however that nesting only works if the Go types are nested too (as this is how we hint to our code generator to generate the necessary flattening code :p). closes #3195 Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4109 Co-authored-by: kim <grufwub@gmail.com> Co-committed-by: kim <grufwub@gmail.com>
113 lines
3.7 KiB
Go
113 lines
3.7 KiB
Go
package split
|
|
|
|
import (
|
|
"strconv"
|
|
"time"
|
|
"unsafe"
|
|
|
|
"codeberg.org/gruf/go-bytesize"
|
|
)
|
|
|
|
// joinFunc will join given slice of elements, using the passed function to append each element at index
|
|
// from the slice, forming a combined comma-space separated string. Passed size is for buffer preallocation.
|
|
func JoinFunc[T any](slice []T, each func(buf []byte, value T) []byte, size int) string {
|
|
|
|
// Move nil check
|
|
// outside main loop.
|
|
if each == nil {
|
|
panic("nil func")
|
|
}
|
|
|
|
// Catch easiest case
|
|
if len(slice) == 0 {
|
|
return ""
|
|
}
|
|
|
|
// Preallocate string buffer (size + commas)
|
|
buf := make([]byte, 0, size+len(slice)-1)
|
|
|
|
for _, value := range slice {
|
|
// Append each item
|
|
buf = each(buf, value)
|
|
buf = append(buf, ',', ' ')
|
|
}
|
|
|
|
// Drop final comma-space
|
|
buf = buf[:len(buf)-2]
|
|
|
|
// Directly cast buf to string
|
|
data := unsafe.SliceData(buf)
|
|
return unsafe.String(data, len(buf))
|
|
}
|
|
|
|
// JoinStrings will pass string slice to JoinFunc(), quoting where
|
|
// necessary and combining into a single comma-space separated string.
|
|
func JoinStrings[String ~string](slice []String) string {
|
|
var size int
|
|
for _, str := range slice {
|
|
size += len(str)
|
|
}
|
|
return JoinFunc(slice, func(buf []byte, value String) []byte {
|
|
return appendQuote(buf, string(value))
|
|
}, size)
|
|
}
|
|
|
|
// JoinBools will pass bool slice to JoinFunc(), formatting
|
|
// and combining into a single comma-space separated string.
|
|
func JoinBools[Bool ~bool](slice []Bool) string {
|
|
return JoinFunc(slice, func(buf []byte, value Bool) []byte {
|
|
return strconv.AppendBool(buf, bool(value))
|
|
}, len(slice)*5 /* len("false") */)
|
|
}
|
|
|
|
// JoinInts will pass signed integer slice to JoinFunc(), formatting
|
|
// and combining into a single comma-space separated string.
|
|
func JoinInts[Int Signed](slice []Int) string {
|
|
return JoinFunc(slice, func(buf []byte, value Int) []byte {
|
|
return strconv.AppendInt(buf, int64(value), 10)
|
|
}, len(slice)*20) // max signed int str len
|
|
}
|
|
|
|
// JoinUints will pass unsigned integer slice to JoinFunc(),
|
|
// formatting and combining into a single comma-space separated string.
|
|
func JoinUints[Uint Unsigned](slice []Uint) string {
|
|
return JoinFunc(slice, func(buf []byte, value Uint) []byte {
|
|
return strconv.AppendUint(buf, uint64(value), 10)
|
|
}, len(slice)*20) // max unsigned int str len
|
|
}
|
|
|
|
// JoinFloats will pass float slice to JoinFunc(), formatting
|
|
// and combining into a single comma-space separated string.
|
|
func JoinFloats[Float_ Float](slice []Float_) string {
|
|
bits := int(unsafe.Sizeof(Float_(0)) * 8) // param type bits
|
|
return JoinFunc(slice, func(buf []byte, value Float_) []byte {
|
|
return strconv.AppendFloat(buf, float64(value), 'g', -1, bits)
|
|
}, len(slice)*20) // max signed int str len (it's a good guesstimate)
|
|
}
|
|
|
|
// JoinSizes will pass byte size slice to JoinFunc(), formatting
|
|
// and combining into a single comma-space separated string.
|
|
func JoinSizes(slice []bytesize.Size) string {
|
|
const iecLen = 7 // max IEC string length
|
|
return JoinFunc(slice, func(buf []byte, value bytesize.Size) []byte {
|
|
return value.AppendFormatIEC(buf)
|
|
}, len(slice)*iecLen)
|
|
}
|
|
|
|
// JoinDurations will pass duration slice to JoinFunc(), formatting
|
|
// and combining into a single comma-space separated string.
|
|
func JoinDurations(slice []time.Duration) string {
|
|
const durLen = 10 // max duration string length
|
|
return JoinFunc(slice, func(buf []byte, value time.Duration) []byte {
|
|
return append(buf, value.String()...)
|
|
}, len(slice)*durLen)
|
|
}
|
|
|
|
// JoinTimes will pass time slice to JoinFunc(), formatting
|
|
// and combining into a single comma-space separated string.
|
|
func JoinTimes(slice []time.Time, format string) string {
|
|
return JoinFunc(slice, func(buf []byte, value time.Time) []byte {
|
|
return value.AppendFormat(buf, format)
|
|
}, len(slice)*len(format))
|
|
}
|