// 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]() }