summaryrefslogtreecommitdiffstats
path: root/vendor/google.golang.org/appengine/search/struct.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/google.golang.org/appengine/search/struct.go')
-rw-r--r--vendor/google.golang.org/appengine/search/struct.go251
1 files changed, 0 insertions, 251 deletions
diff --git a/vendor/google.golang.org/appengine/search/struct.go b/vendor/google.golang.org/appengine/search/struct.go
deleted file mode 100644
index e73d2f2ef..000000000
--- a/vendor/google.golang.org/appengine/search/struct.go
+++ /dev/null
@@ -1,251 +0,0 @@
-// 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
-}