1
0
bind/lib.go

100 lines
2.2 KiB
Go

// provides more flexible and permissive ways of setting values than reflect.Value.Set
// 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
// traverses pointers, slices, wrapper interfaces
package bind
type Scalar int
const (
Any Scalar = iota
Bool
Int
Uint
Float
String
)
type Field struct {
path []string
name string
list bool
typ Scalar
size int
free bool
value any
}
// 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)
}
func ValueByPath(path []string, value any) Field {
return Field{path: path, value: value}
}
func NamedValue(name string, value any) Field {
return Field{name: name, value: value}
}
func (f Field) Path() []string {
p := make([]string, len(f.path))
copy(p, f.path)
return p
}
func (f Field) Name() string {
if f.name != "" || len(f.path) == 0 {
return f.name
}
return nameFromPath(f.path)
}
func (f Field) List() bool { return f.list }
func (f Field) Type() Scalar { return f.typ }
func (f Field) Size() int { return f.size }
func (f Field) Free() bool { return f.free }
func (f Field) Value() any { return f.value }
// it does not return fields with free keys, however, this should be obvious
// non-struct and non-named map values return unnamed fields
func Fields[T any]() []Field {
return fieldsReflect[T]()
}
// the list and bool flags are not set because it is not possible if they are defined by the root type
func FieldValues(structure any) []Field {
return fieldValuesReflect(structure)
}
func BindFields(structure any, values ...Field) []Field {
return bindFieldsReflect(structure, values)
}
func BindFieldsCreate[T any](values ...Field) (T, []Field) {
return bindFieldsCreateReflect[T](values)
}
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]()
}