* update github.com/blevesearch/bleve v2.0.2 -> v2.0.3 * github.com/denisenkom/go-mssqldb v0.9.0 -> v0.10.0 * github.com/editorconfig/editorconfig-core-go v2.4.1 -> v2.4.2 * github.com/go-chi/cors v1.1.1 -> v1.2.0 * github.com/go-git/go-billy v5.0.0 -> v5.1.0 * github.com/go-git/go-git v5.2.0 -> v5.3.0 * github.com/go-ldap/ldap v3.2.4 -> v3.3.0 * github.com/go-redis/redis v8.6.0 -> v8.8.2 * github.com/go-sql-driver/mysql v1.5.0 -> v1.6.0 * github.com/go-swagger/go-swagger v0.26.1 -> v0.27.0 * github.com/lib/pq v1.9.0 -> v1.10.1 * github.com/mattn/go-sqlite3 v1.14.6 -> v1.14.7 * github.com/go-testfixtures/testfixtures v3.5.0 -> v3.6.0 * github.com/issue9/identicon v1.0.1 -> v1.2.0 * github.com/klauspost/compress v1.11.8 -> v1.12.1 * github.com/mgechev/revive v1.0.3 -> v1.0.6 * github.com/microcosm-cc/bluemonday v1.0.7 -> v1.0.8 * github.com/niklasfasching/go-org v1.4.0 -> v1.5.0 * github.com/olivere/elastic v7.0.22 -> v7.0.24 * github.com/pelletier/go-toml v1.8.1 -> v1.9.0 * github.com/prometheus/client_golang v1.9.0 -> v1.10.0 * github.com/xanzy/go-gitlab v0.44.0 -> v0.48.0 * github.com/yuin/goldmark v1.3.3 -> v1.3.5 * github.com/6543/go-version v1.2.4 -> v1.3.1 * do github.com/lib/pq v1.10.0 -> v1.10.1 again ...
139 lines
4.4 KiB
Go
Vendored
139 lines
4.4 KiB
Go
Vendored
// Copyright (C) MongoDB, Inc. 2017-present.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
// not use this file except in compliance with the License. You may obtain
|
|
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
package bsoncodec
|
|
|
|
import (
|
|
"reflect"
|
|
"strings"
|
|
)
|
|
|
|
// StructTagParser returns the struct tags for a given struct field.
|
|
type StructTagParser interface {
|
|
ParseStructTags(reflect.StructField) (StructTags, error)
|
|
}
|
|
|
|
// StructTagParserFunc is an adapter that allows a generic function to be used
|
|
// as a StructTagParser.
|
|
type StructTagParserFunc func(reflect.StructField) (StructTags, error)
|
|
|
|
// ParseStructTags implements the StructTagParser interface.
|
|
func (stpf StructTagParserFunc) ParseStructTags(sf reflect.StructField) (StructTags, error) {
|
|
return stpf(sf)
|
|
}
|
|
|
|
// StructTags represents the struct tag fields that the StructCodec uses during
|
|
// the encoding and decoding process.
|
|
//
|
|
// In the case of a struct, the lowercased field name is used as the key for each exported
|
|
// field but this behavior may be changed using a struct tag. The tag may also contain flags to
|
|
// adjust the marshalling behavior for the field.
|
|
//
|
|
// The properties are defined below:
|
|
//
|
|
// 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 integer of a type larger than 32 bits value as an int32, if that's
|
|
// feasible while preserving the numeric value.
|
|
//
|
|
// Truncate When unmarshaling a BSON double, it is permitted to lose precision to fit within
|
|
// a float32.
|
|
//
|
|
// 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.
|
|
//
|
|
// Skip This struct field should be skipped. This is usually denoted by parsing a "-"
|
|
// for the name.
|
|
//
|
|
// TODO(skriptble): Add tags for undefined as nil and for null as nil.
|
|
type StructTags struct {
|
|
Name string
|
|
OmitEmpty bool
|
|
MinSize bool
|
|
Truncate bool
|
|
Inline bool
|
|
Skip bool
|
|
}
|
|
|
|
// DefaultStructTagParser is the StructTagParser used by the StructCodec by default.
|
|
// It will handle the bson struct tag. See the documentation for StructTags to see
|
|
// what each of the returned fields means.
|
|
//
|
|
// If there is no name in the struct tag fields, the struct field name is lowercased.
|
|
// The tag formats accepted are:
|
|
//
|
|
// "[<key>][,<flag1>[,<flag2>]]"
|
|
//
|
|
// `(...) bson:"[<key>][,<flag1>[,<flag2>]]" (...)`
|
|
//
|
|
// An example:
|
|
//
|
|
// 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"
|
|
// }
|
|
//
|
|
// A struct tag either consisting entirely of '-' or with a bson key with a
|
|
// value consisting entirely of '-' will return a StructTags with Skip true and
|
|
// the remaining fields will be their default values.
|
|
var DefaultStructTagParser StructTagParserFunc = func(sf reflect.StructField) (StructTags, error) {
|
|
key := strings.ToLower(sf.Name)
|
|
tag, ok := sf.Tag.Lookup("bson")
|
|
if !ok && !strings.Contains(string(sf.Tag), ":") && len(sf.Tag) > 0 {
|
|
tag = string(sf.Tag)
|
|
}
|
|
return parseTags(key, tag)
|
|
}
|
|
|
|
func parseTags(key string, tag string) (StructTags, error) {
|
|
var st StructTags
|
|
if tag == "-" {
|
|
st.Skip = true
|
|
return st, nil
|
|
}
|
|
|
|
for idx, str := range strings.Split(tag, ",") {
|
|
if idx == 0 && str != "" {
|
|
key = str
|
|
}
|
|
switch str {
|
|
case "omitempty":
|
|
st.OmitEmpty = true
|
|
case "minsize":
|
|
st.MinSize = true
|
|
case "truncate":
|
|
st.Truncate = true
|
|
case "inline":
|
|
st.Inline = true
|
|
}
|
|
}
|
|
|
|
st.Name = key
|
|
|
|
return st, nil
|
|
}
|
|
|
|
// JSONFallbackStructTagParser has the same behavior as DefaultStructTagParser
|
|
// but will also fallback to parsing the json tag instead on a field where the
|
|
// bson tag isn't available.
|
|
var JSONFallbackStructTagParser StructTagParserFunc = func(sf reflect.StructField) (StructTags, error) {
|
|
key := strings.ToLower(sf.Name)
|
|
tag, ok := sf.Tag.Lookup("bson")
|
|
if !ok {
|
|
tag, ok = sf.Tag.Lookup("json")
|
|
}
|
|
if !ok && !strings.Contains(string(sf.Tag), ":") && len(sf.Tag) > 0 {
|
|
tag = string(sf.Tag)
|
|
}
|
|
|
|
return parseTags(key, tag)
|
|
}
|