1
0
Fork 0

Adding upstream version 0.8.9.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-05-22 10:16:14 +02:00
parent 3b2c48b5e4
commit c0c4addb85
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
285 changed files with 25880 additions and 0 deletions

134
pkg/format/field_info.go Normal file
View file

@ -0,0 +1,134 @@
package format
import (
"reflect"
"strconv"
"strings"
"github.com/nicholas-fedor/shoutrrr/pkg/types"
"github.com/nicholas-fedor/shoutrrr/pkg/util"
)
// DefaultBase represents the default numeric base (decimal) for fields.
const DefaultBase = 10
// FieldInfo is the meta data about a config field.
type FieldInfo struct {
Name string
Type reflect.Type
EnumFormatter types.EnumFormatter
Description string
DefaultValue string
Template string
Required bool
URLParts []URLPart
Title bool
Base int
Keys []string
ItemSeparator rune
}
// IsEnum returns whether a EnumFormatter has been assigned to the field and that it is of a suitable type.
func (fi *FieldInfo) IsEnum() bool {
return fi.EnumFormatter != nil && fi.Type.Kind() == reflect.Int
}
// IsURLPart returns whether the field is serialized as the specified part of an URL.
func (fi *FieldInfo) IsURLPart(part URLPart) bool {
for _, up := range fi.URLParts {
if up == part {
return true
}
}
return false
}
func getStructFieldInfo(structType reflect.Type, enums map[string]types.EnumFormatter) []FieldInfo {
numFields := structType.NumField()
fields := make([]FieldInfo, 0, numFields)
maxKeyLen := 0
for i := range numFields {
fieldDef := structType.Field(i)
if isHiddenField(fieldDef) {
// This is an embedded or private field, which should not be part of the Config output
continue
}
info := FieldInfo{
Name: fieldDef.Name,
Type: fieldDef.Type,
Required: true,
Title: false,
ItemSeparator: ',',
}
if util.IsNumeric(fieldDef.Type.Kind()) {
info.Base = getFieldBase(fieldDef)
}
if tag, ok := fieldDef.Tag.Lookup("desc"); ok {
info.Description = tag
}
if tag, ok := fieldDef.Tag.Lookup("tpl"); ok {
info.Template = tag
}
if tag, ok := fieldDef.Tag.Lookup("default"); ok {
info.Required = false
info.DefaultValue = tag
}
if _, ok := fieldDef.Tag.Lookup("optional"); ok {
info.Required = false
}
if _, ok := fieldDef.Tag.Lookup("title"); ok {
info.Title = true
}
if tag, ok := fieldDef.Tag.Lookup("url"); ok {
info.URLParts = ParseURLParts(tag)
}
if tag, ok := fieldDef.Tag.Lookup("key"); ok {
tag := strings.ToLower(tag)
info.Keys = strings.Split(tag, ",")
}
if tag, ok := fieldDef.Tag.Lookup("sep"); ok {
info.ItemSeparator = rune(tag[0])
}
if ef, isEnum := enums[fieldDef.Name]; isEnum {
info.EnumFormatter = ef
}
fields = append(fields, info)
keyLen := len(fieldDef.Name)
if keyLen > maxKeyLen {
maxKeyLen = keyLen
}
}
return fields
}
func isHiddenField(field reflect.StructField) bool {
return field.Anonymous || strings.ToUpper(field.Name[0:1]) != field.Name[0:1]
}
func getFieldBase(field reflect.StructField) int {
if tag, ok := field.Tag.Lookup("base"); ok {
if base, err := strconv.ParseUint(tag, 10, 8); err == nil {
return int(base)
}
}
// Default to base 10 if not tagged
return DefaultBase
}