mirror of
https://github.com/minio/minio.git
synced 2025-01-29 15:35:58 -05:00
61175ef091
- over the course of a project history every maintainer needs to update its dependency packages, the problem essentially with godep is manipulating GOPATH - this manipulation leads to static objects created at different locations which end up conflicting with the overall functionality of golang. This also leads to broken builds. There is no easier way out of this other than asking developers to do 'godep restore' all the time. Which perhaps as a practice doesn't sound like a clean solution. On the other hand 'godep restore' has its own set of problems. - govendor is a right tool but a stop gap tool until we wait for golangs official 1.5 version which fixes this vendoring issue once and for all. - govendor provides consistency in terms of how import paths should be handled unlike manipulation GOPATH. This has advantages - no more compiled objects being referenced in GOPATH and build time GOPATH manging which leads to conflicts. - proper import paths referencing the exact package a project is dependent on. govendor is simple and provides the minimal necessary tooling to achieve this. For now this is the right solution.
127 lines
3.2 KiB
Go
127 lines
3.2 KiB
Go
package structs
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"reflect"
|
|
)
|
|
|
|
var (
|
|
errNotExported = errors.New("field is not exported")
|
|
errNotSettable = errors.New("field is not settable")
|
|
)
|
|
|
|
// Field represents a single struct field that encapsulates high level
|
|
// functions around the field.
|
|
type Field struct {
|
|
value reflect.Value
|
|
field reflect.StructField
|
|
defaultTag string
|
|
}
|
|
|
|
// Tag returns the value associated with key in the tag string. If there is no
|
|
// such key in the tag, Tag returns the empty string.
|
|
func (f *Field) Tag(key string) string {
|
|
return f.field.Tag.Get(key)
|
|
}
|
|
|
|
// Value returns the underlying value of of the field. It panics if the field
|
|
// is not exported.
|
|
func (f *Field) Value() interface{} {
|
|
return f.value.Interface()
|
|
}
|
|
|
|
// IsEmbedded returns true if the given field is an anonymous field (embedded)
|
|
func (f *Field) IsEmbedded() bool {
|
|
return f.field.Anonymous
|
|
}
|
|
|
|
// IsExported returns true if the given field is exported.
|
|
func (f *Field) IsExported() bool {
|
|
return f.field.PkgPath == ""
|
|
}
|
|
|
|
// IsZero returns true if the given field is not initalized (has a zero value).
|
|
// It panics if the field is not exported.
|
|
func (f *Field) IsZero() bool {
|
|
zero := reflect.Zero(f.value.Type()).Interface()
|
|
current := f.Value()
|
|
|
|
return reflect.DeepEqual(current, zero)
|
|
}
|
|
|
|
// Name returns the name of the given field
|
|
func (f *Field) Name() string {
|
|
return f.field.Name
|
|
}
|
|
|
|
// Kind returns the fields kind, such as "string", "map", "bool", etc ..
|
|
func (f *Field) Kind() reflect.Kind {
|
|
return f.value.Kind()
|
|
}
|
|
|
|
// Set sets the field to given value v. It retuns an error if the field is not
|
|
// settable (not addresable or not exported) or if the given value's type
|
|
// doesn't match the fields type.
|
|
func (f *Field) Set(val interface{}) error {
|
|
// we can't set unexported fields, so be sure this field is exported
|
|
if !f.IsExported() {
|
|
return errNotExported
|
|
}
|
|
|
|
// do we get here? not sure...
|
|
if !f.value.CanSet() {
|
|
return errNotSettable
|
|
}
|
|
|
|
given := reflect.ValueOf(val)
|
|
|
|
if f.value.Kind() != given.Kind() {
|
|
return fmt.Errorf("wrong kind. got: %s want: %s", given.Kind(), f.value.Kind())
|
|
}
|
|
|
|
f.value.Set(given)
|
|
return nil
|
|
}
|
|
|
|
// Fields returns a slice of Fields. This is particular handy to get the fields
|
|
// of a nested struct . A struct tag with the content of "-" ignores the
|
|
// checking of that particular field. Example:
|
|
//
|
|
// // Field is ignored by this package.
|
|
// Field *http.Request `structs:"-"`
|
|
//
|
|
// It panics if field is not exported or if field's kind is not struct
|
|
func (f *Field) Fields() []*Field {
|
|
return getFields(f.value, f.defaultTag)
|
|
}
|
|
|
|
// Field returns the field from a nested struct. It panics if the nested struct
|
|
// is not exported or if the field was not found.
|
|
func (f *Field) Field(name string) *Field {
|
|
field, ok := f.FieldOk(name)
|
|
if !ok {
|
|
panic("field not found")
|
|
}
|
|
|
|
return field
|
|
}
|
|
|
|
// Field returns the field from a nested struct. The boolean returns true if
|
|
// the field was found. It panics if the nested struct is not exported or if
|
|
// the field was not found.
|
|
func (f *Field) FieldOk(name string) (*Field, bool) {
|
|
v := strctVal(f.value.Interface())
|
|
t := v.Type()
|
|
|
|
field, ok := t.FieldByName(name)
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
|
|
return &Field{
|
|
field: field,
|
|
value: v.FieldByName(name),
|
|
}, true
|
|
}
|