github.com/searKing/golang/go@v1.2.117/reflect/tags.go (about)

     1  // Copyright 2020 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package reflect
     6  
     7  import (
     8  	"strings"
     9  	"unicode"
    10  )
    11  
    12  // TagOptions is the string following a comma in a struct field's "json"
    13  // tag, or the empty string. It does not include the leading comma.
    14  type TagOptions string
    15  
    16  // ParseTagOptions splits a struct field's json tag into its name and
    17  // comma-separated options.
    18  func ParseTagOptions(tag string) (tagName string, opts TagOptions) {
    19  	if idx := strings.Index(tag, ","); idx != -1 {
    20  		return tag[:idx], TagOptions(tag[idx+1:])
    21  	}
    22  	return tag, TagOptions("")
    23  }
    24  
    25  // Contains reports whether a comma-separated list of options
    26  // contains a particular substr flag. substr must be surrounded by a
    27  // string boundary or commas.
    28  func (o TagOptions) Contains(optionName string) bool {
    29  	if len(o) == 0 {
    30  		return false
    31  	}
    32  	s := string(o)
    33  	for s != "" {
    34  		var next string
    35  		i := strings.Index(s, ",")
    36  		if i >= 0 {
    37  			s, next = s[:i], s[i+1:]
    38  		}
    39  		if s == optionName {
    40  			return true
    41  		}
    42  		s = next
    43  	}
    44  	return false
    45  }
    46  
    47  // IsValidTagKey checks if key of struct tag, like `json:"name,omitempty"`, is valid
    48  func IsValidTagKey(tagKey string) bool {
    49  	if tagKey == "" {
    50  		return false
    51  	}
    52  	for _, c := range tagKey {
    53  		switch {
    54  		case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c):
    55  			// Backslash and quote chars are reserved, but
    56  			// otherwise any punctuation chars are allowed
    57  			// in a tag name.
    58  		default:
    59  			if !unicode.IsLetter(c) && !unicode.IsDigit(c) {
    60  				return false
    61  			}
    62  		}
    63  	}
    64  	return true
    65  }