aboutsummaryrefslogtreecommitdiff
path: root/vendor/gopkg.in/mgo.v2/bson/bson.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gopkg.in/mgo.v2/bson/bson.go')
-rw-r--r--vendor/gopkg.in/mgo.v2/bson/bson.go738
1 files changed, 0 insertions, 738 deletions
diff --git a/vendor/gopkg.in/mgo.v2/bson/bson.go b/vendor/gopkg.in/mgo.v2/bson/bson.go
deleted file mode 100644
index 7fb7f8c..0000000
--- a/vendor/gopkg.in/mgo.v2/bson/bson.go
+++ /dev/null
@@ -1,738 +0,0 @@
-// BSON library for Go
-//
-// Copyright (c) 2010-2012 - Gustavo Niemeyer <gustavo@niemeyer.net>
-//
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice, this
-// list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Package bson is an implementation of the BSON specification for Go:
-//
-// http://bsonspec.org
-//
-// It was created as part of the mgo MongoDB driver for Go, but is standalone
-// and may be used on its own without the driver.
-package bson
-
-import (
- "bytes"
- "crypto/md5"
- "crypto/rand"
- "encoding/binary"
- "encoding/hex"
- "encoding/json"
- "errors"
- "fmt"
- "io"
- "os"
- "reflect"
- "runtime"
- "strings"
- "sync"
- "sync/atomic"
- "time"
-)
-
-// --------------------------------------------------------------------------
-// The public API.
-
-// A value implementing the bson.Getter interface will have its GetBSON
-// method called when the given value has to be marshalled, and the result
-// of this method will be marshaled in place of the actual object.
-//
-// If GetBSON returns return a non-nil error, the marshalling procedure
-// will stop and error out with the provided value.
-type Getter interface {
- GetBSON() (interface{}, error)
-}
-
-// A value implementing the bson.Setter interface will receive the BSON
-// value via the SetBSON method during unmarshaling, and the object
-// itself will not be changed as usual.
-//
-// If setting the value works, the method should return nil or alternatively
-// bson.SetZero to set the respective field to its zero value (nil for
-// pointer types). If SetBSON returns a value of type bson.TypeError, the
-// BSON value will be omitted from a map or slice being decoded and the
-// unmarshalling will continue. If it returns any other non-nil error, the
-// unmarshalling procedure will stop and error out with the provided value.
-//
-// This interface is generally useful in pointer receivers, since the method
-// will want to change the receiver. A type field that implements the Setter
-// interface doesn't have to be a pointer, though.
-//
-// Unlike the usual behavior, unmarshalling onto a value that implements a
-// Setter interface will NOT reset the value to its zero state. This allows
-// the value to decide by itself how to be unmarshalled.
-//
-// For example:
-//
-// type MyString string
-//
-// func (s *MyString) SetBSON(raw bson.Raw) error {
-// return raw.Unmarshal(s)
-// }
-//
-type Setter interface {
- SetBSON(raw Raw) error
-}
-
-// SetZero may be returned from a SetBSON method to have the value set to
-// its respective zero value. When used in pointer values, this will set the
-// field to nil rather than to the pre-allocated value.
-var SetZero = errors.New("set to zero")
-
-// M is a convenient alias for a map[string]interface{} map, useful for
-// dealing with BSON in a native way. For instance:
-//
-// bson.M{"a": 1, "b": true}
-//
-// There's no special handling for this type in addition to what's done anyway
-// for an equivalent map type. Elements in the map will be dumped in an
-// undefined ordered. See also the bson.D type for an ordered alternative.
-type M map[string]interface{}
-
-// D represents a BSON document containing ordered elements. For example:
-//
-// bson.D{{"a", 1}, {"b", true}}
-//
-// In some situations, such as when creating indexes for MongoDB, the order in
-// which the elements are defined is important. If the order is not important,
-// using a map is generally more comfortable. See bson.M and bson.RawD.
-type D []DocElem
-
-// DocElem is an element of the bson.D document representation.
-type DocElem struct {
- Name string
- Value interface{}
-}
-
-// Map returns a map out of the ordered element name/value pairs in d.
-func (d D) Map() (m M) {
- m = make(M, len(d))
- for _, item := range d {
- m[item.Name] = item.Value
- }
- return m
-}
-
-// The Raw type represents raw unprocessed BSON documents and elements.
-// Kind is the kind of element as defined per the BSON specification, and
-// Data is the raw unprocessed data for the respective element.
-// Using this type it is possible to unmarshal or marshal values partially.
-//
-// Relevant documentation:
-//
-// http://bsonspec.org/#/specification
-//
-type Raw struct {
- Kind byte
- Data []byte
-}
-
-// RawD represents a BSON document containing raw unprocessed elements.
-// This low-level representation may be useful when lazily processing
-// documents of uncertain content, or when manipulating the raw content
-// documents in general.
-type RawD []RawDocElem
-
-// See the RawD type.
-type RawDocElem struct {
- Name string
- Value Raw
-}
-
-// ObjectId is a unique ID identifying a BSON value. It must be exactly 12 bytes
-// long. MongoDB objects by default have such a property set in their "_id"
-// property.
-//
-// http://www.mongodb.org/display/DOCS/Object+IDs
-type ObjectId string
-
-// ObjectIdHex returns an ObjectId from the provided hex representation.
-// Calling this function with an invalid hex representation will
-// cause a runtime panic. See the IsObjectIdHex function.
-func ObjectIdHex(s string) ObjectId {
- d, err := hex.DecodeString(s)
- if err != nil || len(d) != 12 {
- panic(fmt.Sprintf("invalid input to ObjectIdHex: %q", s))
- }
- return ObjectId(d)
-}
-
-// IsObjectIdHex returns whether s is a valid hex representation of
-// an ObjectId. See the ObjectIdHex function.
-func IsObjectIdHex(s string) bool {
- if len(s) != 24 {
- return false
- }
- _, err := hex.DecodeString(s)
- return err == nil
-}
-
-// objectIdCounter is atomically incremented when generating a new ObjectId
-// using NewObjectId() function. It's used as a counter part of an id.
-var objectIdCounter uint32 = readRandomUint32()
-
-// readRandomUint32 returns a random objectIdCounter.
-func readRandomUint32() uint32 {
- var b [4]byte
- _, err := io.ReadFull(rand.Reader, b[:])
- if err != nil {
- panic(fmt.Errorf("cannot read random object id: %v", err))
- }
- return uint32((uint32(b[0]) << 0) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24))
-}
-
-// machineId stores machine id generated once and used in subsequent calls
-// to NewObjectId function.
-var machineId = readMachineId()
-var processId = os.Getpid()
-
-// readMachineId generates and returns a machine id.
-// If this function fails to get the hostname it will cause a runtime error.
-func readMachineId() []byte {
- var sum [3]byte
- id := sum[:]
- hostname, err1 := os.Hostname()
- if err1 != nil {
- _, err2 := io.ReadFull(rand.Reader, id)
- if err2 != nil {
- panic(fmt.Errorf("cannot get hostname: %v; %v", err1, err2))
- }
- return id
- }
- hw := md5.New()
- hw.Write([]byte(hostname))
- copy(id, hw.Sum(nil))
- return id
-}
-
-// NewObjectId returns a new unique ObjectId.
-func NewObjectId() ObjectId {
- var b [12]byte
- // Timestamp, 4 bytes, big endian
- binary.BigEndian.PutUint32(b[:], uint32(time.Now().Unix()))
- // Machine, first 3 bytes of md5(hostname)
- b[4] = machineId[0]
- b[5] = machineId[1]
- b[6] = machineId[2]
- // Pid, 2 bytes, specs don't specify endianness, but we use big endian.
- b[7] = byte(processId >> 8)
- b[8] = byte(processId)
- // Increment, 3 bytes, big endian
- i := atomic.AddUint32(&objectIdCounter, 1)
- b[9] = byte(i >> 16)
- b[10] = byte(i >> 8)
- b[11] = byte(i)
- return ObjectId(b[:])
-}
-
-// NewObjectIdWithTime returns a dummy ObjectId with the timestamp part filled
-// with the provided number of seconds from epoch UTC, and all other parts
-// filled with zeroes. It's not safe to insert a document with an id generated
-// by this method, it is useful only for queries to find documents with ids
-// generated before or after the specified timestamp.
-func NewObjectIdWithTime(t time.Time) ObjectId {
- var b [12]byte
- binary.BigEndian.PutUint32(b[:4], uint32(t.Unix()))
- return ObjectId(string(b[:]))
-}
-
-// String returns a hex string representation of the id.
-// Example: ObjectIdHex("4d88e15b60f486e428412dc9").
-func (id ObjectId) String() string {
- return fmt.Sprintf(`ObjectIdHex("%x")`, string(id))
-}
-
-// Hex returns a hex representation of the ObjectId.
-func (id ObjectId) Hex() string {
- return hex.EncodeToString([]byte(id))
-}
-
-// MarshalJSON turns a bson.ObjectId into a json.Marshaller.
-func (id ObjectId) MarshalJSON() ([]byte, error) {
- return []byte(fmt.Sprintf(`"%x"`, string(id))), nil
-}
-
-var nullBytes = []byte("null")
-
-// UnmarshalJSON turns *bson.ObjectId into a json.Unmarshaller.
-func (id *ObjectId) UnmarshalJSON(data []byte) error {
- if len(data) > 0 && (data[0] == '{' || data[0] == 'O') {
- var v struct {
- Id json.RawMessage `json:"$oid"`
- Func struct {
- Id json.RawMessage
- } `json:"$oidFunc"`
- }
- err := jdec(data, &v)
- if err == nil {
- if len(v.Id) > 0 {
- data = []byte(v.Id)
- } else {
- data = []byte(v.Func.Id)
- }
- }
- }
- if len(data) == 2 && data[0] == '"' && data[1] == '"' || bytes.Equal(data, nullBytes) {
- *id = ""
- return nil
- }
- if len(data) != 26 || data[0] != '"' || data[25] != '"' {
- return errors.New(fmt.Sprintf("invalid ObjectId in JSON: %s", string(data)))
- }
- var buf [12]byte
- _, err := hex.Decode(buf[:], data[1:25])
- if err != nil {
- return errors.New(fmt.Sprintf("invalid ObjectId in JSON: %s (%s)", string(data), err))
- }
- *id = ObjectId(string(buf[:]))
- return nil
-}
-
-// MarshalText turns bson.ObjectId into an encoding.TextMarshaler.
-func (id ObjectId) MarshalText() ([]byte, error) {
- return []byte(fmt.Sprintf("%x", string(id))), nil
-}
-
-// UnmarshalText turns *bson.ObjectId into an encoding.TextUnmarshaler.
-func (id *ObjectId) UnmarshalText(data []byte) error {
- if len(data) == 1 && data[0] == ' ' || len(data) == 0 {
- *id = ""
- return nil
- }
- if len(data) != 24 {
- return fmt.Errorf("invalid ObjectId: %s", data)
- }
- var buf [12]byte
- _, err := hex.Decode(buf[:], data[:])
- if err != nil {
- return fmt.Errorf("invalid ObjectId: %s (%s)", data, err)
- }
- *id = ObjectId(string(buf[:]))
- return nil
-}
-
-// Valid returns true if id is valid. A valid id must contain exactly 12 bytes.
-func (id ObjectId) Valid() bool {
- return len(id) == 12
-}
-
-// byteSlice returns byte slice of id from start to end.
-// Calling this function with an invalid id will cause a runtime panic.
-func (id ObjectId) byteSlice(start, end int) []byte {
- if len(id) != 12 {
- panic(fmt.Sprintf("invalid ObjectId: %q", string(id)))
- }
- return []byte(string(id)[start:end])
-}
-
-// Time returns the timestamp part of the id.
-// It's a runtime error to call this method with an invalid id.
-func (id ObjectId) Time() time.Time {
- // First 4 bytes of ObjectId is 32-bit big-endian seconds from epoch.
- secs := int64(binary.BigEndian.Uint32(id.byteSlice(0, 4)))
- return time.Unix(secs, 0)
-}
-
-// Machine returns the 3-byte machine id part of the id.
-// It's a runtime error to call this method with an invalid id.
-func (id ObjectId) Machine() []byte {
- return id.byteSlice(4, 7)
-}
-
-// Pid returns the process id part of the id.
-// It's a runtime error to call this method with an invalid id.
-func (id ObjectId) Pid() uint16 {
- return binary.BigEndian.Uint16(id.byteSlice(7, 9))
-}
-
-// Counter returns the incrementing value part of the id.
-// It's a runtime error to call this method with an invalid id.
-func (id ObjectId) Counter() int32 {
- b := id.byteSlice(9, 12)
- // Counter is stored as big-endian 3-byte value
- return int32(uint32(b[0])<<16 | uint32(b[1])<<8 | uint32(b[2]))
-}
-
-// The Symbol type is similar to a string and is used in languages with a
-// distinct symbol type.
-type Symbol string
-
-// Now returns the current time with millisecond precision. MongoDB stores
-// timestamps with the same precision, so a Time returned from this method
-// will not change after a roundtrip to the database. That's the only reason
-// why this function exists. Using the time.Now function also works fine
-// otherwise.
-func Now() time.Time {
- return time.Unix(0, time.Now().UnixNano()/1e6*1e6)
-}
-
-// MongoTimestamp is a special internal type used by MongoDB that for some
-// strange reason has its own datatype defined in BSON.
-type MongoTimestamp int64
-
-type orderKey int64
-
-// MaxKey is a special value that compares higher than all other possible BSON
-// values in a MongoDB database.
-var MaxKey = orderKey(1<<63 - 1)
-
-// MinKey is a special value that compares lower than all other possible BSON
-// values in a MongoDB database.
-var MinKey = orderKey(-1 << 63)
-
-type undefined struct{}
-
-// Undefined represents the undefined BSON value.
-var Undefined undefined
-
-// Binary is a representation for non-standard binary values. Any kind should
-// work, but the following are known as of this writing:
-//
-// 0x00 - Generic. This is decoded as []byte(data), not Binary{0x00, data}.
-// 0x01 - Function (!?)
-// 0x02 - Obsolete generic.
-// 0x03 - UUID
-// 0x05 - MD5
-// 0x80 - User defined.
-//
-type Binary struct {
- Kind byte
- Data []byte
-}
-
-// RegEx represents a regular expression. The Options field may contain
-// individual characters defining the way in which the pattern should be
-// applied, and must be sorted. Valid options as of this writing are 'i' for
-// case insensitive matching, 'm' for multi-line matching, 'x' for verbose
-// mode, 'l' to make \w, \W, and similar be locale-dependent, 's' for dot-all
-// mode (a '.' matches everything), and 'u' to make \w, \W, and similar match
-// unicode. The value of the Options parameter is not verified before being
-// marshaled into the BSON format.
-type RegEx struct {
- Pattern string
- Options string
-}
-
-// JavaScript is a type that holds JavaScript code. If Scope is non-nil, it
-// will be marshaled as a mapping from identifiers to values that may be
-// used when evaluating the provided Code.
-type JavaScript struct {
- Code string
- Scope interface{}
-}
-
-// DBPointer refers to a document id in a namespace.
-//
-// This type is deprecated in the BSON specification and should not be used
-// except for backwards compatibility with ancient applications.
-type DBPointer struct {
- Namespace string
- Id ObjectId
-}
-
-const initialBufferSize = 64
-
-func handleErr(err *error) {
- if r := recover(); r != nil {
- if _, ok := r.(runtime.Error); ok {
- panic(r)
- } else if _, ok := r.(externalPanic); ok {
- panic(r)
- } else if s, ok := r.(string); ok {
- *err = errors.New(s)
- } else if e, ok := r.(error); ok {
- *err = e
- } else {
- panic(r)
- }
- }
-}
-
-// Marshal serializes the in value, which may be a map or a struct value.
-// In the case of struct values, only exported fields will be serialized,
-// and the order of serialized fields will match that of the struct itself.
-// The lowercased field name is used as the key for each exported field,
-// but this behavior may be changed using the respective field tag.
-// The tag may also contain flags to tweak the marshalling behavior for
-// the field. The tag formats accepted are:
-//
-// "[<key>][,<flag1>[,<flag2>]]"
-//
-// `(...) bson:"[<key>][,<flag1>[,<flag2>]]" (...)`
-//
-// The following flags are currently supported:
-//
-// omitempty Only include the field if it's not set to the zero
-// value for the type or to empty slices or maps.
-//
-// minsize Marshal an int64 value as an int32, if that's feasible
-// while preserving the numeric value.
-//
-// inline Inline the field, which must be a struct or a map,
-// causing all of its fields or keys to be processed as if
-// they were part of the outer struct. For maps, keys must
-// not conflict with the bson keys of other struct fields.
-//
-// Some examples:
-//
-// type T struct {
-// A bool
-// B int "myb"
-// C string "myc,omitempty"
-// D string `bson:",omitempty" json:"jsonkey"`
-// E int64 ",minsize"
-// F int64 "myf,omitempty,minsize"
-// }
-//
-func Marshal(in interface{}) (out []byte, err error) {
- defer handleErr(&err)
- e := &encoder{make([]byte, 0, initialBufferSize)}
- e.addDoc(reflect.ValueOf(in))
- return e.out, nil
-}
-
-// Unmarshal deserializes data from in into the out value. The out value
-// must be a map, a pointer to a struct, or a pointer to a bson.D value.
-// In the case of struct values, only exported fields will be deserialized.
-// The lowercased field name is used as the key for each exported field,
-// but this behavior may be changed using the respective field tag.
-// The tag may also contain flags to tweak the marshalling behavior for
-// the field. The tag formats accepted are:
-//
-// "[<key>][,<flag1>[,<flag2>]]"
-//
-// `(...) bson:"[<key>][,<flag1>[,<flag2>]]" (...)`
-//
-// The following flags are currently supported during unmarshal (see the
-// Marshal method for other flags):
-//
-// inline Inline the field, which must be a struct or a map.
-// Inlined structs are handled as if its fields were part
-// of the outer struct. An inlined map causes keys that do
-// not match any other struct field to be inserted in the
-// map rather than being discarded as usual.
-//
-// The target field or element types of out may not necessarily match
-// the BSON values of the provided data. The following conversions are
-// made automatically:
-//
-// - Numeric types are converted if at least the integer part of the
-// value would be preserved correctly
-// - Bools are converted to numeric types as 1 or 0
-// - Numeric types are converted to bools as true if not 0 or false otherwise
-// - Binary and string BSON data is converted to a string, array or byte slice
-//
-// If the value would not fit the type and cannot be converted, it's
-// silently skipped.
-//
-// Pointer values are initialized when necessary.
-func Unmarshal(in []byte, out interface{}) (err error) {
- if raw, ok := out.(*Raw); ok {
- raw.Kind = 3
- raw.Data = in
- return nil
- }
- defer handleErr(&err)
- v := reflect.ValueOf(out)
- switch v.Kind() {
- case reflect.Ptr:
- fallthrough
- case reflect.Map:
- d := newDecoder(in)
- d.readDocTo(v)
- case reflect.Struct:
- return errors.New("Unmarshal can't deal with struct values. Use a pointer.")
- default:
- return errors.New("Unmarshal needs a map or a pointer to a struct.")
- }
- return nil
-}
-
-// Unmarshal deserializes raw into the out value. If the out value type
-// is not compatible with raw, a *bson.TypeError is returned.
-//
-// See the Unmarshal function documentation for more details on the
-// unmarshalling process.
-func (raw Raw) Unmarshal(out interface{}) (err error) {
- defer handleErr(&err)
- v := reflect.ValueOf(out)
- switch v.Kind() {
- case reflect.Ptr:
- v = v.Elem()
- fallthrough
- case reflect.Map:
- d := newDecoder(raw.Data)
- good := d.readElemTo(v, raw.Kind)
- if !good {
- return &TypeError{v.Type(), raw.Kind}
- }
- case reflect.Struct:
- return errors.New("Raw Unmarshal can't deal with struct values. Use a pointer.")
- default:
- return errors.New("Raw Unmarshal needs a map or a valid pointer.")
- }
- return nil
-}
-
-type TypeError struct {
- Type reflect.Type
- Kind byte
-}
-
-func (e *TypeError) Error() string {
- return fmt.Sprintf("BSON kind 0x%02x isn't compatible with type %s", e.Kind, e.Type.String())
-}
-
-// --------------------------------------------------------------------------
-// Maintain a mapping of keys to structure field indexes
-
-type structInfo struct {
- FieldsMap map[string]fieldInfo
- FieldsList []fieldInfo
- InlineMap int
- Zero reflect.Value
-}
-
-type fieldInfo struct {
- Key string
- Num int
- OmitEmpty bool
- MinSize bool
- Inline []int
-}
-
-var structMap = make(map[reflect.Type]*structInfo)
-var structMapMutex sync.RWMutex
-
-type externalPanic string
-
-func (e externalPanic) String() string {
- return string(e)
-}
-
-func getStructInfo(st reflect.Type) (*structInfo, error) {
- structMapMutex.RLock()
- sinfo, found := structMap[st]
- structMapMutex.RUnlock()
- if found {
- return sinfo, nil
- }
- n := st.NumField()
- fieldsMap := make(map[string]fieldInfo)
- fieldsList := make([]fieldInfo, 0, n)
- inlineMap := -1
- for i := 0; i != n; i++ {
- field := st.Field(i)
- if field.PkgPath != "" && !field.Anonymous {
- continue // Private field
- }
-
- info := fieldInfo{Num: i}
-
- tag := field.Tag.Get("bson")
- if tag == "" && strings.Index(string(field.Tag), ":") < 0 {
- tag = string(field.Tag)
- }
- if tag == "-" {
- continue
- }
-
- inline := false
- fields := strings.Split(tag, ",")
- if len(fields) > 1 {
- for _, flag := range fields[1:] {
- switch flag {
- case "omitempty":
- info.OmitEmpty = true
- case "minsize":
- info.MinSize = true
- case "inline":
- inline = true
- default:
- msg := fmt.Sprintf("Unsupported flag %q in tag %q of type %s", flag, tag, st)
- panic(externalPanic(msg))
- }
- }
- tag = fields[0]
- }
-
- if inline {
- switch field.Type.Kind() {
- case reflect.Map:
- if inlineMap >= 0 {
- return nil, errors.New("Multiple ,inline maps in struct " + st.String())
- }
- if field.Type.Key() != reflect.TypeOf("") {
- return nil, errors.New("Option ,inline needs a map with string keys in struct " + st.String())
- }
- inlineMap = info.Num
- case reflect.Struct:
- sinfo, err := getStructInfo(field.Type)
- if err != nil {
- return nil, err
- }
- for _, finfo := range sinfo.FieldsList {
- if _, found := fieldsMap[finfo.Key]; found {
- msg := "Duplicated key '" + finfo.Key + "' in struct " + st.String()
- return nil, errors.New(msg)
- }
- if finfo.Inline == nil {
- finfo.Inline = []int{i, finfo.Num}
- } else {
- finfo.Inline = append([]int{i}, finfo.Inline...)
- }
- fieldsMap[finfo.Key] = finfo
- fieldsList = append(fieldsList, finfo)
- }
- default:
- panic("Option ,inline needs a struct value or map field")
- }
- continue
- }
-
- if tag != "" {
- info.Key = tag
- } else {
- info.Key = strings.ToLower(field.Name)
- }
-
- if _, found = fieldsMap[info.Key]; found {
- msg := "Duplicated key '" + info.Key + "' in struct " + st.String()
- return nil, errors.New(msg)
- }
-
- fieldsList = append(fieldsList, info)
- fieldsMap[info.Key] = info
- }
- sinfo = &structInfo{
- fieldsMap,
- fieldsList,
- inlineMap,
- reflect.New(st).Elem(),
- }
- structMapMutex.Lock()
- structMap[st] = sinfo
- structMapMutex.Unlock()
- return sinfo, nil
-}