github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/sqx/struct.go (about) 1 package sqx 2 3 import "reflect" 4 5 // StructField represents the information of a struct's field. 6 type StructField struct { 7 Parent *StructValue 8 Field reflect.Value 9 Index int 10 StructField reflect.StructField 11 Type reflect.Type 12 Name string 13 Tag reflect.StructTag 14 Kind reflect.Kind 15 PkgPath string 16 } 17 18 // GetTag returns the value associated with key in the tag string. 19 // If there is no such key in the tag, Get returns the empty string. 20 func (f StructField) GetTag(name string) string { 21 if v, ok := f.Tag.Lookup(name); ok { 22 return v 23 } 24 25 return "" 26 } 27 28 // GetTagOr returns the tag's value of the field or defaultValue when tag is empty. 29 func (f StructField) GetTagOr(tagName string, defaultValue string) string { 30 tag := f.GetTag(tagName) 31 if tag != "" { 32 return tag 33 } 34 35 return defaultValue 36 } 37 38 // StructValue represents the structure for a struct. 39 type StructValue struct { 40 StructSelf reflect.Value 41 NumField int 42 FieldTypes []reflect.StructField 43 } 44 45 // MakeStructValue makes a StructValue by a struct's value. 46 func MakeStructValue(structSelf reflect.Value) *StructValue { 47 sv := &StructValue{StructSelf: structSelf, NumField: structSelf.NumField()} 48 49 sv.FieldTypes = make([]reflect.StructField, sv.NumField) 50 for i := 0; i < sv.NumField; i++ { 51 sv.FieldTypes[i] = sv.StructSelf.Type().Field(i) 52 } 53 54 return sv 55 } 56 57 // FieldIndexByName return's the index of field by its name. 58 // If the field is not found, FieldIndexByName returns -1. 59 func (s *StructValue) FieldIndexByName(name string) int { 60 for i, ft := range s.FieldTypes { 61 if ft.Name == name { 62 return i 63 } 64 } 65 66 return -1 67 } 68 69 // FieldByName returns the StructField which has the name. 70 func (s *StructValue) FieldByName(name string) (StructField, bool) { 71 index := s.FieldIndexByName(name) 72 if index < 0 { 73 return StructField{}, false 74 } 75 76 return s.FieldByIndex(index), true 77 } 78 79 // FieldByIndex return the StructField at index. 80 func (s *StructValue) FieldByIndex(index int) StructField { 81 fieldType := s.FieldTypes[index] 82 field := s.StructSelf.Field(index) 83 84 return StructField{ 85 Parent: s, 86 Field: field, 87 Index: index, 88 StructField: fieldType, 89 Type: fieldType.Type, 90 Name: fieldType.Name, 91 Tag: fieldType.Tag, 92 Kind: field.Kind(), 93 PkgPath: fieldType.PkgPath, 94 } 95 }