gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

struct_field.go (1640B)


      1 package runtime
      2 
      3 import (
      4 	"reflect"
      5 	"strings"
      6 	"unicode"
      7 )
      8 
      9 func getTag(field reflect.StructField) string {
     10 	return field.Tag.Get("json")
     11 }
     12 
     13 func IsIgnoredStructField(field reflect.StructField) bool {
     14 	if field.PkgPath != "" {
     15 		if field.Anonymous {
     16 			t := field.Type
     17 			if t.Kind() == reflect.Ptr {
     18 				t = t.Elem()
     19 			}
     20 			if t.Kind() != reflect.Struct {
     21 				return true
     22 			}
     23 		} else {
     24 			// private field
     25 			return true
     26 		}
     27 	}
     28 	tag := getTag(field)
     29 	return tag == "-"
     30 }
     31 
     32 type StructTag struct {
     33 	Key         string
     34 	IsTaggedKey bool
     35 	IsOmitEmpty bool
     36 	IsString    bool
     37 	Field       reflect.StructField
     38 }
     39 
     40 type StructTags []*StructTag
     41 
     42 func (t StructTags) ExistsKey(key string) bool {
     43 	for _, tt := range t {
     44 		if tt.Key == key {
     45 			return true
     46 		}
     47 	}
     48 	return false
     49 }
     50 
     51 func isValidTag(s string) bool {
     52 	if s == "" {
     53 		return false
     54 	}
     55 	for _, c := range s {
     56 		switch {
     57 		case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c):
     58 			// Backslash and quote chars are reserved, but
     59 			// otherwise any punctuation chars are allowed
     60 			// in a tag name.
     61 		case !unicode.IsLetter(c) && !unicode.IsDigit(c):
     62 			return false
     63 		}
     64 	}
     65 	return true
     66 }
     67 
     68 func StructTagFromField(field reflect.StructField) *StructTag {
     69 	keyName := field.Name
     70 	tag := getTag(field)
     71 	st := &StructTag{Field: field}
     72 	opts := strings.Split(tag, ",")
     73 	if len(opts) > 0 {
     74 		if opts[0] != "" && isValidTag(opts[0]) {
     75 			keyName = opts[0]
     76 			st.IsTaggedKey = true
     77 		}
     78 	}
     79 	st.Key = keyName
     80 	if len(opts) > 1 {
     81 		for _, opt := range opts[1:] {
     82 			switch opt {
     83 			case "omitempty":
     84 				st.IsOmitEmpty = true
     85 			case "string":
     86 				st.IsString = true
     87 			}
     88 		}
     89 	}
     90 	return st
     91 }