Switch to using the dep tool and update all the dependencies
This commit is contained in:
parent
5135ff73cb
commit
98c2d2c41b
5321 changed files with 4483201 additions and 5922 deletions
251
vendor/google.golang.org/appengine/search/struct.go
generated
vendored
Normal file
251
vendor/google.golang.org/appengine/search/struct.go
generated
vendored
Normal file
|
@ -0,0 +1,251 @@
|
|||
// Copyright 2015 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by the Apache 2.0
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package search
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// ErrFieldMismatch is returned when a field is to be loaded into a different
|
||||
// than the one it was stored from, or when a field is missing or unexported in
|
||||
// the destination struct.
|
||||
type ErrFieldMismatch struct {
|
||||
FieldName string
|
||||
Reason string
|
||||
}
|
||||
|
||||
func (e *ErrFieldMismatch) Error() string {
|
||||
return fmt.Sprintf("search: cannot load field %q: %s", e.FieldName, e.Reason)
|
||||
}
|
||||
|
||||
// ErrFacetMismatch is returned when a facet is to be loaded into a different
|
||||
// type than the one it was stored from, or when a field is missing or
|
||||
// unexported in the destination struct. StructType is the type of the struct
|
||||
// pointed to by the destination argument passed to Iterator.Next.
|
||||
type ErrFacetMismatch struct {
|
||||
StructType reflect.Type
|
||||
FacetName string
|
||||
Reason string
|
||||
}
|
||||
|
||||
func (e *ErrFacetMismatch) Error() string {
|
||||
return fmt.Sprintf("search: cannot load facet %q into a %q: %s", e.FacetName, e.StructType, e.Reason)
|
||||
}
|
||||
|
||||
// structCodec defines how to convert a given struct to/from a search document.
|
||||
type structCodec struct {
|
||||
// byIndex returns the struct tag for the i'th struct field.
|
||||
byIndex []structTag
|
||||
|
||||
// fieldByName returns the index of the struct field for the given field name.
|
||||
fieldByName map[string]int
|
||||
|
||||
// facetByName returns the index of the struct field for the given facet name,
|
||||
facetByName map[string]int
|
||||
}
|
||||
|
||||
// structTag holds a structured version of each struct field's parsed tag.
|
||||
type structTag struct {
|
||||
name string
|
||||
facet bool
|
||||
ignore bool
|
||||
}
|
||||
|
||||
var (
|
||||
codecsMu sync.RWMutex
|
||||
codecs = map[reflect.Type]*structCodec{}
|
||||
)
|
||||
|
||||
func loadCodec(t reflect.Type) (*structCodec, error) {
|
||||
codecsMu.RLock()
|
||||
codec, ok := codecs[t]
|
||||
codecsMu.RUnlock()
|
||||
if ok {
|
||||
return codec, nil
|
||||
}
|
||||
|
||||
codecsMu.Lock()
|
||||
defer codecsMu.Unlock()
|
||||
if codec, ok := codecs[t]; ok {
|
||||
return codec, nil
|
||||
}
|
||||
|
||||
codec = &structCodec{
|
||||
fieldByName: make(map[string]int),
|
||||
facetByName: make(map[string]int),
|
||||
}
|
||||
|
||||
for i, I := 0, t.NumField(); i < I; i++ {
|
||||
f := t.Field(i)
|
||||
name, opts := f.Tag.Get("search"), ""
|
||||
if i := strings.Index(name, ","); i != -1 {
|
||||
name, opts = name[:i], name[i+1:]
|
||||
}
|
||||
ignore := false
|
||||
if name == "-" {
|
||||
ignore = true
|
||||
} else if name == "" {
|
||||
name = f.Name
|
||||
} else if !validFieldName(name) {
|
||||
return nil, fmt.Errorf("search: struct tag has invalid field name: %q", name)
|
||||
}
|
||||
facet := opts == "facet"
|
||||
codec.byIndex = append(codec.byIndex, structTag{name: name, facet: facet, ignore: ignore})
|
||||
if facet {
|
||||
codec.facetByName[name] = i
|
||||
} else {
|
||||
codec.fieldByName[name] = i
|
||||
}
|
||||
}
|
||||
|
||||
codecs[t] = codec
|
||||
return codec, nil
|
||||
}
|
||||
|
||||
// structFLS adapts a struct to be a FieldLoadSaver.
|
||||
type structFLS struct {
|
||||
v reflect.Value
|
||||
codec *structCodec
|
||||
}
|
||||
|
||||
func (s structFLS) Load(fields []Field, meta *DocumentMetadata) error {
|
||||
var err error
|
||||
for _, field := range fields {
|
||||
i, ok := s.codec.fieldByName[field.Name]
|
||||
if !ok {
|
||||
// Note the error, but keep going.
|
||||
err = &ErrFieldMismatch{
|
||||
FieldName: field.Name,
|
||||
Reason: "no such struct field",
|
||||
}
|
||||
continue
|
||||
|
||||
}
|
||||
f := s.v.Field(i)
|
||||
if !f.CanSet() {
|
||||
// Note the error, but keep going.
|
||||
err = &ErrFieldMismatch{
|
||||
FieldName: field.Name,
|
||||
Reason: "cannot set struct field",
|
||||
}
|
||||
continue
|
||||
}
|
||||
v := reflect.ValueOf(field.Value)
|
||||
if ft, vt := f.Type(), v.Type(); ft != vt {
|
||||
err = &ErrFieldMismatch{
|
||||
FieldName: field.Name,
|
||||
Reason: fmt.Sprintf("type mismatch: %v for %v data", ft, vt),
|
||||
}
|
||||
continue
|
||||
}
|
||||
f.Set(v)
|
||||
}
|
||||
if meta == nil {
|
||||
return err
|
||||
}
|
||||
for _, facet := range meta.Facets {
|
||||
i, ok := s.codec.facetByName[facet.Name]
|
||||
if !ok {
|
||||
// Note the error, but keep going.
|
||||
if err == nil {
|
||||
err = &ErrFacetMismatch{
|
||||
StructType: s.v.Type(),
|
||||
FacetName: facet.Name,
|
||||
Reason: "no matching field found",
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
f := s.v.Field(i)
|
||||
if !f.CanSet() {
|
||||
// Note the error, but keep going.
|
||||
if err == nil {
|
||||
err = &ErrFacetMismatch{
|
||||
StructType: s.v.Type(),
|
||||
FacetName: facet.Name,
|
||||
Reason: "unable to set unexported field of struct",
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
v := reflect.ValueOf(facet.Value)
|
||||
if ft, vt := f.Type(), v.Type(); ft != vt {
|
||||
if err == nil {
|
||||
err = &ErrFacetMismatch{
|
||||
StructType: s.v.Type(),
|
||||
FacetName: facet.Name,
|
||||
Reason: fmt.Sprintf("type mismatch: %v for %d data", ft, vt),
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
f.Set(v)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (s structFLS) Save() ([]Field, *DocumentMetadata, error) {
|
||||
fields := make([]Field, 0, len(s.codec.fieldByName))
|
||||
var facets []Facet
|
||||
for i, tag := range s.codec.byIndex {
|
||||
if tag.ignore {
|
||||
continue
|
||||
}
|
||||
f := s.v.Field(i)
|
||||
if !f.CanSet() {
|
||||
continue
|
||||
}
|
||||
if tag.facet {
|
||||
facets = append(facets, Facet{Name: tag.name, Value: f.Interface()})
|
||||
} else {
|
||||
fields = append(fields, Field{Name: tag.name, Value: f.Interface()})
|
||||
}
|
||||
}
|
||||
return fields, &DocumentMetadata{Facets: facets}, nil
|
||||
}
|
||||
|
||||
// newStructFLS returns a FieldLoadSaver for the struct pointer p.
|
||||
func newStructFLS(p interface{}) (FieldLoadSaver, error) {
|
||||
v := reflect.ValueOf(p)
|
||||
if v.Kind() != reflect.Ptr || v.IsNil() || v.Elem().Kind() != reflect.Struct {
|
||||
return nil, ErrInvalidDocumentType
|
||||
}
|
||||
codec, err := loadCodec(v.Elem().Type())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return structFLS{v.Elem(), codec}, nil
|
||||
}
|
||||
|
||||
func loadStructWithMeta(dst interface{}, f []Field, meta *DocumentMetadata) error {
|
||||
x, err := newStructFLS(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return x.Load(f, meta)
|
||||
}
|
||||
|
||||
func saveStructWithMeta(src interface{}) ([]Field, *DocumentMetadata, error) {
|
||||
x, err := newStructFLS(src)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return x.Save()
|
||||
}
|
||||
|
||||
// LoadStruct loads the fields from f to dst. dst must be a struct pointer.
|
||||
func LoadStruct(dst interface{}, f []Field) error {
|
||||
return loadStructWithMeta(dst, f, nil)
|
||||
}
|
||||
|
||||
// SaveStruct returns the fields from src as a slice of Field.
|
||||
// src must be a struct pointer.
|
||||
func SaveStruct(src interface{}) ([]Field, error) {
|
||||
f, _, err := saveStructWithMeta(src)
|
||||
return f, err
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue