mirror of
https://github.com/cwinfo/matterbridge.git
synced 2025-07-03 15:27:45 +00:00
Update vendor (#852)
This commit is contained in:
16
vendor/github.com/gorilla/schema/README.md
generated
vendored
16
vendor/github.com/gorilla/schema/README.md
generated
vendored
@ -11,7 +11,7 @@ Package gorilla/schema converts structs to and from form values.
|
||||
Here's a quick example: we parse POST form values and then decode them into a struct:
|
||||
|
||||
```go
|
||||
// Set a Decoder instance as a package global, because it caches
|
||||
// Set a Decoder instance as a package global, because it caches
|
||||
// meta-data about structs, and an instance can be shared safely.
|
||||
var decoder = schema.NewDecoder()
|
||||
|
||||
@ -27,9 +27,9 @@ func MyHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
var person Person
|
||||
|
||||
|
||||
// r.PostForm is a map of our POST form values
|
||||
err := decoder.Decode(&person, r.PostForm)
|
||||
err = decoder.Decode(&person, r.PostForm)
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
@ -64,9 +64,9 @@ To define custom names for fields, use a struct tag "schema". To not populate ce
|
||||
|
||||
```go
|
||||
type Person struct {
|
||||
Name string `schema:"name"` // custom name
|
||||
Phone string `schema:"phone"` // custom name
|
||||
Admin bool `schema:"-"` // this field is never set
|
||||
Name string `schema:"name,required"` // custom name, must be supplied
|
||||
Phone string `schema:"phone"` // custom name
|
||||
Admin bool `schema:"-"` // this field is never set
|
||||
}
|
||||
```
|
||||
|
||||
@ -83,8 +83,8 @@ The supported field types in the struct are:
|
||||
|
||||
Unsupported types are simply ignored, however custom types can be registered to be converted.
|
||||
|
||||
More examples are available on the Gorilla website: http://www.gorillatoolkit.org/pkg/schema
|
||||
More examples are available on the Gorilla website: https://www.gorillatoolkit.org/pkg/schema
|
||||
|
||||
## License
|
||||
## License
|
||||
|
||||
BSD licensed. See the LICENSE file for details.
|
||||
|
81
vendor/github.com/gorilla/schema/cache.go
generated
vendored
81
vendor/github.com/gorilla/schema/cache.go
generated
vendored
@ -117,7 +117,7 @@ func (c *cache) get(t reflect.Type) *structInfo {
|
||||
info := c.m[t]
|
||||
c.l.RUnlock()
|
||||
if info == nil {
|
||||
info = c.create(t, nil)
|
||||
info = c.create(t, "")
|
||||
c.l.Lock()
|
||||
c.m[t] = info
|
||||
c.l.Unlock()
|
||||
@ -126,37 +126,40 @@ func (c *cache) get(t reflect.Type) *structInfo {
|
||||
}
|
||||
|
||||
// create creates a structInfo with meta-data about a struct.
|
||||
func (c *cache) create(t reflect.Type, info *structInfo) *structInfo {
|
||||
if info == nil {
|
||||
info = &structInfo{fields: []*fieldInfo{}}
|
||||
}
|
||||
func (c *cache) create(t reflect.Type, parentAlias string) *structInfo {
|
||||
info := &structInfo{}
|
||||
var anonymousInfos []*structInfo
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
if field.Anonymous {
|
||||
ft := field.Type
|
||||
if ft.Kind() == reflect.Ptr {
|
||||
ft = ft.Elem()
|
||||
}
|
||||
if ft.Kind() == reflect.Struct {
|
||||
bef := len(info.fields)
|
||||
c.create(ft, info)
|
||||
for _, fi := range info.fields[bef:len(info.fields)] {
|
||||
// exclude required check because duplicated to embedded field
|
||||
fi.isRequired = false
|
||||
}
|
||||
if f := c.createField(t.Field(i), parentAlias); f != nil {
|
||||
info.fields = append(info.fields, f)
|
||||
if ft := indirectType(f.typ); ft.Kind() == reflect.Struct && f.isAnonymous {
|
||||
anonymousInfos = append(anonymousInfos, c.create(ft, f.canonicalAlias))
|
||||
}
|
||||
}
|
||||
}
|
||||
for i, a := range anonymousInfos {
|
||||
others := []*structInfo{info}
|
||||
others = append(others, anonymousInfos[:i]...)
|
||||
others = append(others, anonymousInfos[i+1:]...)
|
||||
for _, f := range a.fields {
|
||||
if !containsAlias(others, f.alias) {
|
||||
info.fields = append(info.fields, f)
|
||||
}
|
||||
}
|
||||
c.createField(field, info)
|
||||
}
|
||||
return info
|
||||
}
|
||||
|
||||
// createField creates a fieldInfo for the given field.
|
||||
func (c *cache) createField(field reflect.StructField, info *structInfo) {
|
||||
func (c *cache) createField(field reflect.StructField, parentAlias string) *fieldInfo {
|
||||
alias, options := fieldAlias(field, c.tag)
|
||||
if alias == "-" {
|
||||
// Ignore this field.
|
||||
return
|
||||
return nil
|
||||
}
|
||||
canonicalAlias := alias
|
||||
if parentAlias != "" {
|
||||
canonicalAlias = parentAlias + "." + alias
|
||||
}
|
||||
// Check if the type is supported and don't cache it if not.
|
||||
// First let's get the basic type.
|
||||
@ -181,19 +184,20 @@ func (c *cache) createField(field reflect.StructField, info *structInfo) {
|
||||
if isStruct = ft.Kind() == reflect.Struct; !isStruct {
|
||||
if c.converter(ft) == nil && builtinConverters[ft.Kind()] == nil {
|
||||
// Type is not supported.
|
||||
return
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
info.fields = append(info.fields, &fieldInfo{
|
||||
return &fieldInfo{
|
||||
typ: field.Type,
|
||||
name: field.Name,
|
||||
alias: alias,
|
||||
canonicalAlias: canonicalAlias,
|
||||
unmarshalerInfo: m,
|
||||
isSliceOfStructs: isSlice && isStruct,
|
||||
isAnonymous: field.Anonymous,
|
||||
isRequired: options.Contains("required"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// converter returns the converter for a type.
|
||||
@ -216,11 +220,26 @@ func (i *structInfo) get(alias string) *fieldInfo {
|
||||
return nil
|
||||
}
|
||||
|
||||
func containsAlias(infos []*structInfo, alias string) bool {
|
||||
for _, info := range infos {
|
||||
if info.get(alias) != nil {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type fieldInfo struct {
|
||||
typ reflect.Type
|
||||
// name is the field name in the struct.
|
||||
name string
|
||||
alias string
|
||||
// canonicalAlias is almost the same as the alias, but is prefixed with
|
||||
// an embedded struct field alias in dotted notation if this field is
|
||||
// promoted from the struct.
|
||||
// For instance, if the alias is "N" and this field is an embedded field
|
||||
// in a struct "X", canonicalAlias will be "X.N".
|
||||
canonicalAlias string
|
||||
// unmarshalerInfo contains information regarding the
|
||||
// encoding.TextUnmarshaler implementation of the field type.
|
||||
unmarshalerInfo unmarshaler
|
||||
@ -231,6 +250,13 @@ type fieldInfo struct {
|
||||
isRequired bool
|
||||
}
|
||||
|
||||
func (f *fieldInfo) paths(prefix string) []string {
|
||||
if f.alias == f.canonicalAlias {
|
||||
return []string{prefix + f.alias}
|
||||
}
|
||||
return []string{prefix + f.alias, prefix + f.canonicalAlias}
|
||||
}
|
||||
|
||||
type pathPart struct {
|
||||
field *fieldInfo
|
||||
path []string // path to the field: walks structs using field names.
|
||||
@ -239,6 +265,13 @@ type pathPart struct {
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
func indirectType(typ reflect.Type) reflect.Type {
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
return typ.Elem()
|
||||
}
|
||||
return typ
|
||||
}
|
||||
|
||||
// fieldAlias parses a field tag to get a field alias.
|
||||
func fieldAlias(field reflect.StructField, tagName string) (alias string, options tagOptions) {
|
||||
if tag := field.Tag.Get(tagName); tag != "" {
|
||||
|
99
vendor/github.com/gorilla/schema/decoder.go
generated
vendored
99
vendor/github.com/gorilla/schema/decoder.go
generated
vendored
@ -81,52 +81,83 @@ func (d *Decoder) Decode(dst interface{}, src map[string][]string) error {
|
||||
errors[path] = err
|
||||
}
|
||||
} else if !d.ignoreUnknownKeys {
|
||||
errors[path] = fmt.Errorf("schema: invalid path %q", path)
|
||||
errors[path] = UnknownKeyError{Key: path}
|
||||
}
|
||||
}
|
||||
errors.merge(d.checkRequired(t, src))
|
||||
if len(errors) > 0 {
|
||||
return errors
|
||||
}
|
||||
return d.checkRequired(t, src, "")
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkRequired checks whether required fields are empty
|
||||
//
|
||||
// check type t recursively if t has struct fields, and prefix is same as parsePath: in dotted notation
|
||||
// check type t recursively if t has struct fields.
|
||||
//
|
||||
// src is the source map for decoding, we use it here to see if those required fields are included in src
|
||||
func (d *Decoder) checkRequired(t reflect.Type, src map[string][]string, prefix string) error {
|
||||
func (d *Decoder) checkRequired(t reflect.Type, src map[string][]string) MultiError {
|
||||
m, errs := d.findRequiredFields(t, "", "")
|
||||
for key, fields := range m {
|
||||
if isEmptyFields(fields, src) {
|
||||
errs[key] = EmptyFieldError{Key: key}
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
// findRequiredFields recursively searches the struct type t for required fields.
|
||||
//
|
||||
// canonicalPrefix and searchPrefix are used to resolve full paths in dotted notation
|
||||
// for nested struct fields. canonicalPrefix is a complete path which never omits
|
||||
// any embedded struct fields. searchPrefix is a user-friendly path which may omit
|
||||
// some embedded struct fields to point promoted fields.
|
||||
func (d *Decoder) findRequiredFields(t reflect.Type, canonicalPrefix, searchPrefix string) (map[string][]fieldWithPrefix, MultiError) {
|
||||
struc := d.cache.get(t)
|
||||
if struc == nil {
|
||||
// unexpect, cache.get never return nil
|
||||
return errors.New("cache fail")
|
||||
return nil, MultiError{canonicalPrefix + "*": errors.New("cache fail")}
|
||||
}
|
||||
|
||||
m := map[string][]fieldWithPrefix{}
|
||||
errs := MultiError{}
|
||||
for _, f := range struc.fields {
|
||||
if f.typ.Kind() == reflect.Struct {
|
||||
err := d.checkRequired(f.typ, src, prefix+f.alias+".")
|
||||
if err != nil {
|
||||
if !f.isAnonymous {
|
||||
return err
|
||||
}
|
||||
// check embedded parent field.
|
||||
err2 := d.checkRequired(f.typ, src, prefix)
|
||||
if err2 != nil {
|
||||
return err
|
||||
fcprefix := canonicalPrefix + f.canonicalAlias + "."
|
||||
for _, fspath := range f.paths(searchPrefix) {
|
||||
fm, ferrs := d.findRequiredFields(f.typ, fcprefix, fspath+".")
|
||||
for key, fields := range fm {
|
||||
m[key] = append(m[key], fields...)
|
||||
}
|
||||
errs.merge(ferrs)
|
||||
}
|
||||
}
|
||||
if f.isRequired {
|
||||
key := f.alias
|
||||
if prefix != "" {
|
||||
key = prefix + key
|
||||
}
|
||||
if isEmpty(f.typ, src[key]) {
|
||||
return fmt.Errorf("%v is empty", key)
|
||||
key := canonicalPrefix + f.canonicalAlias
|
||||
m[key] = append(m[key], fieldWithPrefix{
|
||||
fieldInfo: f,
|
||||
prefix: searchPrefix,
|
||||
})
|
||||
}
|
||||
}
|
||||
return m, errs
|
||||
}
|
||||
|
||||
type fieldWithPrefix struct {
|
||||
*fieldInfo
|
||||
prefix string
|
||||
}
|
||||
|
||||
// isEmptyFields returns true if all of specified fields are empty.
|
||||
func isEmptyFields(fields []fieldWithPrefix, src map[string][]string) bool {
|
||||
for _, f := range fields {
|
||||
for _, path := range f.paths(f.prefix) {
|
||||
if !isEmpty(f.typ, src[path]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return true
|
||||
}
|
||||
|
||||
// isEmpty returns true if value is empty for specific type
|
||||
@ -424,6 +455,24 @@ func (e ConversionError) Error() string {
|
||||
return output
|
||||
}
|
||||
|
||||
// UnknownKeyError stores information about an unknown key in the source map.
|
||||
type UnknownKeyError struct {
|
||||
Key string // key from the source map.
|
||||
}
|
||||
|
||||
func (e UnknownKeyError) Error() string {
|
||||
return fmt.Sprintf("schema: invalid path %q", e.Key)
|
||||
}
|
||||
|
||||
// EmptyFieldError stores information about an empty required field.
|
||||
type EmptyFieldError struct {
|
||||
Key string // required key in the source map.
|
||||
}
|
||||
|
||||
func (e EmptyFieldError) Error() string {
|
||||
return fmt.Sprintf("%v is empty", e.Key)
|
||||
}
|
||||
|
||||
// MultiError stores multiple decoding errors.
|
||||
//
|
||||
// Borrowed from the App Engine SDK.
|
||||
@ -445,3 +494,11 @@ func (e MultiError) Error() string {
|
||||
}
|
||||
return fmt.Sprintf("%s (and %d other errors)", s, len(e)-1)
|
||||
}
|
||||
|
||||
func (e MultiError) merge(errors MultiError) {
|
||||
for key, err := range errors {
|
||||
if e[key] == nil {
|
||||
e[key] = err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user