route/vendor/gopkg.in/gorethink/gorethink.v2/encoding/tags.go

105 lines
2.1 KiB
Go

// This code is based on encoding/json and gorilla/schema
package encoding
import (
"reflect"
"strconv"
"strings"
"unicode"
)
var (
Tags []string
)
const (
TagName = "gorethink"
JSONTagName = "json"
RefTagName = "gorethink_ref"
)
// tagOptions is the string following a comma in a struct field's
// tag, or the empty string. It does not include the leading comma.
type tagOptions string
func getTag(sf reflect.StructField) string {
if Tags == nil {
return sf.Tag.Get(TagName)
}
for _, tagName := range Tags {
if tag := sf.Tag.Get(tagName); tag != "" {
return tag
}
}
return ""
}
func getRefTag(sf reflect.StructField) string {
return sf.Tag.Get(RefTagName)
}
// parseTag splits a struct field's tag into its name and
// comma-separated options.
func parseTag(tag string) (string, tagOptions) {
if idx := strings.Index(tag, ","); idx != -1 {
return tag[:idx], tagOptions(tag[idx+1:])
}
return tag, tagOptions("")
}
func parseCompoundIndex(tag string) (string, int, bool) {
lIdx := strings.Index(tag, "[")
rIdx := strings.Index(tag, "]")
if lIdx > 1 && rIdx > lIdx+1 {
if elemIndex_, err := strconv.ParseInt(tag[lIdx+1:rIdx], 10, 64); err == nil {
return tag[:lIdx], int(elemIndex_), true
}
}
return tag, 0, false
}
func isValidTag(s string) bool {
if s == "" {
return false
}
for _, c := range s {
switch {
case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c):
// Backslash and quote chars are reserved, but
// otherwise any punctuation chars are allowed
// in a tag name.
default:
if !unicode.IsLetter(c) && !unicode.IsDigit(c) {
return false
}
}
}
return true
}
// Contains returns whether checks that a comma-separated list of options
// contains a particular substr flag. substr must be surrounded by a
// string boundary or commas.
func (o tagOptions) Contains(optionName string) bool {
if len(o) == 0 {
return false
}
s := string(o)
for s != "" {
var next string
i := strings.Index(s, ",")
if i >= 0 {
s, next = s[:i], s[i+1:]
}
if s == optionName {
return true
}
s = next
}
return false
}