github.com/xhebox/bstruct@v0.0.0-20221115052913-86d4d6d98866/field.go (about) 1 package bstruct 2 3 import ( 4 "go/ast" 5 ) 6 7 type Coder func(rdwt ast.Expr, ptr ast.Expr, s *Field) []ast.Stmt 8 9 type FieldType uint 10 11 const ( 12 FieldInvalid FieldType = iota 13 FieldBool 14 FieldInt8 15 FieldInt16 16 FieldInt32 17 FieldInt64 18 FieldUint8 19 FieldUint16 20 FieldUint32 21 FieldUint64 22 FieldFloat32 23 FieldFloat64 24 FieldString 25 FieldSlice 26 FieldStruct 27 FieldCustom 28 ) 29 30 func (ft FieldType) IsPrimitive() bool { 31 switch ft { 32 case FieldBool, FieldFloat32, FieldFloat64, FieldInt8, FieldInt16, FieldInt32, FieldInt64, FieldUint8, FieldUint16, FieldUint32, FieldUint64: 33 return true 34 default: 35 return false 36 } 37 } 38 39 func (ft FieldType) String() string { 40 switch ft { 41 case FieldBool: 42 return "bool" 43 case FieldInt8: 44 return "int8" 45 case FieldInt16: 46 return "int16" 47 case FieldInt32: 48 return "int32" 49 case FieldInt64: 50 return "int64" 51 case FieldUint8: 52 return "uint8" 53 case FieldUint16: 54 return "uint16" 55 case FieldUint32: 56 return "uint32" 57 case FieldUint64: 58 return "uint64" 59 case FieldFloat32: 60 return "float32" 61 case FieldFloat64: 62 return "float64" 63 case FieldString: 64 return "string" 65 case FieldSlice: 66 return "slice" 67 case FieldStruct: 68 return "struct" 69 default: 70 return "invalid" 71 } 72 } 73 74 func (ft FieldType) Size() uint { 75 sz := uint(0) 76 switch ft { 77 case FieldBool, FieldInt8, FieldUint8: 78 sz = 1 79 case FieldInt16, FieldUint16: 80 sz = 2 81 case FieldInt32, FieldUint32, FieldFloat32: 82 sz = 4 83 case FieldInt64, FieldUint64, FieldFloat64: 84 sz = 8 85 } 86 return sz 87 } 88 89 func (ft FieldType) IsType(t FieldType) bool { 90 return ft == t 91 } 92 93 type StructField struct { 94 *Field 95 strucName string 96 comment string 97 optional bool 98 } 99 100 type Field struct { 101 // all 102 typename string 103 comment string 104 typ FieldType 105 virtual bool 106 // FieldSlice 107 sliceType *Field 108 // FieldStruct 109 strucFields []StructField 110 // FieldCustom 111 custyp ast.Expr 112 cusenc Coder 113 cusdec Coder 114 } 115 116 func New(typ FieldType) *Field { 117 if typ.IsType(FieldSlice) || typ.IsType(FieldString) { 118 panic("should not pass slice or string type") 119 } 120 return &Field{ 121 typ: typ, 122 } 123 } 124 125 func NewSlice(t *Field) *Field { 126 return &Field{ 127 typ: FieldSlice, 128 sliceType: t, 129 } 130 } 131 132 func NewString() *Field { 133 return &Field{ 134 typ: FieldString, 135 sliceType: New(FieldUint8), 136 } 137 } 138 139 func NewCustom(typ ast.Expr, enc, dec Coder) *Field { 140 if typ == nil { 141 panic("typ can not be nil") 142 } 143 return &Field{ 144 typ: FieldCustom, 145 custyp: typ, 146 cusenc: enc, 147 cusdec: dec, 148 } 149 } 150 151 func (b *Field) Add(name, comment string, optional bool, field *Field) *Field { 152 b.strucFields = append(b.strucFields, StructField{ 153 comment: comment, 154 optional: optional, 155 strucName: name, 156 Field: field, 157 }) 158 return b 159 } 160 161 func (b *Field) Comment(comment string) *Field { 162 b.comment = comment 163 return b 164 } 165 166 func (s *Field) Virtual() *Field { 167 s.virtual = true 168 return s 169 } 170 171 func (s *Field) Reg(e *Builder, name string) *Field { 172 s.typename = name 173 e.types[name] = builtField{field: s} 174 return s 175 }