2025-08-27 21:03:25 +02:00
|
|
|
// provides more flexible and permissive ways of setting values than reflect.Value.Set
|
2025-08-28 05:04:06 +02:00
|
|
|
// circular type structures not supported
|
|
|
|
|
// it handles scalar fields
|
|
|
|
|
// primary use cases by design are: command line options, environment variables, ini file fields, URL query parameters, HTTP form values
|
2025-08-27 21:03:25 +02:00
|
|
|
package bind
|
|
|
|
|
|
|
|
|
|
type Field struct {
|
2025-08-28 05:04:06 +02:00
|
|
|
path []string
|
2025-08-31 00:40:47 +02:00
|
|
|
name string
|
2025-08-28 05:04:06 +02:00
|
|
|
list bool
|
2025-08-31 00:40:47 +02:00
|
|
|
isBool bool
|
2025-08-28 05:04:06 +02:00
|
|
|
free bool
|
|
|
|
|
value any
|
2025-08-27 21:03:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// the receiver must be addressable
|
|
|
|
|
func BindScalar(receiver any, value ...any) bool {
|
|
|
|
|
return bindScalarReflect(receiver, value)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func BindScalarCreate[T any](value ...any) (T, bool) {
|
|
|
|
|
return bindScalarCreateReflect[T](value)
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-31 00:40:47 +02:00
|
|
|
func ValueByPath(path []string, value any) Field {
|
2025-08-27 21:03:25 +02:00
|
|
|
return Field{path: path, value: value}
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-31 00:40:47 +02:00
|
|
|
func NamedValue(name string, value any) Field {
|
2025-08-27 21:03:25 +02:00
|
|
|
return Field{name: name, value: value}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (f Field) Path() []string {
|
|
|
|
|
p := make([]string, len(f.path))
|
|
|
|
|
copy(p, f.path)
|
|
|
|
|
return p
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-31 00:40:47 +02:00
|
|
|
func (f Field) Name() string {
|
|
|
|
|
if f.name != "" || len(f.path) == 0 {
|
|
|
|
|
return f.name
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nameFromPath(f.path)
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-31 01:23:21 +02:00
|
|
|
func (f Field) List() bool { return f.list }
|
|
|
|
|
func (f Field) Bool() bool { return f.isBool }
|
|
|
|
|
func (f Field) Free() bool { return f.free }
|
|
|
|
|
func (f Field) Value() any { return f.value }
|
2025-08-27 21:03:25 +02:00
|
|
|
|
2025-08-31 00:40:47 +02:00
|
|
|
// it does not return fields with free keys, however, this should be obvious
|
|
|
|
|
// non-struct and non-named map values return unnamed fields
|
2025-08-27 21:03:25 +02:00
|
|
|
func Fields[T any]() []Field {
|
2025-08-28 05:04:06 +02:00
|
|
|
return fieldsReflect[T]()
|
2025-08-27 21:03:25 +02:00
|
|
|
}
|
|
|
|
|
|
2025-08-31 00:40:47 +02:00
|
|
|
// the list and bool flags are not set because it is not possible if they are defined by the root type
|
2025-08-27 21:03:25 +02:00
|
|
|
func FieldValues(structure any) []Field {
|
2025-08-28 05:04:06 +02:00
|
|
|
return fieldValuesReflect(structure)
|
2025-08-27 21:03:25 +02:00
|
|
|
}
|
|
|
|
|
|
2025-08-31 00:40:47 +02:00
|
|
|
func BindFields(structure any, values ...Field) []Field {
|
|
|
|
|
return bindFieldsReflect(structure, values)
|
2025-08-27 21:03:25 +02:00
|
|
|
}
|
|
|
|
|
|
2025-08-31 00:40:47 +02:00
|
|
|
func BindFieldsCreate[T any](values ...Field) (T, []Field) {
|
2025-08-31 01:49:53 +02:00
|
|
|
return bindFieldsCreateReflect[T](values)
|
2025-08-27 21:03:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func AcceptsScalar[T any]() bool {
|
|
|
|
|
return acceptsScalarReflect[T]()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func AcceptsFields[T any]() bool {
|
|
|
|
|
return acceptsFieldsReflect[T]()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func AcceptsList[T any]() bool {
|
|
|
|
|
return acceptsListReflect[T]()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Bindable[T any]() bool {
|
|
|
|
|
return bindableReflect[T]()
|
|
|
|
|
}
|